1018
MFC的消息循环(::GetMessage,::PeekMessage),消息泵(CWinThread:: PumpMessage)和MFC的消息在窗口之间的路由是两件不同的事情。
消息循环就是循环地从App消息队列中取出消息并分发:
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
//第一:注册窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
...
//第二:创建一个该类型的窗口
HWND hWnd;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
......
//第三:启动消息循环,将消息发送给相应的窗口函数
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
消息路由就是《深入浅出》例子中Msg从在Frame、View、Document之间的传递和路由:
在MFC的应用程序中(应用程序类基于CWinThread继承),必须要有 一个消息循环,他的作用是从应用程序的消息队列中读取消息,并把它派送出去(::DispatchMessage)。而消息路由是指消息派送出去之后,系 统(USER32.DLL)把消息投递到哪个窗口,以及以后消息在窗口之间的传递是怎样的。
消息分为队列消息(进入线程的消息队列)和非队列消息(不进入线程的消息队列)。
对于队列消息:
1,最常见的是鼠标和键盘触发的消息,例如 WM_MOUSERMOVE,WM_CHAR等消息;2,还有例如:WM_PAINT、WM_TIMER和WM_QUIT。
当鼠标、键盘事件被触发后,相应的 鼠标或键盘驱动程序就会把这些事件转换成相应的消息,然后输送到系统消息队列,由Windows系统负责把消息加入到相应线程的消息队列中,于是就有了消 息循环(从消息队列中读取并派送消息)。
鼠标键盘 ----硬件驱动程序----> 系统的消息队列 -------Windows系统的调度------> 特定App的消息队列
还有一种是非队列消息,他绕过系统队列和消息队列,直接将消息发送到窗口过程。例如,当用户激活一个窗口系统发送 WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。创建窗口时发送WM_CREATE消息。