windows 消息循环(二)

    又查阅了些资料,发现下面这张图,能够很好的解释windows的消息循环机制。图很简单明了,就不作过多的解释了。



1、消息队列

(1)消息队列的容量有多大?

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\ 下 USERPostMessageLimit 定义了队列的最大长度,默认为10000;

(2)消息来源分为Hardware event或者是application,application一般会指定窗口或者线程发送消息,hardware event, 比如鼠标移动,键盘输入,都是由相应的设备驱动将这些event,转换成消息,放入系统消息队列。

(3)是不是所有的消息都要经过消息队列呢?

答案是,NO! 消息分为队列消息和非队列消息。队列消息需要经过消息队列,非队列消息不需要,他们直接被传入指定窗口的窗口过程进行处理。PostMessage发送的消息是队列消息,它会把消息Post到消息队列中;SendMessage发送的消息是非队列消息, 被直接送到窗口过程处理。

(4)消息队列中,大部分消息都是按照FIFO的方式进行处理,但也有例外。WM_PAINT,WM_TIMER, WM_QUIT只有在Queue中没有其他消息的时候才会被处理,WM_PAINT消息还会被合并以提高效率。

2、消息循环

(1)取消息GetMessage / PeekMessage,GetMessage属于阻塞式API。这两个API除了可以取消息,还可以对消息做一些过滤,只需要传入相应的参数就可以了。

(2)TranslateMessage 翻译消息,注意,在包含有热键和模态窗口消息的时候,还需要调用IsDialogMessage和TranslateAccelarator进行消息的翻译;

(3)DispatchMessage将控制权交给系统,系统将消息分发给对应的窗口过程。发送给窗口过程的消息不包括消息发送时间和坐标位置,如果需要的话,可以通过API函数获取;

3、窗口过程

窗口过程对所有的消息都会做处理,application可以选择自己关系的消息做一些特殊处理,其余的消息可以交给windows的默认窗口过程DefWindowProc。


经过以上了解后,对上文,gtest单元测试中遇到的问题就可以解决了。

在main()中创建一个工作线程,线程中创建一个窗口,定义窗口过程,创建消息循环。

主线程执行gtest用例,工作线程,执行相应的被测代码。

问题得到解决。


