当前位置: 首页 > article >正文

windows消息机制

目录

  • 1. 消息队列(Message Queue)
  • 2. 消息循环(Message Loop)
  • 3. 窗口过程(Window Procedure)
  • 4. 消息(Message)
  • 5. 消息发送的两种方式

Windows消息机制是Windows操作系统下应用程序与操作系统之间的一种重要通信方式。通过这一机制,应用程序能够接收来自操作系统的各种事件和请求,并作出相应的响应和处理。以下是Windows消息机制的详细解析:

1. 消息队列(Message Queue)

消息队列是一个用于存储消息的缓冲区。当操作系统有消息需要传递给应用程序时,这些消息会被放入消息队列中。

  • 系统消息队列:这是一个系统唯一的队列,输入设备驱动程序(如键盘、鼠标等)会将用户的操作输入转化为消息并放置于系统队列中,然后系统会将此消息转到目标窗口所在线程的消息队列中等待处理。
  • 线程消息队列(也称为应用程序消息队列):每个GUI线程都会维护这样一个线程消息队列。线程消息队列中的消息会被本线程的消息循环(也称为消息泵)派送到相应的窗口过程(窗口回调函数WndProc)处理。

2. 消息循环(Message Loop)

应用程序通常有一个消息循环,它不断从消息队列中提取消息,并根据消息的类型将其传递给相应的窗口或控件进行处理。这部分代码通常使用以下函数:

   while (GetMessage(&msg, NULL, 0, 0)) {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
   }
  • GetMessage: 从线程的消息队列中取出一条消息,如果消息队列为空,则程序会等待。
  • TranslateMessage: 用于翻译一些消息,比如将键盘消息转换为字符消息。
  • DispatchMessage: 将消息传递给窗口过程(Window Procedure,通常简称为WndProc)。

3. 窗口过程(Window Procedure)

每个窗口都有一个窗口过程(WndProc),它是一个回调函数,用于接收Windows传递给窗口的消息,并处理这些消息。

  LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
      switch (uMsg) {
          case WM_PAINT:
              // 处理重绘窗口的消息
              break;
          case WM_DESTROY:
              PostQuitMessage(0); // 通知系统关闭程序
              break;
          default:
              return DefWindowProc(hwnd, uMsg, wParam, lParam);
      }
      return 0;
  }

当DispatchMessage函数将消息分发到窗口过程时,窗口过程会根据消息的类型和附加数据来执行相应的逻辑,如绘图、更新窗口状态、响应用户输入等。处理完消息后,窗口过程会返回一个值给Windows系统,表示消息已被处理

4. 消息(Message)

  • 系统定义的消息:这些消息是由Windows系统定义的,用于处理各种系统级事件,如窗口的创建、销毁、移动、大小调整等。系统消息ID的范围通常是从0到WM_USER-1(即0x0000到0x03FF)。
  • 应用程序定义的消息:这些消息是由应用程序自己定义的,用于处理特定的应用程序事件。应用程序消息ID的范围从WM_USER(0x0400)开始,到0x7FFF结束。此外,还有一个范围(0xC000到0xFFFF)用于跨应用程序通信,这些消息ID通常通过RegisterWindowMessage函数注册得到。

5. 消息发送的两种方式

在Windows编程中,消息发送是一种基本的通信机制,用于在不同的应用程序、应用程序内的不同窗口或控件之间传递信息。Windows消息系统允许应用程序通过发送和接收消息来执行各种任务,比如响应用户输入、管理窗口和控件的生命周期等。

  • SendMessage:这是一个同步消息发送函数。当调用SendMessage函数时,它会立即将消息发送到指定的窗口或控件,并等待该窗口或控件处理完消息后才返回。这意呀着,如果目标窗口或控件处理消息时耗时较长,那么调用SendMessage的线程将被阻塞,直到消息处理完成。
 LRESULT SendMessage(
   HWND   hWnd,       // 目标窗口的句柄
   UINT   Msg,        // 要发送的消息
   WPARAM wParam,     // 消息附加的额外信息(WPARAM)
   LPARAM lParam      // 消息附加的额外信息(LPARAM)
 );
  • PostMessage:这是一个异步消息发送函数。与SendMessage不同,PostMessage将消息放入目标窗口的消息队列后立即返回,而不等待消息被处理。这意味着调用PostMessage的线程不会被阻塞。
 BOOL PostMessage(
   HWND   hWnd,       // 目标窗口的句柄
   UINT   Msg,        // 要发送的消息
   WPARAM wParam,     // 消息附加的额外信息(WPARAM)
   LPARAM lParam      // 消息附加的额外信息(LPARAM)
 );

示例

假设我们想要向一个窗口发送一个简单的WM_USER消息(一个自定义消息,其值在WM_USER0x7FFF之间):

// 假设hWnd是目标窗口的句柄
const UINT WM_MY_MESSAGE = WM_USER + 1;

// 使用SendMessage发送消息
SendMessage(hWnd, WM_MY_MESSAGE, (WPARAM)0, (LPARAM)0);

// 或者使用PostMessage发送消息
PostMessage(hWnd, WM_MY_MESSAGE, (WPARAM)0, (LPARAM)0);

处理消息

为了在目标窗口中处理这些消息,你需要在窗口过程中(Window Procedure)添加相应的消息处理代码。窗口过程是一个函数,它定义了窗口如何响应各种消息。

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_MY_MESSAGE:
            // 处理WM_MY_MESSAGE消息
            break;
        // 其他消息处理...
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

通过结合使用消息发送函数(如SendMessagePostMessage)和适当的消息处理代码,你可以在Windows应用程序中实现复杂的交互逻辑。


http://www.kler.cn/news/312133.html

相关文章:

  • Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
  • 设计模式 组合模式(Composite Pattern)
  • 【HTTP】认识 URL 和 URL encode
  • KL散度(Kullback-Leibler)
  • java框架
  • 深入理解 MySQL MVCC:多版本并发控制的核心机制
  • vmware,centos8(虚拟机) 的安装
  • Python Web开发中的持续集成与持续交付(CI/CD)
  • cassandra指定配置文件的docker启动方法
  • 【学术会议征稿】第四届计算机、信息工程与电子材料国际学术会议 (CTIEEM 2024)
  • 微信小程序能不能有一种公共的分包,能被普通的分包引用其资源?(内有解决方案)
  • 【测试】博客系统测试报告
  • docker面经
  • 【Mac】系统环境配置
  • mybatisplus分页查询学习
  • QT应用开发的C++功能框架以及实战入门开发项目场景
  • 计算机网路(应用层)
  • 中台架构下的数据仓库与非结构化数据整合
  • Nuxt Kit 中的插件:创建与使用
  • ffmpeg实现视频的合成与分割
  • 特征融合魔改,看这一篇就够了
  • Microsoft Edge 五个神级插件
  • vue 中属性值上变量和字符串怎么拼接
  • layui table中的checkbox禁用问题
  • Vue3.0组合式API:使用ref获取DOM元素
  • 中国电子学会202403青少年软件编程(Python)等级考试试卷(二级)真题
  • 数据库———事务及bug的解决
  • SpringCloud~
  • idea 恢复 pom 文件呈现灰色并带删除线
  • 【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)