zoukankan      html  css  js  c++  java
  • 详谈Windows消息循环机制

    一直对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


  • 相关阅读:
    用TPLINK 无线网卡设置无线工作环境
    ChartDirector与JFreeChart两款主要web图表工具调研报告
    发现奇怪的问题,TOMCAT居然跟本机网卡的DNS设置有关
    解决Oracle监听器服务不能启动的问题
    JAVA 调用 .NET写的WEBSERVICE
    Windows Forms 实现安全的多线程详解
    异步调用与多线程
    关于.NET异步调用的初步总结
    c#中的多线程同步
    WinForm界面开发
  • 原文地址:https://www.cnblogs.com/kevinWu7/p/10163511.html
Copyright © 2011-2022 走看看