2.05 消息循环原理
消息循环的阻塞
GetMessage 从系统获取消息, 将消息从系统中移除, 阻塞函数. 当系统无消息时, 会等待下一条消息
OeekMessage 以查看的方式从系统获取消息, 可以不将消息从系统移除, 非阻塞函数. 当系统无消息时, 返回FALSE, 继续执行后续代码.
BOOL PeekMessage(
LPMSG lpMsg, // 信息
HWND hWnd, // 窗口句柄
UINT wMsgFilterMin, // 附加消息1
UINT wMsgFilterMax, // 附加消息2
UINT wRemoveMsg //移除标识, 是否像GetMessage一样移除消息 PM_REMOVE/ PM_NOREMOVE
);
while(1){
if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){
if(GetMessage(&nMsg,NULL,0,0)){
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}else{
return; // 退出程序
}
}else{
// 没消息 空闲处理
WriteConsole(g_hOutput,"Onldle",strlen("Onldle"),NULL,NULL);
}
}
发送消息
SendMessage -> 消息队列 -> GetMessage -> TranslateMessage -> DispatchMessage -> WndProd(窗口处理函数)
SendMessage: 发送消息(打电话),阻塞, 会等候消息处理的结果。
PostMessage: 投递消息(投递邮筒),消息发出后立刻返回,不等候消息执行结果。
BOOL SendMessage/PostMessage(
HWND hWnd, //消息发送的目的窗口
UINT Msg, //消息ID
WPARAM wParam, //消息参数
LPARAM lParam //消息参数
);
PostQuitMessage(0);
PostMessage(hWnd,WM_QUIT,0,0);
区别
SendMessage 发送到消息队列, PostMessage 发到(不是消息队列)
SendMessage 函数会将调用线程阻塞,直到消息处理完毕并返回结果。而 PostMessage 函数则不会阻塞调用线程,它只是将消息放入队列中,由消息循环来异步处理。
消息分类
系统消息- 系统定义好的消息,可以直接在程序中使用, 只负责发送或处理. ID为 0- 0x03FF (1024个)
用户自定义消息- 自行发送并自行处理. ID范围为 0x0400 - 0x7FFF(31743)
自定义消息宏: WM_USER(即0x0400)
// 自定义消息
// 定义
#define WM_MYMESSAGE WM_USER+10(小于31743的值)
// 发送
PostMessage(hWnd,WM_MYMESSAGE,1,2);
// 接受
case WM_MYMESSAGE:
xx(hWnd,wParam,lParam); // 处理函数
break;