一、下面示例函数func()中有PostMessage和SendMessage
int MainWnd(...)
{
MSG msg;
while(1)
{
//当没有消息时,GetMessage不返回,程序就停在这里
GetMessage(&msg,NULL,0,0)
TranslateMessage(&msg);
DispatchMessage(&msg);
}
........
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_CLOSE:
{
}
break;
case WM_PASTE:
{
}
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}
void func()
{
........
........
PostMessage(hWnd,WM_CLOSE,NULL,NULL)
//PostMessage,只是简单的把WM_CLOSE放在消息队列里,然后函数立刻返回,
//继续执行下面的代码,那我们要执行的WM_CLOSE什么时候执行呢?这个系统说了算
//系统会在合适的时候从消息队列里取出WM_CLOSE,在代码里体现为
//GetMessage返回,参数msg.message设为WM_CLOSE,之后如代码所示,会执行到
//DispatchMessage,DispatchMessage内部调用SendMessage,SendMessage内部调用
//窗口函数WndProc,最后才会跳到 “case WM_CLOSE”
........
........
SendMessage(hWnd,WM_PASTE,NULL,NULL)
//SendMessage内部调用了WndProc,之后就会跳转到"case WM_PASTE" ,再之后WndProc返回,
//SendMessage返回。程序才会继续往下执行。从理解的角度来看,你完全可以把
//SendMessage(hWnd,WM_PASTE,NULL,NULL) 等同于调用函数
//WndProc(hWnd,WM_PASTE,NULL,NULL) ,这样就很好理解了。
}
二、总结来说:
1.
PostMessage(WM_CLOSE)简单把消息放入队列并返回->
GetMessage->DispatchMessage->SendMessage->WndProc->处理消息WM_CLOSE
2.
SendMessage(WM_CLOSE) 就相当于调用WndProc(WM_CLOSE)
三、PostMessage、SendMessage和 GetMessage 内部结构简化:
PostMessage内部结构简化:
BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
....................
把消息放到窗口消息队列中
....................
return TRUE;
}
SendMessage内部结构简化:
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
....................
....................
LRESULT ret=WndProc(hWnd,Msg,wParam,lParam);
....................
....................
return ret;
}
GetMessage内部结构简化:
BOOL GetMessage(LPMSG lpMsg,HWND hWnd,wMsgFilterMin,wMsgFilterMax)
{
....................
GetMessage是一个很神奇的函数,它不是按我们常规那样理解的。
常规函数里的代码是一行一行往下执行并最后返回,但GetMessage里有堵塞结构,
系统如果发现消息队列里没有消息,就让代码停下来,整个程序也就没有“运动了”
(后台程序往往处于这种情况)
不停地查看消息队列里是否有消息,如果没有就停在这里,不往下执行。
如果发现有消息了,比如系统发现鼠标点击了窗口,会把WM_LBUTTONDOWN
放到消息队列里,这时就可以从队列中取出WM_LBUTTONDOWN消息,继续往下执行
....................
lpMsg->message=WM_LBUTTONDOWN;
....................
return TRUE; //GetMessage基本都是返回TRUE,否则while循环就推出,程序也就结束了
}