本文将以实际的典型场景来解释发生的消息,从而能够将窗口的消息具体化,并能连贯起来。文中的内容绝大部分为VC提供的Spy++工具获得,小部分为通过程序获得。文中显示的片段多数为一个窗口中的消息,对于发往父窗口的消息,将会附带说明。
Windows的标准消息定义位于winuser.h中(%Program Files%/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/include/winuser.h).可是,使用Spy++能够捕获所有窗口消息,经常会看到一些MSDN中未提及的消息.这一少部分消息的定义位于afxpriv.h中(%Program Files%/Microsoft Visual Studio .NET 2003/Vc7/atlmfc/include/afxpriv.h),这部分为MFC的内部消息(0x0360 ~ 0x037f),因此在MSDN中通常也找不到它们的踪迹.不过,MSDN中的"TN024: MFC-Defined Messages and Resources"解释了这些消息.
1 Mouse动作
1.1 Mouse在Title bar上移动
下面的片段是Mouse在Dialog的Caption上移动时产生的片段:
<00001> 00050592
S WM_NCHITTEST
xPos:254 yPos:170
<00002> 00050592 R WM_NCHITTEST nHittest:HTCAPTION
<00003> 00050592
S WM_SETCURSOR
hwnd:00050592 nHittest:HTCAPTION wMouseMsg:WM_MOUSEMOVE
<00004> 00050592 R WM_SETCURSOR fHaltProcessing:False
<00005> 00050592 P WM_NCMOUSEMOVE nHittest:HTCAPTION xPos:254 yPos:170
<00006> 00050592 S WM_KICKIDLE
其中,
1. WM_NCHITTEST:当鼠标在窗体移动时,系统会产生该消息。对于窗口的不同的区域,会返回不同的代码,。对于上述场景,为HTCAPTION,即title bar。如果是客户区,则都为HTCLIENT。其它代码都是用来区分非客户区的不同部分。
2. WM_SETCURSOR可以用来设置光标的形状。其nHittest同WM_NCHITTEST的代码,wMouseMsg参数表明了此时鼠标的动作
3. WM_NCMOUSEMOVE为post消息,而且只有当窗口拥有光标时,系统才会发送该消息。如果一个窗口capture了光标,那么该消息不会被发送。
4. WM_KICKIDLE为消息队列空闲时,系统发送的消息,以便程序可以在此时处理一些事情,比如:同步状态等。应用可以控制系统是否发送该消息。对对话框而言,就是设置DS_NOIDLEMSG风格。如果是主消息循环,那么CWinApp提供了OnIdle虚方法(实际为CWinThread的方法),其中lIdleCount