冒号课堂§3.4:事件驱动 - 编程入门网
者Delphi来实现窗口,是因为它们高度的封装和强大的IDE掩盖了部分事件机制。如果你们对win32 API不太熟悉,没有关系。为了减少语言和API上的障碍,同时突出重点,这里最大限度地省略了次要的过程和参数等,仅保留脉络主干。”冒号解释,“从中看出到,创建一个能响应用户操作的win32窗口共分四步:注册窗口类别、创建窗口、消息循环和窗口过程。”
问号对概念很敏感:“消息与事件是一回事吗?” “严格说来它们不是一回事,但如果你不想深究,不加区分也无大碍。概略地说,消息是Windows内部最基本的通讯方式,事件需要通过消息来传递,是消息的主要来源。每当用户触发一个事件,如移动鼠标或敲击键盘,系统都会将其转化为消息并放入相应程序的消息队列(message queue)中[2]。”冒号解答着,“明白了这一点,上面的代码就不难理解了——在消息循环中,程序通过GetMessage不断地从消息队列中获取消息,经过TranslateMessage预处理后再通过DispatchMessage将消息送交窗口过程WndProc处理。” 逗号琢磨了一会,不解地问:“窗口过程应该是在分派消息时被调用的,但我怎么想不出DispatchMessage是如何联系到WndProc的?” 冒号为其解惑:“DispatchMessage的消息参数含有事发窗口的句柄(handle),从而可以得到窗口过程WndProc[3]。至于窗口与窗口过程之间是如何建立联系的,回看前面两步就一目了然了:当初在创建窗口时指明了窗口类别名windowClassName,而窗口类别windowClass又绑定了窗口过程。” 叹号有点纳闷:“干嘛要绕这么大的弯子,直接调用WndProc不就得了?” “对于这个简单的程序来说,的确区别不大。但假如再增添其他菜单、按钮、文本框之类的控件,每个控件都可绑定自己的窗口过程,那么到底该调用哪个才对呢?”冒号反问。 叹号虽有所悟,但仍有心结:“总觉得窗口过程的用法有些怪怪的。” 冒号课堂§3.4:事件驱动(4)时间:2011-06-25 BlogJava xyz98冒号一敲桌案:“没错!怪就怪在编程者自己写了一个应用层的函数,却不直接调用它,而是通过库函数间接调用。这类函数有个专用名称:回调函数(callback)。” 引号忍不住插话:“回调函数我知道,在C和C++中就是函数指针嘛。” “确切地说,函数指针是C和C++用来实现callback的一种方式。此外,C++中的functor、Java中的interface和C#中的delegate都可实现callback。我们先图解一下回调机制。”冒号调出一张图示—— “如果我们把系统划分为两层[4]:底层的函数库和高层的应用程序。同样作为主函数的辅助函数,左图中的普通函数直接被主函数调用,然而右图中的回调函数却是通过库函数间接被主函数调用的。”冒号的手影在幻灯下上下翻飞。 句号点出要害:“一般都是高层代码调用低层代码,callback反其道而行之,因此显得与众不同。” “所言极是。一方面,在软件模块分层中,低层模块为高层模块提供服务,但不能依赖高层模块,以保证其可重用性和可扩展性;另一方面,通常被调者(callee)为调用者(caller)提供服务,调用者依赖被调者。两相结合,决定了低层模块多为被调者,高层模块多为调用者。callback的出现改变了这种惯例,我们看一个简单的例子。”冒号写下一段Java代码——
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |