SendMessage和PostMessage 的区别,以及消息循环路由

SendMessage和PostMessage 的区别,以及消息循环路由_第1张图片


一、下面示例函数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循环就推出,程序也就结束了
 }


你可能感兴趣的:(C++,VC++)