Windows消息机制
Windows是一个消息驱动的操作系统。
什么是消息
消息是一种手段,可以帮助应用程序和操作系统、应用程序之间 进行通信。
操作系统可以发给应用程序一个消息,告诉应用程序某个特定的事件发生了。比如:当用户点击鼠标或键盘都会引发Windows发送相应的消息。应用程序也可以产生一个消息,使窗口执行特定的任务,或与其它应用程序通信。
从数据结构的角度来看,消息是一个结构体,包含了消息的类型标识符和其他附加信息。
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *LPMSG, *PMSG;
消息的种类
根据定义者来分类:
根据发送途径分类:
- 队列消息:消息先保存在消息队列中,之后再被分发到对应的窗口处理函数。如鼠标、键盘消息。
- 非队列消息:消息会绕过消息队列,直接被发送到对应的窗口处理函数。如WM_ACTIVATE、WM_SETFOCUS、WM_SETCURSOR、WM_WINDOWPOSCHANGED,应用程序调用SetWindowPos时会产生这些消息。
消息队列
Windows系统中有两种消息队列:
- 系统消息队列:由系统维护,唯一的消息队列。计算机的所有输入设备都由系统监控,设备驱动会把输入操作转化成消息,放在系统消息队列中,系统再将其复制到相应的应用程序消息队列中。
- 应用程序消息队列:每个GUI线程都会维护一个消息队列(当该线程第一次调用GDI函数时,系统才会为它创建消息队列),应用程序中的消息循环会在它的消息队列中检索每个消息并发送给相应的窗口处理函数。
小结:当一个事件发生时,Windows会先将输入的消息放入系统消息队列,再将其复制到相应的应用程序队列中,应用程序中的消息循环
会在它的消息队列中检索每个消息并发送给相应的窗口函数。一个事件从发生到到达处理它的窗口函数必须经历上述过程。
注意:事件有非抢先性,即不论事件的急与缓,总是按到达的先后排队(一些系统消息除外),这可能导致一些外部实时事件得不到及时的处理。
常用的消息函数
SendMessage :将消息发给目标窗口。等消息处理完毕后,函数才会返回;否则一直阻塞。
PostMessage :将消息发给目标窗口所在的消息队列中,然后立即返回。
PostThreadMessage :将消息发给指定线程的消息队列中,然后立即返回。
注意:SendMessage 发送的是非队列消息,PostMessage 发送的是队列消息。
LRESULT
SendMessageW(
HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
BOOL
PostMessageW(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
BOOL
WINAPI
PostThreadMessageW(
DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
GetMessage :从指定的窗口中取出消息(消息范围在wMsgFilterMin~wMsgFilterMax之间),消息取出后就从消息队列中删除该消息。取不到消息线程会挂起,直到取出。
PeekMessage :从消息队列中查询消息,如果有消息则返回TRUE,没有则返回FALSE。
WaitMessage :当一个线程的消息队列中没有消息时,WaitMessage会使该线程中断并处于等待状态,把控制权交给其他线程,直到被中断线程的消息队列中有新消息。
BOOL
GetMessageW(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax);
BOOL
PeekMessageW(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg);
BOOL WaitMessage(VOID);
TranslateMessage :把一个virtual-key消息转化成字符消息,并放到当前线程的消息队列中,消息循环下一次取出处理。
BOOL
TranslateMessage(CONST MSG *lpMsg);
DispatchMessage :应用程序通过消息循环将消息派发到目标窗口。
LRESULT
DispatchMessageW(CONST MSG *lpmsg);
常用的消息
-
WM_COMMAND :当用户从菜单或按钮中选择一条命令或一个控件时,该消息被发送给它的父窗口,或者当一个快捷键被释放时发送。对应0111h。 -
WM_DESTROY :当一个窗口被销毁时发送该消息。对应02h。 -
WM_GETTEXT :用户程序发送一条WM_GETTEXT消息,会将对应窗口的文本复制到一个由应用程序提供的缓冲区中。对应0Dh。 -
WM_QUIT :当应用程序调用PostQuitMessage时,生成WM_QUIT消息。对应012h。 -
WM_LBUTTONDOWN :当光标停在一个窗口的客户区且用户按下鼠标左键时,WM_LBUTTONDOWN消息将被发送。如果鼠标动作未被捕获,这条消息将被发送给光标下的窗口;否则将被发送给已经捕获鼠标动作的窗口。对应0201h。
|