欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

详谈Windows消息循环机制

程序员文章站 2022-07-14 17:43:19
...

一直对windows消息循环不太清楚,今天做个详细的总结,有说错的地方,请务必指出。

用VS2017新建一个win32 Application的默认代码如下:

程序入口                                          //intWINAPI WinMain
定义窗口类                                      //typedef struct tagWNDCLASSA
注册窗口类                                      //RegisterClass(&wndclass))
生成窗口                                          //CreateWindow
更新窗口                                          //ShowWindow(hwnd,iCmdShow);
显示窗口                                          //UpdateWindow(hwnd);
消息循环                                          //while(GetMessage(&msg,NULL,0,0))
窗口消息处理(回调函数)                     //LRESULT CALLBACK WndProc

消息循环的代码如下:
while(GetMessage(&Msg, NULL, 0, 0) > 0) 
{ 
    TranslateMessage(&Msg);    //转换
    DispatchMessage(&Msg);     //分发
} 



这里有几个概念,容易混淆:
1.系统:
特指windows操作系统

2.应用程序:
指一个程序,比如QQ,或者酷狗之类的都算一个应用程序

3.窗口:
每个应用程序都可以拥有窗口,而且可以有多个,但一般会有一个主窗口。例如QQ的主窗口,但是QQ也有很多类似于设置窗口的子窗口,这些窗口都属于QQ应用程序。

4.消息:
window系统定义了很多种消息,例如,单击鼠标、改变窗口尺寸、按下键盘,这些操作都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息

5.消息循环:
window系统的一种消息机制

6.消息队列:
是属于线程的,是windows系统为线程创建并维护的一个队列,用于存放各类消息。系统自身维护一个系统消息队列,然后还为每个GUI线程线程维护一个线程专门消息队列。

7.线程:
每个线程默认是没有消息队列的,线程只有在第一次调用用户接口时(比如创建窗口,或者是操作UI元素时),系统才为其创建消息队列。一个应用程序可以有多个线程,但只能有一个UI线程,默认为主线程,其他子线程是无法操作UI并创建UI元素的。这是windows规定的


windows消息循环的详细过程:

1.我们创建完win32应用程序,当用户通过对鼠标,键盘操作应用程序时,由于Windows一直监控着I/O设备,该事件首先会被转化成消息,由windows系统捕获,存放于系统消息队列。

2.Windows系统知道该消息应由哪个应用程序处理,然后拷贝到相应的应用程序消息队列。同时将该消息从系统消息队列中删除。

3.应用程序的消息循环不断在执行,此时,调用GetMessage()从消息队列中查找消息,发现了该消息,GetMessage()将返回一个正值,并获取到了该消息Msg;PS:如果消息队列为空,程序将停止执行并等待(程序阻塞)。

4. 然后取出消息(Msg)并将其传递给TranslateMessage()函数,这个函数做一些额外的处理:将虚拟键值信息转换为字符信息。这一步实际上是可选的,但有些地方需要用到这一步。

5. 上面的步骤执行完后,将消息MSG传递给DispatchMessage()函数。DispatchMessage()函数将消息再给windows系统,由windows系统找到目标窗口并分发给该窗口,调用消息对应的窗口过程函数,既窗口的WinPro函数,让WinPro函数处理。WinPro函数可以允许我们对不同的消息做特定的处理,若不处理的话,则会调用DefWindowProc函数,做默认处理,所以为什么默认代码中WinPro的类型是CallBack(回调),因为不是我们主动调用的,是系统回调的

6. 一旦一个消息处理完成,窗口过程WinPro函数返回,DispatchMessage()函数返回,应用程序的消息循环继续while循环,Window系统继续监控各类消息,重复上述步骤

参考资料:http://blog.csdn.net/hellochenlian/article/details/41745799