翻译《The Old New Thing》- What’s with this MSH_MOUSEWHEEL message?

news2024/11/22 19:02:21

What's with this MSH_MOUSEWHEEL message? - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20080806-00/?p=21353

Raymond Chen 2008年06月06日


MSH_MOUSEWHEEL 消息是怎么回事?

        硬件团队正在研发一种鼠标滚轮设备,并需要一种方法让应用程序支持这种鼠标。一种方法是说:“我们将开始销售这种带滚轮的鼠标,但在下一代Windows发布之前,没有任何应用程序可以使用它。”当然,这意味着要等到Windows NT 4发布,而谁也不知道那会是什么时候。此外,这意味着人们必须升级Windows才能利用他们的新鼠标。可以想象,他们对“等几年”的计划并不满意。

        在此期间,他们为应用程序响应鼠标滚轮提出了一种临时机制。于是引入了zmouse.h头文件及其注册消息MSH_MOUSEWHEEL。当你安装滚轮鼠标驱动程序时,它会监听硬件的滚轮事件,并在鼠标滚轮转动时发布这个新消息,应用程序只需响应WM_MOUSEWHEEL消息(如果运行在支持该消息的Windows版本上)或MSH_MOUSEWHEEL消息(如果运行在不支持该消息的旧版Windows上)。不幸的是,这两个消息的行为不同,所以不是简单地编写:

if (uMsg == WM_MOUSEWHEEL || uMsg == g_msgWheel) {
  // 处理滚轮事件
}

(下面几段总结了MSDN中已经明确的内容;如果已经知道这些消息的工作原理,可以跳过。)

        首先,让我们看看WM_MOUSEWHEEL。这个消息被传递到拥有焦点的窗口(在SetFocus的意义上)。如果窗口过程不处理这个消息,只是将其传递给DefWindowProc函数,那么DefWindowProc函数会将这个消息转发给窗口的父窗口。通过这种方式,WM_MOUSEWHEEL消息自动地从焦点窗口“向外冒泡”到父窗口链,直到有人最终处理这个消息(或者根本没有被处理)。

        另一方面,MSH_MOUSEWHEEL消息从外部向内部工作。它被传递到前景窗口(在SetForegroundWindow的意义上)。如果窗口过程不想处理这个消息,它可以将消息转发给它选择的子窗口,直到其中一个返回TRUE表示消息已被处理,或者直到没有更多的候选者。

        我将以表格形式总结这些差异,因为人们似乎非常喜欢表格。

WM_MOUSEWHEELMSH_MOUSEWHEEL
传播方向内向外外向内
传播机制DefWindowProcSendMessage
处理自动手动:应用程序检查从子窗口返回的值以确定接下来要做什么
如果已处理的返回值TRUE
如果未处理的返回值DefWindowProcFALSE

        注意WM_MOUSEWHEEL更简单,内向外的传播机制保留了其他消息(如WM_CONTEXTMENUWM_SETCURSOR)的精神。

        为什么MSH_MOUSEWHEEL不能以相同的方式进行?

        首先,MSH_MOUSEWHEEL没有修改DefWindowProc函数的特权。毕竟,引入这个消息的整个目的,是因为我们正试图向一个早于鼠标滚轮的旧操作系统添加滚轮支持。换句话说,如果我们能修改DefWindowProc来处理MSH_MOUSEWHEEL消息,那么我们一开始就不需要MSH_MOUSEWHEEL消息;我们只需要修改DefWindowProc来处理WM_MOUSEWHEEL消息。

        前一段中的论点是一个令人沮丧的常见问题。面对问题X和变通方法Y,有人会问:“为什么不用方法Z?”然而,如果你看看方法Z,你会发现它受到与问题X完全相同的问题。

这里有一个“困惑的变通方法”的真实世界例子:

“由于I-90桥关闭了,我不能乘坐550公交车从贝尔维尤到安全球场。相反,我将乘坐230到雷德蒙德,然后换乘545。”

——嗯,那很傻。为什么不乘坐245到东门,然后换乘554呢?这样更快。

