消息不过是定义了一个结构MSG, 每个应用程序就自己有自己的消息队列.
typedef struct tagMSG { // msg
HWND hwnd; //发送给的对应窗口句柄
UINT message; //消息的类型
WPARAM wParam; //消息传送第一个32位参数,
LPARAM lParam; //消息传送第二个32位参数
DWORD time; //发送消息的时间
POINT pt; //发送消息时鼠标所在的位置
} MSG;
每个消息都对应着一个窗口。USER模块是管理窗口的,一般每个窗口自己有一个消息队列。当键盘或鼠标有消息时,就会发给激活的窗口,当在程序设计中用SendMessage来发送消息时,就会明确指定窗口句柄,当运行此函数后,就会把消息放到此窗口的消息队列中。
所有的程序都通过系统消息队列来调用USER的DLL来完成工作,所以,这个DLL就有机会轮循,来查看什么程序有消息。如果某程序有消息,就会去调用这个程序的窗口函数,而这个窗口在生成时,必须注册在这个窗口类中。在窗口类中就有窗口的处理消息函数的地址指针。当程序有消息时,USER就调用这个函数的地址,去完成消息处理。
在键盘或鼠标这类设备中,消息一般只是发给当前激活的窗口,当然其他窗口也可以得到消息,可以通过程序直接发送。还有一些情况也可以得到消息,例如时钟消息TIMER是底层驱动的,当TIMER产生一个消息时,它会查找当前窗口中定义了时钟消息的时间是否来到,当时间到了,就会在对应的窗口函数中放入一时间消息事件。
有两种消息的发送函数,一种是立即发送消息,另一种是队列调用。
LRESULT SendMessage(
HWND Hwnd
UINT uMsg,
WPARAM wParam,
LPARAM lParam );
LRESULT PostMessage(
HWND Hwnd
UINT uMsg,
WPARAM wParam,
LPARAM lParam );
这两种函数的接口参数基本上是一样的。
HWnd:将要发送给消息的对应的窗口句柄。它实际指向消息发给谁。
UMsg:消息的类型,说明被发送的消息是什么消息。
WParam:第一个32位的参数。
lParam:第二个32位的参数。
可不能小看这两个参数,它们可是很有用的。
SendMessage:当用它向一个窗口(也可以是本身窗口)发送消息时,它不会把消息放入消息队列中,而是直接发送给窗口。窗口接到消息后就立刻处理,处理完成后,把结果作为返回值传送回来。这样的处理过程就像是操作函数一样。
PostMessage:当用它向一个窗口(也可以是本身窗口)发送消息时,它把消息放入消息队列中,自己什么也不干就会返回,到底消息什么时候处理,有没有被处理它是不知道的。