MSG构造体和WndProc窗口进程关于Windows编程十分主要,假如不理解它们,可以说就没有学会Windows编程。

MSG构造体

MSG 构造体用来表现一条音讯,各个字段的寄义如下:

			typedef struct tagMSG{ HWND hwnd; //窗口句柄 UINT message; //音讯类型 WPARAM wParam; //附加音讯1 LPARAM lParam; //附加音讯2 DWORD time; //音讯被传递时分的工夫 POINT pt; //音讯被传递光阴标在屏幕上的地位 } MSG;

对各个字段的阐明:
1) 最初两个字段 time 和 pt 普通由零碎运用,我们很罕用到。
2) message 为音讯类型,也就是以 WM 扫尾的音讯(WM 是 Window Message 的缩写 ),例如 WM_CREATE、WM_PAINT、WM_DESTROY、WM_COMMAND 等。
2) wParam 和 lParam 是要重点阐明的,它们都表现附加音讯。例如,当收到一个字符音讯的时,message 的值为 WM_CHAR,但用户究竟输出的是什么字符,那么就由 wParam 和 lParam 来阐明。wParam、lParam 表现的信息随音讯类型的分歧而分歧,详细细节可以到MSDN中检查。
WPARAM 和 LPARAM 这两种数据类型的界说辨别为:

typedef  UINT_PTR  WPARAM;
typedef  LONG_PTR  LPARAM;

在古代操作零碎中(32位和64位操作零碎),它们普通都表现 32 位的整数。
但在16位操作零碎中,WPARAM 表现16位整数,而 LPARAM 表现32位整数,依据匈牙利定名法,16 位的变量平日以W扫尾,32 位变量平日以L扫尾。晋级到32位操作零碎后,WPARAM也被扩大到32位,此时 WPARAM 和 LPARAM 的巨细完整相反。
在 Win32 API 的晚期,因为还有许多 Win16 API 的软件,为了包管和 Win16 API 的代码可移植性,微软仍然保存了 WPARAM 和 LPARAM 两个宏。
不外16位零碎早已成为汗青,如今你可以以为这两个参数的长度相反。读者可以在 VC / VS 中经过 F12 键或许“转到界说”菜单检查。

wParam 和 lParam 究竟表现什么信息

可以一定的是,音讯类型 message 分歧,wParam 和 lParam 两个字段表现的附加音讯普通也分歧。那么,它们究竟表现什么呢?其实这个真的纷歧定,没有什么纪律,它们原本就是一个汗青遗留成绩,也不晓得微软究竟怎样布置的,只能依据分歧的音讯类型去 MSDN 中查找。
普通商定,wParam 用来表现控件的ID,或许高 16 位和低 16 位组合起来辨别表现鼠标的地位,假如发送音讯时需求附带某种构造的指针或许是某品种型的句柄时,习气上用 lParam。
不外这也纷歧定是对的,例如关于一个鼠标左键按下的音讯 WM_LBUTTONDOW,就用 lParam 来表现鼠标的坐标:

			//point 是一个构造体,表现鼠标坐标 //msg 表现一条音讯 point.x = LOWORD( msg.lParam ); point.y = HIWORD( msg.lParam );

LOWORD 和 HIWORD 多是宏界说:LOWORD 用来取一个 32 位数的低 16 位,HIWORD 用来取一个32 位数的高 16 位。关于 WM_LBUTTONDOW 音讯,低 16 位寄存的是 x 坐标,而高 16 位寄存的是 y 坐标。

WndProc 窗口进程

窗口进程普通界说为如下的方式:

			LRESULT CALLBACK WndProc( HWND hwnd, //窗口句柄 UINT message, //音讯类型 WPARAM wParam, //附加音讯1 LPARAM lParam //附加音讯2 ){ // TODO }

WndProc 的各个参数和 MSG 构造体的前四个字段是逐个对应的。需求铭刻的是:每发生一条音讯,都邑挪用一次 WndProc 函数。
当用户点击按钮、编纂框、下拉列表框等控件的时分,会发生WM_COMMAND音讯。关于分歧起源的 WM_COMMAND 音讯,wParam、lParam 参数也分歧,见下表:

音讯起源 wParam (高16位) wParam (低16位) lParam
菜单 0 菜单ID 0
快捷键 1 快捷键ID 0
控件 控件告诉码 控件ID 控件句柄


留意:

  • 下面说的菜单是指窗口题目下方、客户区上方的下拉菜单,而不是客户区的下拉列表框控件。

  • 控件告诉码用来辨认控件的操作。例如 Button 控件普通有两种告诉码,BN_CLICKED 和 BN_DOUBLECLICKED,前者表现 Button 被单击,后者表现 Button 被双击。