论坛问题收集(2)

来源:互联网 发布:全职妈妈 知乎 编辑:程序博客网 时间:2024/04/30 10:02

回调函数与普通函数没有本质上的区别,只是概念上的区别。  
  回调函数的典型应用可以描述如下:  
  用户A写一段程序,处理某一事务,例如数据排序。他对排序算法有相当研究,因此,他使用了一种高效的排序算法。为了让不懂排序算法的人也能够使用这个高效的算法,他决定为其他用户提供一个函数接口。但是,既然要排序,就必须比较2个对象的大小,而算法编写者对客户的对象没有任何知识,因此,他需要客户提供一个比较对象大小的函数,如,  
  int   comp(const   void*   obj1,   const   void*   obj2)  
  当他需要比较大小时,就调用客户提供的这个函数,根据函数返回值确定大小关系。而客户提供的这个比较函数,就可以称作回调(callback)函数,即:本来是我(客户)调用你(算法库),而你会过头来又调用我的函数(比较函数),回调函数由此得名。  
  回调函数的概念随处可见,其应用并不局限于系统调用。一般来讲,如果某个处理流程具有确定性,而流程中某个具体的处理环节需要根据实际情况具体处理,就可以将这个流程固定下来,在需要具体处理的地方“安插”适当的回调函数接口。  
   
  从调用时机来看,回调函数可以分为同步、异步2类:上面提到的排序的例子是一个同步回调的例子。  
  异步回调等同于中断注册的概念,客户首先就某一个感兴趣的事件向服务器注册一个处理函数,服务器在发生客户感兴趣的事件是,就调用客户注册的处理函数。

B:任务中需排序操作

B调用A的排序函数------------------->A:排序函数 px()

                                  {

                                   。。

比较两对象大小

函数comp(x,y)  <---------------------A调用B的比较函数

                                     A完成排序 

 B完成任务                   

 ++++++++++++++++++++++++++++++++++++++++

进行Windows程序设计,实际上是在进行一种对象导向的程序设计(OOP)。这一点在Windows中使用得最多的对象上表现最为明显。这种对象正是Windows之所以命名为「Windows」的原因,它具有人格化的特征,甚至可能会在您的梦中出现,这就是那个叫做「窗口」的东西。

  桌面上最明显的窗口就是应用程序窗口。这些窗口含有显示程序名称的标题列、菜单甚至可能还有工具列和滚动条。另一类窗口是对话框,它可以有标题列也可以没有标题列。

  装饰对话框表面的还有各式各样的按键、单选按钮、复选框、清单方块、滚动条和文字输入区域。其中每一个小的视觉对象都是一个窗口。更确切地说,这些都称为「子窗口」或「控件窗口」或「子窗口控件」。

  作为对象,使用者会在屏幕上看到这些窗口,并通过键盘和鼠标直接与它们进行交互操作。更有趣的是,程序写作者的观点与使用者的观点极其类似。窗口以「消息」的形式接收窗口的输入,窗口也用消息与其它窗口通讯。对讯息的理解将是学习如何写作Windows程序所必须越过的障碍之一。

  这有一个Windows的消息范例:我们知道,大多数的Windows程序都有大小合适的应用程序窗口。也就是说,您能够通过鼠标拖动窗口的边框来改变窗口的大小。通常,程序将通过改变窗口中的内容来响应这种大小的变化。您可能会猜测(并且您也是正确的),是Windows本身而不是应用程序在处理与使用者重新调整窗口大小相关的全部杂乱程序。由于应用程序能改变其显示的样子,所以它也「知道」窗口大小改变了。

  应用程序是如何知道使用者改变了窗口的大小的呢?由于程序写作者习惯了往常的文字模式程序,操作系统没有设置将此类消息通知给使用者的机制。问题的关键在于理解Windows所使用的架构。当使用者改变窗口的大小时,Window给程序发送一个消息指出新窗口的大小。然后程序就可以调整窗口中的内容,以响应大小的变化。

「Windows给程序发送消息。」我们希望读者不要对这句话视而不见。它到底表达了什么意思呢?我们在这里讨论的是程序代码,而不是一个电子邮件系统。操作系统怎么给程序发送消息呢?

  其实,所谓「Windows给程序发送消息」,是指Windows呼叫程序中的一个函数,该函数的参数描述了这个特定消息。这种位于Windows程序中的函数称为「窗口消息处理程序」。

  无疑,读者对程序呼叫操作系统的做法是很熟悉的。例如,程序在打开磁盘文件时就要使用有关的系统呼叫。读者所不习惯的,可能是操作系统呼叫程序,而这正是Windows对象导向架构的基础。

  程序建立的每一个窗口都有相关的窗口消息处理程序。这个窗口消息处理程序是一个函数,既可以在程序中,也可以在动态链接库中。Windows通过呼叫窗口消息处理程序来给窗口发送消息。窗口消息处理程序根据此消息进行处理,然后将控制传回给Windows。

  更确切地说,窗口通常是在「窗口类别」的基础上建立的。窗口类别标识了处理窗口消息的窗口消息处理程序。使用窗口类别使多个窗口能够属于同一个窗口类别,并使用同一个窗口消息处理程序。例如,所有Windows程序中的所有按钮均依据同一个窗口类别。这个窗口类别与一个处理所有按钮消息的窗口消息处理程序(位于Windows的动态链接库中)联结。

  在对象导向的程序设计中,对象是程序与数据的组合。窗口是一种对象,其程序是窗口消息处理程序。数据是窗口消息处理程序保存的信息和Windows为每个窗口以及系统中那个窗口类别保存的信息。

  窗口消息处理程序处理给窗口发送消息。这些消息经常是告知窗口,使用者正使用键盘或者鼠标进行输入。这正是按键窗口知道它被「按下」的奥妙所在。在窗口大小改变,或者窗口表面需要重画时,由其它消息通知窗口。

  Windows程序开始执行后,Windows为该程序建立一个「消息队列」。这个消息队列用来存放该程序可能建立的各种不同窗口的消息。程序中有一小段程序代码,叫做「消息循环」,用来从队列中取出消息,并且将它们发送给相应的窗口消息处理程序。有些消息直接发送给窗口消息处理程序,不用放入消息队列中。

  如果您对这段Windows架构过于简略的描述将信将疑,就让我们去看看在实际的程序中,窗口、窗口类别、窗口消息处理程序、消息队列、消息循环和窗口消息是如何相互配合的。这或许会对您有些帮助。

+++++++++++++++++++++++++
原创粉丝点击