《windows核心编程指南29.pdf》由会员分享,可在线阅读,更多相关《windows核心编程指南29.pdf(4页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、下载附录B 消息分流器、子控件宏和A P I宏每当我参加一些会议时,常问一些人是不是使用消息分流器,而回答通常是“N o”。我再进一步深究这件事,发现很多人不知道消息分流器是干什么用的,甚至没有听说过它。在本书中,通过使用带有消息分流器的C/C+编写示例代码,我想向大家介绍这种不大为人所知但很有用的宏。消息分流器定义在Microsoft Visual C+中提供的Wi n d o w s X.h文件里。通常在Wi n d o w s.h文件之后紧接着包含这个文件。Wi n d o w s X.h文件就是一组#d e f i n e指令,建立了一组供我们使用的宏。Wi n d o w s X.h
2、的宏实际上分为三组:消息分流器、子控件宏和 A P I宏。这些宏以下述的方式为我们提供帮助:利用这些宏可以减少程序中要做的转换(c a s t i n g)的数量,并可使所要求的转换是无错误的。使用C/C+的Wi n d o w s编程中一个大的问题是所要求的转换数量。你很难看到一个不要求某种转换的 Wi n d o w s函数调用。但应该尽量避免使用转换,因为转换阻碍编译器发现代码中的潜在错误。一个转换是在告诉编译程序:“我知道我在这里传递了错误的转换,但就要这样做。我知道我在干什么。”当你做了许多转换时,就很容易出错。编译程序应该尽可能对此提供帮助。使代码的可读性更好。可简化1 6位Wi
3、n d o w s、3 2位Wi n d o w s和6 4位Wi n d o w s之间的代码移植工作。易于理解(只是一些宏)这些宏容易结合到已有的代码中。可以不管老的代码而立即在新的代码中使用这些宏。不必修改整个程序。在C和C+代码中都可以使用这些宏,尽管当使用C+类时它们不是必需的。如果需要某一个特性,而这些宏不直接支持这个特性,可以根据这个头文件中的宏,很容易地编写自己的宏。不需要参照或记住费解的Wi n d o w s构造。例如,许多Wi n d o w s中的函数,要求一个l o n g型参数,其中这个长参数的高字(h i g h-w o r d)的值代表一个东西,而其低字(l o
4、 w-w o r d)又代表另一个东西。在调用这个函数之前,你必须用两个单独的值构造一个l o n g型值。通常利用Wi n D e f.h中的M A K E L O N G宏来做这种事。我简直记不清有多少次把两个值的次序给弄反了,造成对函数传递了一个错误的值。而Wi n d o w s X.h中的宏可以帮我们的忙。B.1 消息分流器消息分流器(message cracker)使窗口过程的编写更加容易。通常,窗口过程是用一个大的s w i t c h语句实现的。在我的经验中,我见过有的窗口过程的 s w i t c h语句包含5百多行代码。我们都知道按这种方式实现窗口过程是一种坏的习惯,但我们
5、都这么做过。而利用消息分流器可将s w i t c h语句分成小的函数,每个窗口消息对应一个函数。这样使代码更容易管理。有关窗口过程的另一个问题是每个消息都有 w P a r a m和l P a r a m参数,并且根据消息的不同,这些参数的意思也不同。在某些情况下,如对 W M _ C O M M A N D消息,w P a r a m包含两个不同的值。w P a r a m参数的高字是通知码,而低字是控件的 I D。或者是反过来?我总是忘了次序。如果使用消息分流器,就不用记住或查阅这些内容。消息分流器之所以这样命名,是因为它们对任何给定的消息进行分流。为了处理W M _ C O M M A
6、 N D消息,你只需编写这样一个函数:这是多么容易!分流器查看消息的w P a r a m和l P a r a m参数,将参数分开,并调用你的函数。为了使用消息分流器,必须对你的窗口过程的 s w i t c h语句做一些修改。看一看下面的窗口过程:H A N D L E _ M S G宏在Wi n d o w s X.h中是这样定义的:对于W M _ C O M M A N D消息,预处理程序把这一行代码扩展成下面的代码:定义在WindowsX.h 中的各H A N D L E _ W M _*宏是实际的消息分流器。它们分流 w P a r a m参数和 l P a r a m参数,执行所有
7、必要的转换,并调用适当的消息函数,如前面例举过的C l s _O n C o m m a n d函数。H A N D L E _ W M _ C O M M A N D宏的定义如下:附录 B 消息分流器、子控件宏和API宏计计687下载当预处理程序扩展这个宏时,其结果是用w P a r a m和l P a r a m参数的内容分流成各自的部分并经适当转换,来调用C l s _ O n C o m m a n d函数。在使用消息分流器来处理一个消息之前,应该打开 Wi n d o w s X.h文件并搜索要处理的消息。例如,如果搜索W M _ C O M M A N D,将会找到文件中包含下面代
8、码行的部分:第一行是注释行,展示要编写的函数原型。下一行是 H A N D L E _ W M _*宏,我们已经讨论过。最后一行是消息转发器(f o r w a r d e r)。假定在你处理W M _ C O M M A N D消息时,你想调用默认的窗口过程,并让它为你做事。这个函数应该是这个样子:F O RWA R D _ W M _*宏将分流开的消息参数重新构造成等价的 w P a r a m和l P a r a m。然后这个宏再调用你提供的函数。在上面的例子中,宏调用 D e f Wi n d o w P r o c函数,但你可以简单地使用S e n d M e s s a g e或P
9、 o s t M e s s a g e。实际上,如果你想发送(或登记)一个消息到系统中的任何窗口,可以使用一个F O RWA R D _ W M _*宏来帮助合并各个参数。B.2 子控件宏子控件宏(Child Control Macro)使发送消息到子控件变得更加容易。这些宏同F O RWA R O _W M _*宏很相似。每个宏的定义以一个控件类型开始(这个控件是要对它发送消息的控件),后面跟一个下横线和消息名。例如,向一个列表框发送一个L B _ G E T C O U N T消息,就使用Wi n d o w s X.h中的这个宏:关于这个宏我想说两件事。第一,它只用一个参数 h w n
10、 d C t l,这是列表框的窗口句柄。因为L B _ G E T C O U N T消息忽略了w P a r a m和l P a r a m参数,你不必再管这些参数。你可以看到,宏只传递了零。第二,当S e n d M e s s a g e返回时,结果被转换成i n t,所以你不必提供你自己的转换。关于子控件宏,有一件事我不喜欢,就是这些宏要用控件窗口的句柄。许多时候,你要发送消息到一个控件,而这个控件是一个对话框的子控件。所以最终你总要调用 G e t D l g I t e m,产生这样的代码:688计计第七部分附录下载比起使用S e n d D l g I t e m M e s s
11、 a g e,这个代码的运行虽然不慢,但你的程序会包含一些额外的代码。这是由于对G e t D l g I t e m的额外调用。如果需要对同一控件发送几个消息,你可能想调用一次G e t D l g I t e m,保存子窗口的句柄,然后调用你需要的所有的宏,见下面的代码:如果按这种方式设计你的代码,你的程序会运行得更快,因为这样就不会反复地调用G e t D l g I t e m。如果你的对话框有许多控件并且你要寻找的控件在 Z序的结尾,则G e t D l g I t e m可能是个很慢的函数。B.3 API宏A P I宏可以简化某些常用的操作,如建立一种新字体,选择字体到设备环境,保存原来字体的句柄。代码的形式如下:这个语句要求两个转换以得到没有编译警告错误的编译。在 Wi n d o w s X.h中有一个宏,正是为了这个用途而设计:如果你使用这个宏,你的程序中的代码行就变成:这行代码更容易读,也不容易出错。在Wi n d o w s X.h中还有其他一些A P I宏,有助于常用的Wi n d o w s任务。建议读者了解并使用这些宏。附录 B 消息分流器、子控件宏和API宏计计689下载