learn, think, share, communication
Posts tagged 消息循环
windows的消息队列与消息循环
Mar 27th
从最初开始学写Windows应用程序以来,都免不了和Windows消息打交道,但是事实上很长时间都没能把Windows的消息机制彻底弄清楚。本文记叙了我对Windows消息机制以及线程与消息关系的理解,因为水平所限,不免会有些错漏,希望对此有了解的同学指正。
1、Windows的消息队列与消息循环
所有创建了窗口的Windows程序,都需要运行一个消息循环,我们在无数的Windows编程书籍中都可以看到这样的经典代码:
1: while (GetMessage(&msg, hWnd, 0, 0) > 0)
2: {
3: TranslateMessage(&msg);
4: DispatchMessage(&msg);
5: }
这里的hWnd就是创建的窗口句柄,上述循环会不断的把该窗口(hWnd)相关的消息取出来,并分发到消息处理函数当中。
GetMessage函数是用来获取当前线程消息队列当中的消息的,其中的第二个参数如果传递一个窗口句柄,那么就会获取该窗口相关的消息,如果传NULL,那么会将线程消息队列中所有的消息都取出来。如果创建了多个窗口,而只对其中一个窗口句柄调用GetMessage形成消息循环,那么别的窗口都会毫无响应。
这里需要补充说明一个概念:消息队列是操作系统为每个需要处理消息的线程创建的,任何线程只要调用过与消息有关的函数(如,GetMessage,PeekMessage),操作系统就会为该线程创建消息队列。可能有人会问,那没有窗口的线程,操作系统也有必要为其创建消息队列么?这是有可能的,因为我们可以通过诸如PostThreadMessage的Api向别的线程或者本线程发送消息,如果目标线程没有消息队列,会导致这个函数返回失败。
做一个验证上述想法实验:
我们撰写类似于如下代码(所有的示例代码我都已经在Windows7系统上编写程序做过实验,这里忽略与要说明内容无关的细节并不影响对原理的理解,就不再将完整代码附上,读者感兴趣的话可以自行实验)
1: HWND hWnd1 = CreateWindow(…);
2: HWND hWnd2 = CreateWindow(…);
3: while (GetMessage(&msg, hWnd1, 0, 0) > 0)
4: {
5: TranslateMessage(&msg);
6: [...]