zoukankan      html  css  js  c++  java
  • Windows API的消息处理机制

      上个学期找实习失利,让我觉得自己基础打得不够牢固,所以在华为实习的这三个月里,每天下班都在复习理论课的知识,顺便刷了一个月的 LeetCode。本来以为找工作是势在必得了,结果这个学期秋季校招的坑爹经历导致现在还没有拿到一家公司的 offer。华为实习一结束,回学校的第二天就去参加了 360 在广州的笔试,进了面试以后却又喜闻乐见地一面就被干掉了。再加上之前 milo yip 大大对我提的建议,思来想去,感觉还是自己的简历不够拿得出手。现在开始都没剩下几家想进的公司了,为了不失业只能提早为明年的春招做准备了 T_T。

      昨天在京东买的《游戏引擎架构》送到了,大致翻阅了一遍后,我便决定开始编写自己的游戏引擎了。2014年10月20日,Rune Words Game Engine项目正式宣布启动!

      第一天,我主要对要实现的模块进行了初步构思,在 github 上建立了资源仓库。

      今天是第二天,我重温了一下 Ogre 和自己原来做的游戏的源代码,然后决定从渲染窗口开始写起,要建立窗口就不得不考虑窗口类如何对消息进行处理,于是查阅了一下 Windows API 消息处理的资料,现在将自己的理解整理记录一下。

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4041700.html 


     

    1. 在使用 Windows API 编写窗口程序时,我们主要通过以下几个函数对消息进行处理:

    ① BOOL WINAPI GetMessage(LPMSG lpMsg, HWND hWnd, UNIT wMsgFilterMin, UINT wMsgFilterMax);

    ② BOOL WINAPI PeekMessage(LPMSG lpMsg, HWND hWnd, UNIT wMsgFilterMin, UINT wMsgFilterMax, UNIT wRemoveMsg);

    GetMessage 函数和 PeekMessage 函数的作用都是从系统的消息队列中获取消息,如果成功得到消息的话返回 true,否则返回 false。所不同的是,GetMessage 在消息队列为空(即无法获取消息)时会进入等待,直到获取到一个消息为止;PeekMessage 无论是否成功获取到消息,都会立即返回。

     

    ③ BOOL WINAPI TranslateMessage(const MSG *lpMsg);

    TranslateMessage 函数的作用类似于“将 WM_KEYDOWN+WM_KEYUP 的组合消息转换为字符消息 WM_CHAR(一个按键的按下和释放表示输入了一个字符)”,若发生转换返回 true,否则返回 false。注意,转换后的消息是新生成的,lpMsg 指向的消息并不会被修改。

     

    ④ LRESULT WINAPI DispatchMessage(const MSG *lpMsg);

    DispatchMessage 函数的作用是将消息发送给窗口程序,让窗口函数调用回调函数 WNDPROC 对消息进行处理。

     

    ⑤ LRESULT (CALLBACK* WNDPROC)(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

    实际上,WNDPROC 并不是一个函数,而是一个函数指针,指向用于响应窗口消息的消息处理函数,它应该在窗口初始化前被赋值。

     

    ⑥ BOOL WINAPI PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

    ⑦ LRESULT WINAPI SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

    PostMessage 函数和 SendMessage 函数都用于发送消息,不同的地方是:PostMessage 只负责将消息放入到消息队列中,之后便立即返回(不管消息是否被处理);SendMessage 要等到收到消息的返回码后才会返回(等待直到确认消息被处理)。

     

    2. 在上述函数的参数中,LPMSG(Long Ptr of Message)是指向存储消息的结构体(MSG)的指针;HWND(Handle of Window)是窗口的句柄(也是一个指向结构体的指针)。

     

    3. 利用这些 Windows API,一个完整的消息循环处理流程可以表示如下:

      PeekMessage / GetMessage —true—> TranslateMessage  

            ↑                  ↓ 

         WindowProc <————————— DispatchMessage 

     

    4. 消息循环处理的代码示例:

    // Author DaBianYiLuoKuang.
    // http://www.cnblogs.com/dbylk/
    
    // Main message loop
    MSG msg = { 0 };
    while (WM_QUIT != msg.message) 
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
      {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else 
      {
            Sleep(20);
            // DoSomething
        }
    }
  • 相关阅读:
    06C++11线程池
    05C++11生产者消费者模式2
    04C++11生产者消费者模式
    03智能指针之shared_ptr
    洛谷P1262+Tarjan缩点
    洛谷P1147 连续自然数和
    洛谷P1970 花匠
    接下来的一些操作
    树状数组 代码(洛谷为例)
    洛谷P1576 最小花费
  • 原文地址:https://www.cnblogs.com/dbylk/p/4041700.html
Copyright © 2011-2022 走看看