GetMessage PeekMessage WaitMessage简介

    消息的接收主要有3个函数: GetMessagePeekMessageWaitMessage
   GetMessage原型如下:
    BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
  该函数用来获取与hWnd参数所指定的窗口相关的且wMsgFilterMin和wMsgFilterMax参数所给出的消息值范围内的消息。需要注意的是,如果hWnd为NULL,则 GetMessage获取属于调用该函数应用程序的任一窗口的消息,如果wMsgFilterMin和 wMsgFilterMax都是0,则GetMessage就返回所有可得到的消息。函数获取之后将删除消息队列中的除 WM_PAINT消息之外的其他消息,至于 WM_PAINT则只有在其处理之后才被删除。
  
PeekMessage原型如下:
    BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
  该函数用于查看应用程序的消息队列,如果其中有消息就将其放入lpMsg所指的结构中,不过,与 GetMessage不同的是, PeekMessage函数不会等到有消息放入队列时才返回。同样,如果hWnd为NULL,则PeekMessage获取属于调用该函数应用程序的任一窗口的消息,如果hWnd=-1,那么函数只返回把hWnd参数为NULL的 PostAppMessage函数送去的消息。如果 wMsgFilterMin和wMsgFilterMax都是0,则 PeekMessage就返回所有可得到的消息。函数获取之后将删除消息队列中的除 WM_PAINT消息之外的其他消息,至于 WM_PAINT则只有在其处理之后才被删除。
  WaitMessage原型如下:
    BOOL WaitMessage();
    当一个应用程序无事可做时,该函数就将控制权交给另外的应用程序,同时将该应用程序挂起,直到一个新的消息被放入应用程序的队列之中才返回。
  
    消息的处理
  接下来我们谈一下消息的处理,首先我们来看一下VC中的消息泵:
   while(GetMessage(&msg, NULL, 0, 0))
  {
  if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
  {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
  }
  }
  
首先, GetMessage从进程的主线程的消息队列中获取一个消息并将它复制到MSG结构,如果队列中没有消息,则 GetMessage函数将等待一个消息的到来以后才返回。如果你将一个窗口句柄作为第二个参数传入GetMessage,那么只有指定窗口的的消息可以从队列中获得。 GetMessage也可以从消息队列中过滤消息只接受消息队列中落在范围内的消息。这时候就要利用 GetMessage/PeekMessage指定一个消息过滤器。这个过滤器是一个消息标识符的范围或者是一个窗体句柄,或者两者同时指定。当应用程序要查找一个后入消息队列的消息是很有用。 WM_KEYFIRSTWM_KEYLAST 常量用于接受所有的键盘消息。 WM_MOUSEFIRSTWM_MOUSELAST 常量用于接受所有的鼠标消息。
  然后 TranslateAccelerator判断该消息是不是一个按键消息并且是一个加速键消息,如果是,则该函数将把几个按键消息转换成一个加速键消息传递给窗口的回调函数。处理了加速键之后,函数 TranslateMessage将把两个按键消息 WM_KEYDOWNWM_KEYUP 转换成一个 WM_CHAR,不过需要注意的是,消息 WM_KEYDOWN, WM_KEYUP仍然将传递给窗口的回调函数。
  处理完之后, DispatchMessage函数将把此消息发送给该消息指定的窗口中已设定的回调函数。如果消息是 WM_QUIT,则 GetMessage返回0,从而退出循环体。应用程序可以使用 PostQuitMessage来结束自己的消息循环。通常在主窗口的 WM_DESTROY消息中调用。
  下面我们举一个常见的小例子来说明这个消息泵的运用:
   if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
  {
  if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
  }
  这里我们接受所有的键盘消息,所以就用 WM_KEYFIRST WM_KEYLAST作为参数。最后一个参数可以是 PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否应该从消息队列中删除。
  所以这段小代码就是判断是否按下了Esc键,如果是就进行处理。
GetMessagePeekMessage是Windows API中用于处理消息队列的函数。它们的主要区别如下: 1. GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,如果有消息,就返回true,否则返回false。PeekMessage也可以从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设置为PM_REMOVE,消息则被取出并从消息队列中删除;如果设置为PM_NOREMOVE,消息就不会从消息队列中取出。 2. 如果GetMessage从消息队列中取不到消息,则线程就会被操作系统挂起,等到操作系统重新调度该线程时才会继续执行;而PeekMessage不会挂起线程,如果没有消息,它会立即返回,并且线程会继续执行。 3. GetMessage每次都会等待消息,直到取到消息才返回;而PeekMessage只是查询消息队列,没有消息就立即返回,从返回值判断是否取到了消息。 综上所述,GetMessagePeekMessage的区别在于GetMessage会阻塞线程并且从消息队列中删除消息,而PeekMessage不会阻塞线程并且可以选择是否删除消息。 #### 引用[.reference_title] - *1* *2* [GetMessagePeekmessage区别](https://blog.csdn.net/lala_achun/article/details/6201486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [GetMessagePeekMessage 的区别](https://blog.csdn.net/hellokandy/article/details/52275366)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值