最开始为windows消息迷惑的时候是一个叫做sendMessage的函数:
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
最后的两个参数在不同的情况下到底应该怎么来赋值呢?后来又遇到了窗口过程函数:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam),后面的两个参数在不同的消息下分别代表什么意思呢?
曾经四处搜索过,但是没有满意的答复,这两天在看《windows程序设计》,把关于鼠标这部分内容记录下来,作个笔记。
鼠标消息:
鼠标消息有21种,可以分为三类:
1.命中测试消息WM_NCHITTEST(我的理解:以WM开头的严格来说是消息名称,完整的消息应该是个结构体MSG msg,该消息名称为msg.wParam,但是一般消息和消息名称似乎分的不是很仔细)。
它是优先于任何接下来要说到的客户区和非客户区的鼠标消息。因为其余20种鼠标消息都是基于它的基础之上产生的。也就是说user用鼠标点击之后首先产生的是WM_NCHITTEST消息,然后经窗口函数的DefWindowProc返回一个值,这个值将成为新的鼠标消息的wParam值。
注意:不要被这里的字面字母所迷惑,WM_NCHITTEST虽然有NC作为前缀,但是它不仅是产生非客户区鼠标消息的基础同时也是客户区消息的产生基础。
经由WM_NCHITTEST消息产生的值可以是任意非客户区鼠标消息的wParam值再加上以下四种中的一种:
HTCLIENT 客户区
HTNOWHERE 不在窗口中
HTTRANSPARENT 窗口被另外一个窗口覆盖
HTERROR 使得DefWindowProc产生蜂鸣声
举个例子:如果DefWindowProc返回的是HTCLIENT ,那么windows将把屏幕坐标转换为客户区坐标并产生客户区鼠标消息。
lParam包含的是鼠标位置的屏幕坐标
wParam没有用。
2.客户区鼠标消息(10个):左:WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK
中:WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK
右:WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK
鼠标移动消息:WM_MOUSEMOVE
lParam含有鼠标位置的坐标,低字位是x坐标,高字位是y坐标,当然此时它们是客户区坐标。可以用
x=LOWORD(lParam);
y=HIWORD(lParam);
来表示。
如果要转化为屏幕坐标,可用:
ClientToScreen(hWnd,&pt);
wParam用来指示鼠标键和shift和Ctrl的状态:
MK_LBUTTON
MK_MBUTTON
MK_RBUTTON
MK_SHIFT
MK_CONTROL
举例:如果要表示收到了WM_LBUTTON和按下了shift,那么可以表示为:wParam&MK_SHIFT
3.非客户区鼠标消息(10个。完全和客户区那九个消息名称相对应,就是前面加了前缀NC表示no_client):
左:WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
中:WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
右:WM_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK
鼠标移动消息:WM_NCMOUSEMOVE
同样的,lParam含有鼠标位置的坐标,低字位是x坐标,高字位是y坐标,但是此时它们是屏幕坐标。也可以用
x=LOWORD(lParam);
y=HIWORD(lParam);
来表示。
如果要转化为客户区坐标,可用:
ScreenToClient(hWnd,&pt);
wParam指示鼠标所在的非客户区的位置(非坐标),由
HTCLIENT
HTNOWHERE
HTTRANSPARENT
HTERROR
四个中的某个表示
键盘消息:
击键消息:WM_KEYDOWN WM_KEYUP WM_SYSKEYDOWN WM_SYSKEYUP
wParam 包括了虚拟键码,如VK_SPACE VK_CANCEL之类的东东
lParam 包括了了解击键非常有用的其他信息,如重复计数、环境代码、键的先前状态、转换状态、OEM扫描码等。具体参见《windows程序设计》P.201
字符消息:WM_CHAR WM_SYSCHAR WM_DEADCHAR WM_SYSDEADCHAR
事实上,字符消息也是由击键消息经TranslateMessage转换而来。如WM_CHAR和WM_DEADCHAR是从WM_KEYDOWN得到的;WM_SYSCHAR和WM_SYSDEADCHAR由WM_SYSKEYDOWN得到的。
wParam不是虚拟键码,而是ANSI或UNICODE字符代码
lParam与击键消息的lParam相同
其余消息:
WM_SIZE:
lParam包含了客户区的大小,同样的低字位的表示x(宽度),高字位的表示y(高度);
wParam表示窗口大小的状态,即:
SIZE_MAXIMIZED Window has been maximized. 最大化
SIZE_MINIMIZED Window has been minimized. 最小化
SIZE_RESTORED Window has been resized, but neither SIZE_MINIMIZED nor SIZE_MAXIMIZED applies.既非最大也非最小,并不极端。
SIZE_MAXHIDE Message is sent to all pop-up windows when some other window is maximized.
SIZE_MAXSHOW Message is sent to all pop-up windows when some other window has been restored to its former size.
WM_CREATE:
其中lParam是指向结构体类型CREATESTRUCT的一个指针,其中包含了程序实例hInstance,故可通过(LPCREATESTRUCT)lParam->hInstance获取该实例,这和通过函数GetWindowProc(hWnd,GWL_HINSTANCE)效果是一样的
WM_COMMAND:
这个消息一般是在主窗口上点击其子窗口如按钮、菜单、复选框等才会产生的消息(这里的例外是滚动控制(就是可以在客户区的任何地方出现的滚动条子窗口),它是不会发送该消息的)。点击这些这些Button时候,向父窗口发送该消息,其中
LOWORD(wParam) 子窗口ID
HIWORD (wParam) 通知码(如BN_CLICKED、BN_PAINT、BN_PUSHED、BN_UNPUSHED、BN_DISABLE、BN_DBLCLK、 BN_SETFOCUS、BN_KILLFOCUS)
lParam 子窗口句柄
注意:
1.此时当点击子窗口时,子窗口获得焦点,但是它会忽略除Spacebar键之外的所有键盘输入,此时Spacebar和鼠标的效果一样;
2.当子窗口为菜单时,它给窗口发送该消息时wParam和lParam和其他有点不一样:
HIWORD (wParam) :0
lParam :0
WM_CTLCOLORBTN(WM_CTLCOLORSCROLLBAR、WM_CTLCOLORSTATIC):
一般用来由子窗口发送给父窗口,从而改变子窗口的显示颜色(详见P.348)
wParam是子窗口(比如说按钮)的设备描述表(这也意味着当父窗口获得该消息时,子窗口已经取得设备描述表了,否则如何传递给父窗口呢?)
lParam是子窗口的窗口句柄
WM_DRAWITEM:
这是在子窗口(如按钮等)在被创建、改动时候由windows发送给父窗口的wndProc的。就按钮具体情况而言:如果该按钮是BS_OWNERDRAW风格的话,那么在这么几种情况下是会发送给其父窗口的:创建、按下或被释放、得到或失去焦点、被重新着色。
对于其它的子窗口,比如说复选框、单选框、列表框、菜单等是否和按钮一致,书上没说,我也没经过试验,不清楚。以后回来说明,或者哪位哥们看到这里告诉我。。
lParam是个指向DRAWITEMSTRUCT结构的指针,该结构包含了很多内容,有按钮的hDC、rectItem(按钮的尺寸)、CtrlID(控制窗口ID)、itemState(按钮状态,如是否拥有输入焦点)
滚动条消息WM_VSCROLL WM_HSCROLL:
lParm可以用来区分“窗口滚动条(一般意义上的滚动条)”和“滚动控制”,对于前者该值是0,对于后者该值是滚动控制的窗口句柄
wParam暂时不清楚其包含的含义,但是对于这两个滚动条消息该值是相同的。(P.357)
WM_INITMENU(不常用):
wParam: 主菜单句柄
lParam: 0
WM_SELECTMENU:
当用户的光标在菜单上面上下移动时该消息被发送给窗口(即意味着可以帮助实现包含对菜单栏文本描述的状态栏)。
LOWORD(wParam): 选中项:菜单ID或者弹出式菜单句柄
HIWORD(wParam) : 选择标志(可以是以下组合:MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、MF_HELP、MF_SYSMENU、MF_MOUSESELECT)
lParam :包含选中项的菜单句柄
WM_INITMENUPOPUP:
当显示一个弹出菜单前给窗口发送该消息。
wParam: 弹出式菜单句柄
LOWORD(lParam):弹出式菜单索引
HIWORD(lParam):系统菜单为1,其他为0.
WM_MENUCHAR:
该消息实际并非菜单消息。当用户按下ALT和一个与菜单项不匹配的字符时,或者当显示弹出式菜单而用户按下一个与弹出式菜单里的项不匹配的字符时将发送给窗口该消息。
LOWORD(wParam) :字符代码(ASCII或者UNICODE)
HIWORD(wParam) :选择码(可以是0:不显示弹出式菜单;MF_POPUP:显示出弹出式菜单;MF_SYSMENU:显示系统出弹出式菜单)
lParam :菜单句柄