又查阅了些资料,发现下面这张图,能够很好的解释windows的消息循环机制。图很简单明了,就不作过多的解释了。
1、消息队列
(1)消息队列的容量有多大?
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\ 下 USERPostMessageLimit 定义了队列的最大长度,默认为10000;
(2)消息来源分为Hardware event或者是application,application一般会指定窗口或者线程发送消息,hardware event, 比如鼠标移动,键盘输入,都是由相应的设备驱动将这些event,转换成消息,放入系统消息队列。
(3)是不是所有的消息都要经过消息队列呢?
答案是,NO! 消息分为队列消息和非队列消息。队列消息需要经过消息队列,非队列消息不需要,他们直接被传入指定窗口的窗口过程进行处理。PostMessage发送的消息是队列消息,它会把消息Post到消息队列中;SendMessage发送的消息是非队列消息, 被直接送到窗口过程处理。
(4)消息队列中,大部分消息都是按照FIFO的方式进行处理,但也有例外。WM_PAINT,WM_TIMER, WM_QUIT只有在Queue中没有其他消息的时候才会被处理,WM_PAINT消息还会被合并以提高效率。
2、消息循环
(1)取消息GetMessage / PeekMessage,GetMessage属于阻塞式API。这两个API除了可以取消息,还可以对消息做一些过滤,只需要传入相应的参数就可以了。
(2)TranslateMessage 翻译消息,注意,在包含有热键和模态窗口消息的时候,还需要调用IsDialogMessage和TranslateAccelarator进行消息的翻译;
(3)DispatchMessage将控制权交给系统,系统将消息分发给对应的窗口过程。发送给窗口过程的消息不包括消息发送时间和坐标位置,如果需要的话,可以通过API函数获取;
3、窗口过程
窗口过程对所有的消息都会做处理,application可以选择自己关系的消息做一些特殊处理,其余的消息可以交给windows的默认窗口过程DefWindowProc。
经过以上了解后,对上文,gtest单元测试中遇到的问题就可以解决了。
在main()中创建一个工作线程,线程中创建一个窗口,定义窗口过程,创建消息循环。
主线程执行gtest用例,工作线程,执行相应的被测代码。
问题得到解决。