windows消息机制摘记
Windows 操作系统为每个线程维持一个消息队列,当事件产生时,操作系统感知这一事件的发生,并包装成消息发送到消息队列,应用程序通过GetMessage()函数取得消息并存于一个消息结构体中,然后通过一个TranslateMessage()和DispatchMessage()解释和分发消息,下面的代码描述了Windows 的消息循环。
while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; }
消息结构体:
typedef struct tagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
}MSG;
TranslateMessage(&msg)对于大多数消息而言不起作用,但是有些消息,比如键盘按键按下和弹起(分别对于KeyDown和KeyUp 消息),却需要通过它解释,产生一个WM_CHAR消息。DispatchMessage(&msg)负责把消息分发到消息结构体中对应的窗口,交由窗口过程函数处理。GetMessage()在取得WM_QUIT 之前的返回值都为TRUE,也就是说只有获取到WM_QUIT消息才返回FALSE,才能跳出消息循环。
取得的消息将交由窗口处理函数进行处理,对于每个窗口类Windows 为我们预备了一个默认的窗口过程处理函数DefWindowProc(),这样做的好处是,我们可以着眼于我们感兴趣的消息,把其他不感兴趣的消息传递给默认窗口过程函数进行处理。每一个窗口类都有一个窗口过程函数,此函数是一个回调函数,它是由Windows 操作系统负责调用的,而应用程序本身不能调用它。以switch 语句开始,对于每条感兴趣的消息都以一个case 引出.
LRESULT CALLBACK WndProc( HWND hwnd,UINT message,WPARAMwParam,LPARAM lParam) { ...... switch(uMsgId) { case WM_TIMER://对WM_TIMER 定时器消息的处理过程 break; case WM_LBUTTONDOWN://对鼠标左键单击消息的处理过程 break; . … default: return DefWindowProc(hwnd,uMsgId,wParam,lParam); } return 0; }
对于不感兴趣的消息,交给DefWindowProc()函数进行处理,并需要返回其处理值。
总结一句话:人操作电脑,windows系统将接收的消息放在消息队列中;应用程序通过GetMessage(&msg, NULL, 0, 0)取出对本程序做的操作消息,放在本程序MSG结构体的实例化中;再由 TranslateMessage (&msg) ; DispatchMessage (&msg) ;把消息发送给LRESULT CALLBACK WndProc函数处理;再通个switch判断消息;你通过鼠标点了我的某某按钮吗?是,就让程序干case里的事;