当某应用程序有某一事件发生时,操作系统接受此消息。消息也分为队列化和非队列化的。队列化的消息由Windows放入程序消息队列中,在程序的消息循环中重新传回并分配给窗口消息处理程序(Windosw调用WinProc函数)。非队列化的消息在Windows呼叫窗口时直接送给消息处理程序。至于那些是队列化,那些是非队列化的,Windows会处理。从窗口消息处理程序的角度来看,这些消息是以一种有序的、同步的方式进出的。窗口消息处理程序可以处理它们,也可以不处理。
对于队列化的消息,应用程序通过下面代码(也即消息循环)进行消息获取和处理:
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
其中GetMessage (&msg, NULL, 0, 0)传给Windows一个指标,指向名为msg的MSG结构。第二、第三和第四个参数设定为NULL或者0,表示程序接收它自己建立的所有窗口的所有消息。Windows用从消息队列中取出的下一个消息来填充消息结构的各个字段.MSG结构的各字段如下:
typedef struct tagMSG
{
HWND hwnd ; //接收消息的窗口句柄
UINT message ; //消息标识符,每一个消息对应一个常量
WPARAM wParam ; //与具体消息有关
LPARAM lParam ;
DWORD time ; //消息放入消息队列中的时间。
POINT pt ; //消息放入消息队列时的鼠标坐标。
};
TranslateMessage (&msg) ;
将msg结构传给Windows,进行一些键盘转换。
DispatchMessage (&msg) ;
又将msg结构回传给Windows。然后,Windows将该消息发送给适当的窗口消息处理程序,让它进行处理。
另外有一些值得注意的知识点:
1.WinMain函数被指定了一个WINAPI型态(在表头文件中定义的所有Windows函数都被指定这种型态),而WndProc函数被指定一个CALLBACK型态。这两个标识符都被定义为_stdcall,表示在Windows本身和使用者的应用程序之间发生的函数呼叫的呼叫参数传递方式。
2.PostMessage和SendMessage的区别:
PostMessage 和SendMessage的区别主要在于是否等待其他程序消息处理。PostMessage只是把消息放入队列,不管其他程序是否处理都返回,然后继续执行;而SendMessage必须等待其他程序处理消息后才返回,继续执行。这两个函数的返回值也不同,PostMessage的返回值表示PostMessage函数执行是否正确,而SendMessage的返回值表示其他程序处理消息后的返回值。