<think> 首先,用户的问题是:“我想获取windows消息循环机制的介绍 请问windows消息循环机制介绍”。用户正在寻求Windows消息循环机制的介绍。 用户提供了几个引用: - 引用[1]:描述消息循环的基本结构,包括GetMessage, TranslateMessage, DispatchMessage。 - 引用[2]:解释消息是如何生成和传递的。 - 引用[3]:详细说明消息从生成到处理的全过程。 - 引用[4]:讨论消息处理的特殊情况,比如键盘消息需要额外处理。 从系统指令看: - 所有行内数学表达式必须用$...$格式(但这里可能不需要)。 - 独立公式用$$...$$格式(同样可能不需要)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识。 结构上: - 回答应该清晰、结构化。 - 基于引用内容构建回答。 - 末尾添加相关问题。 关键点从引用中提取: - 消息循环Windows应用程序的核心,用于处理事件。 - 消息类型:鼠标点击、键盘按键等事件被翻译成消息。 - 消息生成:事件被系统捕获,存于系统消息队列。 - 消息分发:系统分析消息目标应用程序,拷贝到应用消息队列。 - 消息检索:应用程序使用消息循环(while循环)用GetMessage取出消息。 - 消息处理:TranslateMessage用于键盘消息翻译,DispatchMessage分发到窗口处理程序。 - 窗口过程:每个窗口有一个回调函数(窗口过程),处理消息;未处理的消息由默认过程处理。 - 特殊情况:如键盘消息需要TranslateMessage进行翻译。 组织回答: 1. **引言**:简要介绍Windows消息循环机制。 2. **核心概念**:什么是消息消息队列。 3. **消息处理流程**:从事件发生到消息处理。 4. **代码示例**:展示一个简单的消息循环代码(从引用[1]提供)。 5. **关键组件**:GetMessage, TranslateMessage, DispatchMessage的作用。 6. **窗口过程**:解释回调函数。 7. **特殊情况**:如TranslateMessage的必要性。 8. **总结**。 9. **相关问题**。 使用引用: - 在相关部分添加引用标识,如[^1], [^2], [^3], [^4]。 生成相关问题: - 基于主题,如优化、性能、应用场景。 确保中文回答。 </think> ### Windows消息循环机制介绍 Windows消息循环机制是操作系统中应用程序处理用户输入和系统事件的核心机制。它确保事件(如鼠标点击、键盘按键、窗口变化等)被捕获、翻译、分发和处理,从而实现应用程序的响应性。下面我将基于提供的引用内容,逐步解析这一机制。 #### 1. **基本概念** Windows系统中的所有事件(如用户操作或系统通知)都被封装为“消息”。消息本质上是一个数据结构记录,包含消息类型(例如鼠标点击对应`WM_LBUTTONDOWN`)和其他相关信息(如位置或按键值)[^2]。这些消息被组织在队列中: - **系统消息队列**:Windows监控I/O设备事件(如键盘或鼠标),捕获事件后将其翻译为消息并存储于此。 - **应用程序消息队列**:每个应用程序有自己的队列;系统分析消息目标后,将消息拷贝到相应应用的队列[^3]。 #### 2. **消息循环的核心流程** 应用程序启动后,会建立一个无限循环消息处理结构。引用[1]和[3]中的代码示例展示了标准流程: ```c while(GetMessage(&msg, NULL, 0, 0)) // 从应用程序消息队列检索消息 { TranslateMessage(&msg); // 翻译键盘消息(如转换为WM_CHAR) DispatchMessage(&msg); // 分发消息到目标窗口 } ``` - **GetMessage()函数**:从应用程序消息队列取出消息;如果队列为空,线程会等待新消息[^1][^3]。 - **TranslateMessage()函数**:针对键盘事件(如`WM_KEYDOWN`),翻译为字符消息(如`WM_CHAR`),确保按键能正确处理[^1][^4]。注意,非键盘消息可直接跳过此步。 - **DispatchMessage()函数**:将消息分发到指定的窗口处理程序(即窗口过程函数)[^1][^3]。 整个过程可总结为: 1. **事件捕获**:用户操作(如点击鼠标)被Windows捕获并存入系统队列[^2][^3]。 2. **消息分发**:系统识别目标应用,将消息复制到其应用程序消息队列[^3]。 3. **消息检索**:应用循环调用`GetMessage()`取出消息。 4. **消息处理**:键盘消息需`TranslateMessage()`翻译后重新入队,其他消息直接分发[^4]。 5. **窗口处理**:`DispatchMessage()`调用窗口过程函数处理消息[^3]。 #### 3. **窗口过程函数** 每个窗口都有一个预定义的“窗口过程函数”(callback function),由系统调用而非应用程序直接调用。开发者可以重载此函数处理特定消息: - **自定义处理**:对感兴趣的消息(如鼠标单击),应用可定义响应逻辑。 - **默认处理**:不处理的消息由系统默认窗口过程处理(如`DefWindowProc`)[^3][^4]。 这种方式保证了消息处理的灵活性和扩展性。 #### 4. **特殊处理与注意事项** - **键盘消息的翻译**:键盘事件首次到达时,`TranslateMessage()`将其翻译为具体键位消息(如`WM_CHAR`),然后消息重回队列,第次取出时才能被正确识别[^4]。这避免了消息歧义。 - **消息类型多样性**:Windows定义了数百种消息类型(例如`WM_PAINT`用于窗口绘制),处理机制需适应不同场景[^2]。 - **性能影响**:消息循环是单线程的;如果处理耗时消息(如复杂计算),可能导致应用假死,因此需优化消息处理逻辑[^1][^3]。 #### 总结 Windows消息循环机制通过队列化、翻译和分发消息,实现了事件驱动的应用程序模型。核心组件包括`GetMessage`、`TranslateMessage`和`DispatchMessage`函数,以及窗口过程回调。这一机制确保了用户交互的高效响应,是Windows GUI编程的基础[^1][^2][^3][^4]。如需深入探讨性能优化或实际应用,请参考以下相关问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值