Windows的消息函数:SendMessage PostMessage BroadcastSystemMessage PostThreadMessage SendMessageCallback SendMessageTimeout SendNotifyMessage
消息队列包括SendMessageList链表,PostMessageList链表,HardwareMessagesList链表(键盘鼠标)。
消息队列是线程的一部分。CreateThread创建的普通线程,当调用任何消息相关的函数,Windows就会给线程创建一个消息队列数据结构,即,将线程从普通线程切换到GUI线程。
1. SendMessage
将消息推送到消息队列的SendMessageList链表,并等待消息处理返回。
对于同一线程,实际效果相当于直接调用消息过程处理函数,但会有多次函数调用操作(调用消息过程分发函数),所以,效率较低。而很多Windows的API函数,例如GetWindowText对同一进程的窗口操作,实际是调用SendMessage发送WM_GETTEXT消息获取窗口或控件文本。这也就意味着,如果一些频繁的函数中调用类似的API,其效率会极其低下。一个典型的情况,我们在自绘控件时,WM_PAINT的处理中,可能就频繁调用类似于GetWindowText这样的API函数。而Windows在设计中,窗口和控件都是有句柄的,进而导致复杂窗口中类似的API调用将占用大量的资源。所以,Windows的窗口程序实际效率并不高。相比之下,Qt反而更节约资源。
并且,如果随意调用SendMessage,还可能导致程序死锁。SendMessage的消息过程处理函数中,再调用SendMessage或GetWindowText这样的API函数,就会死锁。这种情况,相信很多程序员都遇到过。
可以查阅Windows内核相关的资料了解。
对于不同线程,消息会放入SendMessageList链表,并等待消息处理返回。可以使用InSendMessage判断是否处于SendMessage过程中,但仅限于不同线程的情况。
个人理解:当SendMessageList链表满了的情况下,SendMessage可能会一直等待,直到投递消息成功并处理成功。
2. SendMessageCallback
发送消息后,即返回。通过回调函数获得消息处理结果。
3. SendMessageTimeout
发送消息后,等待消息处理返回。但有时间限制,超时则返回。注意:超时返回不代表消息发送失败,可能已经在处理中。所以,如果重试发送的话,需要考虑消息重复的情况。
4. SendNotifyMessage
同一线程,发送消息后,等待消息处理返回。
不同线程,等待投递到SendMessageList链表,即返回。不等待消息过程处理函数处理,但可以确保消息投递到指定线程。
5. BroadcastSystemMessage
广播消息。用到的场景较少,在不知道对方窗口句柄的情况,进行全系统广播。较浪费资源,一般不建议使用。
6. PostMessage
将消息推送到消息队列的PostMessageList链表,不需要等待消息处理返回。
7. PostThreadMessage
将消息推送到消息队列的PostMessageList链表,不需要等待消息处理返回。不同于PostMessage的是,PostMessage关联于窗口句柄,PostThreadMessage关联于线程ID。一个线程可以有多个窗口,但一个窗口只属于一个线程。
转载请注明来源,谢谢。
有偿解决C++编程问题,承接项目定制开发;寻一份全职或兼职Windows C++开发工作。联系邮箱:[email protected]。