“嗯,554也使用I-90桥。”

        好的,所以你不能更改DefWindowProc,但为什么不至少从内向外传播MSH_MOUSEWHEEL而不是从外向内呢?

        从焦点窗口开始的假设是你可以找出焦点窗口是什么,但如果你注意到了《每个Win32程序员都应该知道的五件事》,你就会知道每个线程都有自己的焦点窗口。(不是吹毛求疵的真,但足够真。)因此,当注入MSH_MOUSEWHEEL消息的帮助程序调用GetFocus时,它只会得到自己的焦点窗口,而不是控制前景窗口的线程的焦点窗口。(记住,我们谈论的是1996年,远在GetGUIThreadInfo函数发明之前。历史爱好者可以更多地了解鼠标滚轮的发明者。)由于内部向外是不可能的,这基本上就迫使了外部向内部。

        现在你知道鼠标滚轮消息是如何工作的,你可以解释这位客户看到的行为:

我注意到WM_MOUSEWHEEL消息被传递到了错误的子窗口。 我有一个父窗口和两个子窗口。 即使我把鼠标指针移动到子窗口1上, WM_MOUSEWHEEL却发送到了子窗口2。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1794660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LlamaIndex 一 简单文档查询

前言 在学习LangChain的时候,我接触到了LlamaIndex。它犹如我在开发vue时用到的axios,主要负责数据打理。别问我为什么打这个比方,前端老狗,重走AI路,闭关一年能否学的妥当? LlamaIndex 是一个用于 LLM 应…

【Python】教你彻底认识Python中的Web开发

​​​​ 文章目录 一、Web开发的基本概念1. Web服务器2. 客户端-服务器模型3. HTTP协议4. 前端与后端 二、常用的Web开发框架1. Django1.1 安装Django1.2 创建Django项目1.3 定义模型1.4 定义视图1.5 定义URL路由1.6 模板 2. Flask2.1 安装Flask2.2 创建Flask应用2.3 模板2.4…

Day 41 NGINX详解

Nginx详解 一、HTTP协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 1、HTTP 工作原理 HTTP协议通信流程 WEB Server&…

队列的实现及其应用

队列的概念 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作,具有先进先出的效果。入数据的一段称为队尾,出数据的一段称为队头。队列的应用是:1.维持公平性(抽号)、2.广度优先遍历…

JVM垃圾收集器和性能调优

目标: 1.JVM垃圾收集器有哪几种? 2.CMS垃圾收集器回收步骤。 一、JVM常见的垃圾回收器 为什么垃圾回收的时候需要STW? 标记垃圾的时候,如果不STW,可能用户线程就会不停的产生垃圾。 1.1 单线程收集 Serial和SerialOld使用单…

大语言模型应用与传统程序的不同

大语言模型(LLM) 被描述的神乎其神,无所不能,其实,大语言模型只是一个模型,它能够理解和生成自然语言,唯有依靠应用程序才能够发挥作用。例如,基于大模型可以构建一个最简单的会话机…

黑马python-JavaScript

1.JavaScript的定义&#xff1a; JavaScript是运行在浏览器端的脚步语言&#xff0c;是由浏览器解释执行的、简称js。它能够让网页和用户有交互功能&#xff0c;增加良好的用户体验效果 2.使用方式&#xff1a; 1.行内式&#xff08;主要用于事件&#xff09; <input type&q…

24-unittest简介

一、unittest简介 unittest是Python中常用的单元测试框架&#xff0c;与Java中的Junit单元测试框架类似。 二、示例程序 1&#xff09;导入unittest模块 import unittest 2&#xff09;使用help()函数查看源码中的示例程序 help(unittest) Simple usage:import unittestc…

Unity DOTS技术(二)ECS

文章目录 一.ECS简介二.基本操作实例三.实体查看组件四.位置实体修改五.旋转实体六.了解原有属性七.禁止自动创建八.动态实例化 一.ECS简介 ECS全称 (Entity Component System).即(E:实体 C:组件 S:系统). 实际上即是数据方法分离.数据放在组件里,具体实现放在系统里.组件挂载…

【excel】设置二级可变联动菜单

文章目录 【需求】在一级菜单选定后&#xff0c;二级菜单联动显示一级菜单下的可选项【步骤】step1 制作辅助列1.列转行2.在辅助列中匹配班级成员 step2 名称管理器step3 制作二级下拉菜单step4 消除二级菜单中的空白 【总结】 之前做完了 【excel】设置可变下拉菜单&#xff…

