DispatchMessage是异步的吗

          这几天面试失败,是由于对一些知识不够深入。虽然自己对这些东西‘大致了解’,但是要进大公司,那还是远远不够滴,所以务必做到知道一些知识的原理。开写这一些博客就是这个目的。

消息循环中

While(GetMessage(&msg,NULL,0,0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
DispatchMessage将消息分发到窗口函数中,请问:DispatchMessage是直接返回还是等待WndProc处理完毕再返回? 经过网上多方求证和自己平时调试程序的经验来看,下面给出探讨。

如果直接返回,那一定会造成冲突(几个消息一起处理了),所以我认为肯定是等待WndProc处理完毕后再返回继续取出下条指令来处理。 

还有DispatchMessage究竟干了什么呢?有没有想过点击一个按钮时,为什么其父窗口会收到WM_COMMAND消息?点击程序关闭按钮时,程序究竟做了哪些操作?其实这些都是DispatchMessage的功劳。

DispatchMessage负责:
  1、将子窗口的消息(如WM_LBUTTONUP,转换成WM_COMMAND发给父窗口) WM_COMMAND和WM_NOTIFY
2、向同一线程的不同窗口的窗口处理函数分派消息。

     再回答上面的问题就有眉目了。

当点击一个按钮松开时,会发送WM_LBUTTONUP消息,DispatchMessage根据消息的坐标位置判断其在按钮上,然后再给其父窗口发送WM_COMMAND消息(经调试得知,不是发送消息到消息队列,而是直接SendMessage到窗口消息过程。)关闭程序时过程也大体一样,但是过程更加复杂。他通过WM_NCLBUTTONUP来判断,然后进行一系列操作。

DispatchMessage到底干了什么 ?
  如果只是去调用相应的窗口,那自己写个switch不就可以了, DispatchMessage与switch不同之处在于DispatchMessage会先调用windows,进入管态(大概是range   0),然后再由windows调用窗口的函数。  
  为什么这么麻烦?  
  因为这样windows就可以知道你的程序运行到什么情况了, windows来调用你的窗口,这样你的窗口返回的时候windows就知道你已经处理过一个消息了,如果没有新的消息进入消息队列windows就不再会给你的进程分配时间片  
  如果是你自己写switch的话,windows就不可能这样灵活的分配时间资源利用率就会降低 ,那么还要消息循环干什么,windows直接把消息发给窗口不就可以了吗?  
  因为你要在消息循环里把KEY_DOWN和KEY_UP组合成WM_CHAR,还可以直接屏蔽掉许多对你来说无用的消息,加快速度 。
DispatchMessage这一套机制大概是windows里最难理解的部分了


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
异步线程中使用PostMessage或PostThreadMessage发送消息,可以向指定的窗口或线程发送消息,让其在消息循环中处理。一般情况下,我们可以自定义特定的消息类型来传递数据或通知事件。 具体实现可以参考以下步骤: 1. 定义消息类型,可以使用WM_APP+数字来定义自定义消息类型,例如#define WM_MY_MESSAGE (WM_APP + 1)。 2. 使用PostMessage或PostThreadMessage发送消息,其中PostMessage用于向指定的窗口发送消息,PostThreadMessage用于向指定的线程发送消息。例如,可以使用以下代码向指定窗口发送消息: ``` HWND hWnd = ::FindWindow(NULL, _T("Window Title")); if (hWnd != NULL) { ::PostMessage(hWnd, WM_MY_MESSAGE, WPARAM wParam, LPARAM lParam); } ``` 3. 在窗口或线程的消息循环中处理自定义消息。 对于窗口,可以在WndProc函数中添加对自定义消息的处理,例如: ``` LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_MY_MESSAGE: // 处理自定义消息 break; // 其他消息处理 } return DefWindowProc(hWnd, message, wParam, lParam); } ``` 对于线程,可以在线程函数中使用GetMessage或PeekMessage函数获取消息并处理,例如: ``` DWORD WINAPI ThreadFunc(LPVOID lpParam) { MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { if (msg.message == WM_MY_MESSAGE) { // 处理自定义消息 } else { TranslateMessage(&msg); DispatchMessage(&msg); } } return 0; } ``` 需要注意的是,PostMessage和PostThreadMessage异步发送消息,即发送后不会等待消息处理完毕再返回。如果需要同步发送消息并等待处理完毕再返回,可以使用SendMessage或SendMessageTimeout函数。同时,由于异步发送消息可能会导致消息被快速发送过多,因此在发送消息前应该加入消息队列,保证消息的顺序和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值