NPDP|智造业产品经理的战略智慧与行动之道

在智能制造风起云涌的时代&#xff0c;智造业产品经理的角色愈发重要。他们不仅需要具备深厚的行业知识&#xff0c;更要拥有前瞻的战略眼光和高效的行动能力。那么&#xff0c;智造业产品经理如何进行战略思考与行动呢&#xff1f;本文将为您揭示其中的奥秘。 洞察市场趋势&am…

01_初识微服务

文章目录 一、微服务概述1.1 什么是微服务1.2 对比微服务架构与单体架构1.3 微服务设计原则1.4 微服务开发框架1.5 简单理解分布式部署与集群部署 二、微服务的核心概念2.1 服务注册与发现2.2 微服调用&#xff08;通信&#xff09;2.3 服务网关2.4 服务容错2.5 链路追踪参考链…

用友NC pagesServlet SQL注入致RCE漏洞复现(XVE-2024-13067)

0x01 产品简介 用友NC是由用友公司开发的一套面向大型企业和集团型企业的管理软件产品系列。这一系列产品基于全球最新的互联网技术、云计算技术和移动应用技术,旨在帮助企业创新管理模式、引领商业变革。 0x02 漏洞概述 用友NC /portal/pt/servlet/pagesServlet/doPost接口…

焦化超低排平台改造指南

在当今社会&#xff0c;环保已成为各行各业的共识&#xff0c;焦化行业也不例外。随着环保政策的日益严格&#xff0c;焦化超低排平台改造成为了行业内的热点话题。本文旨在为广大焦化企业提供一份全面、实用的改造指南&#xff0c;帮助企业顺利实现超低排放&#xff0c;迈向绿…

python 字符串(str)、列表(list)、元组(tuple)、字典(dict)

学习目标: 1:能够知道如何定义一个字符串; [重点] 使用双引号引起来: 变量名 "xxxx" 2:能够知道切片的语法格式; [重点] [起始: 结束] 3:掌握如何定义一个列表; [重点] 使用[ ]引起来: 变量名 [xx,xx,...] 4:能够说出4个列表相关的方法; [了解] ap…

解决在Windows11上新安装的Docker Desktop一直显示“starting the Docker Engine“登录不上去的问题

解决在Windows11上新安装的Docker Desktop一直显示“starting the Docker Engine“登录不上去的问题 管理员权限运行cmd 还需要安装wsl(适用于Linux的Windows子系统)。注意windows powershell也要以管理员权限打开 这个是小羊用错窗口了&#xff0c;but好像也没错吧&#xff…

shell的编程方式

文章目录 变量俩种方式第一种方式第二种方式 取消变量数组创建数组获取数组元素的方式 read输出的方式限制输入的方式 流程控制方式for循环输出的方式第一种方式第二种方式while循环输出的方式select选择输出的方式 判断方式判断的四种方式第一种方式第二种方式第三种方式 算术…

C++之RTTI

1、RTTI&#xff08;runtime type information&#xff09;运行时类型信息 static_cast&#xff1a;用在编译器认可的转型 reinterpret_cast&#xff1a;用在编译器不认可的转型&#xff08;不做任何的对齐操作&#xff09; const_cast&#xff1a;去除常量属性 dynamic_ca…

国产开发板——香橙派Kunpeng Pro的上手初体验

开发板&#xff08;Development Board&#xff09;是一种特殊的电子产品&#xff0c;它的主要目的是为了帮助开发者快速地设计、测试和验证电子产品的硬件和软件设计。开发板通常提供了一个完整的硬件平台&#xff0c;包括微控制器、存储器、接口和其他外围设备&#xff0c;开发…

开源Mamba-2性能狂飙8倍!多个Mamba超强进化体拿下顶会

MambaOut的热度刚过去没多久&#xff0c;Mamba-2就带着它狂飙8倍的性能炸场了。 Mamba-2的核心层是对Mamba的选择性SSM的改进&#xff0c;同等性能下&#xff0c;模型更小&#xff0c;消耗更低&#xff0c;速度更快。与Mamba不同&#xff0c;新一代的Mamba-2再战顶会&#xff…