《Windows API每日一练》6.3 非客户区鼠标消息
上一节我们讨论客户区的鼠标消息,本节我们讨论非客户区鼠标消息。如果鼠标位于窗口内部除客户区外的其他区域,Windows就会向窗口过程发送一个“非客户区”鼠标消息。窗口的非客户区包括标题栏、菜单和窗口滚动条。
本节必须掌握的知识点:
非客户区鼠标消息
6.3.1 非客户区鼠标消息
非客户区鼠标消息是指在 Windows 操作系统中,当鼠标位于窗口的非客户区域时发送的鼠标相关的消息。非客户区指的是窗口周围的边框和标题栏等区域,与窗口的客户区(即窗口内部可显示内容的区域)相对。
■以下是一些常见的非客户区鼠标消息:
| 事件 | 消息 |
| 鼠标经过 | WM_NCMOUSEMOVE |
| 击中测试 | WM_NCHITTEST |
| 左键 | WM_NCLBUTTONDOWN、WM_NCLBUTTONUP、 WM_NCLBUTTONDBLCLK(双击) |
| 中键 | WM_NCMBUTTONDOWN、WM_NCMBUTTONUP、 WM_NCMBUTTONDBLCLK(第二次按下) |
| 右键 | WM_NCRBUTTONDOWN、WM_NCRBUTTONUP、WM_NCRBUTTONDBLCLK |
●WM_NCHITTEST:在鼠标移动时通知应用程序进行命中测试,以确定鼠标在非客户区的哪个位置。这个消息用于确定鼠标是否位于窗口的边框、标题栏、大小调整框等位置。
●WM_NCLBUTTONDOWN:通知应用程序鼠标左键在非客户区按下。这个消息用于响应用户在非客户区按下鼠标左键的操作。
●WM_NCLBUTTONUP:通知应用程序鼠标左键在非客户区释放。这个消息用于响应用户释放非客户区鼠标左键的操作。
●WM_NCLBUTTONDBLCLK:通知应用程序在非客户区(窗口边框和标题栏等区域)接收到鼠标左键双击事件。这个消息来响应非客户区的鼠标左键双击事件。
●WM_NCMBUTTONDOWN:通知应用程序在非客户区(窗口边框和标题栏等区域)接收到鼠标中键(鼠标滚轮按钮)按下事件。这个消息来响应非客户区的鼠标中键按下事件。
●WM_NCMBUTTONUP:通知应用程序在非客户区(窗口边框和标题栏等区域)接收到鼠标中键(鼠标滚轮按钮)释放事件。这个消息来响应非客户区的鼠标中键释放事件。
●WM_NCMBUTTONDBLCLK:通知应用程序在非客户区(窗口边框和标题栏等区域)接收到鼠标中键(鼠标滚轮按钮)双击事件。这个消息来响应非客户区的鼠标中键双击事件。
●WM_NCRBUTTONDOWN:通知应用程序鼠标右键在非客户区按下。这个消息用于响应用户在非客户区按下鼠标右键的操作。
●WM_NCRBUTTONUP:通知应用程序鼠标右键在非客户区释放。这个消息用于响应用户释放非客户区鼠标右键的操作。
●WM_NCRBUTTONDBLCLK:通知应用程序在非客户区(窗口边框和标题栏等区域)接收到鼠标右键双击事件。这个消息来响应非客户区的鼠标右键双击事件。
这些消息提供了与非客户区鼠标交互相关的信息,应用程序可以根据这些消息来处理非客户区的鼠标事件。通过捕获和处理这些消息,应用程序可以实现自定义的非客户区行为,如拖动窗口、改变窗口大小、自定义标题栏按钮等。
■参数 wParam和参数IParam
非客户区鼠标消息的参数wParam和IParam与客户区鼠标消息的参数有些不同。
| wParam(窗口的哪个部位) (20多个位置,见MSDN) | lParam(鼠标屏幕坐标) |
| HTCLINET 客户区 HTNOWHERE 不在任何窗口 HTRANSPARENT 被另一个窗口覆盖 HTERROR 使函数DefWindowProc产生警示声 …… | Pt.x =LOWORD(lParam); Pt.y =HIWORD(lParam); //屏幕坐标与客户区坐标转换 ScreenToClient(hwnd,&pt); ClientToScreen(hwnd,&pt); |
●参数 wParam表示非客户区鼠标移动或单击的位置。它的值被设定成一个以HT为首的标识符, 其中HT表示“击中测试”(hit-test)。这些标识符都定义在WINUSER.H头文件中。
●参数IParam的低位字包含x坐标,高位字包含y坐标。但是,这些坐标都是屏幕坐标, 而不是前面客户区鼠标消息中的客户区坐标。对屏幕坐标来说,显示区域左上角的x和y 都是0。向右表示x值增加的方向,而沿屏幕向下表示y值增加的方向。
利用下面两个Windows函数,可以将屏幕坐标与客户区坐标相互转换:
ScreenToClient (hwnd, &pt);
ClientToScreen (hwnd, &pt);
其中pt是一个POINT结构。这两个函数转换POINT结构中保存的坐标值,且不保留过去的值。
【注意】如果一个屏幕坐标点位于窗口客户区的上方或者左方,那么转换成客户区坐标 后,x值或y值会是负数。
■击中测试消息
WM_NCHITTEST消息表示“非客户区击中测试”(nonclient hit test)。这个消息的优先级高于其他所有的客户区和非客户区鼠标消息。参数IParam包含鼠标位置的屏幕坐标x和y。 参数wParam没有用到。
Windows应用程序通常会把这个消息发送给DefWindowProc。然后Windows会利用 WM_NCHITTEST消息来产生所有其他和鼠标位置相关的鼠标消息。对非客户区消息来说, DefWindowProc处理WM_NCHITTEST消息后返回一个可用于鼠标消息参数wParam的值。 这个返回值可以是任何一个非客户区鼠标消息的wParam参数的值,也可以是如下所示的一些值:
HTCLIENT 客户区
HTNOWHERE 不在任何窗口
HTTRANSPARENT 被另一个窗口覆盖的窗口
HTERROR 使函数DefWindowProc产生一个警示声
如果 DefWindowProc 在处理 WM_NCHITTEST 消息之后返回 HTCLIENT,则 Windows 会将屏幕坐标转换成客户区坐标,并产生一个客户区鼠标消息。
你可能记得如何利用捕捉WM_SYSKEYDOWN消息,使所有的系统键盘函数失效。 也许你会想,可不可以利用捕捉鼠标消息来实现类似的功能呢?当然可以!如果在窗口过程中包含下面几行语句:
case WM_NCHITTEST:
return (LRESULT) HTNOWHERE ;
那么程序就能够有效地阻止系统向窗口发送所有客户区和非客户区鼠标消息。此时,无论 鼠标位于窗口的任何位置,包括系统菜单、图标、调整大小按钮和关闭按钮,鼠标按钮操作都将失效。(参见第35练实例CONNECT.C。)
■消息引发消息
Windows利用WM_NCHITTEST消息来产生其他所有的鼠标消息。这种消息引发消息的思想在Windows中很常见。举一个例子来说,双击Windows程序的系统菜单图标可以关闭这个窗口。双击产生了一系列WM_NCHITTEST消息。鼠标位于系统菜单图标之上,所以DefWindowProc返回HTSYSMENU,这时Windows在消息队列中添加了一个 WM_NCLBUTTONDBLCLIK 消息,其中参数 wParam 等于 HTSYSMENU。
窗口过程一般将这个消息发送给DefWindowProc。当DefWindowProc接收到参数 wParam为HTSYSMENU的WM_NCLBUTTONDBLCLK消息时,系统会在消息队列中添加一个WM_SYSCOMMAND消息,其中参数wParam等于SC_CLOSE。(当用户选择系统菜单中的关闭按钮时,也产生WM_SYSCOMMAND消息。然后,通常窗口过程再将这个消息发送给DefWindowProc。DefWindowProc处理这个消息,并向窗口发送WM_CLOSE 消息。
如果想在结束程序之前等待用户的确认,窗口过程可以捕捉WM_CLOSE消息。否则, DefWindowProc会调用DestroyWindow函数来处理WM_CLOSE消息。除了其他处理, DestroyWindow还会向窗口过程发送一个WM_DESTROY消息。在正常情况下,窗口过程处理WM_DESTROY消息的代码如下:
case WM_DESTROY:
PostQuitMessage (0);
return 0;
PostQuitMessage函数使Windows在消息队列中添加一个WM_QUIT消息。窗口过程不会接收到这个消息,因为它会导致GetMessage函数返回0,从而结束了消息循环.整个程序也就退出了。
相关文章:
《Windows API每日一练》6.3 非客户区鼠标消息
上一节我们讨论客户区的鼠标消息,本节我们讨论非客户区鼠标消息。如果鼠标位于窗口内部除客户区外的其他区域,Windows就会向窗口过程发送一个“非客户区”鼠标消息。窗口的非客户区包括标题栏、菜单和窗口滚动条。 本节必须掌握的知识点: 非…...
Http客户端-Feign 学习笔记
作者介绍:计算机专业研究生,现企业打工人,从事Java全栈开发 主要内容:技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流(SCI论文两篇) 上点关注下点赞 生活越过…...
【Linux】进程信号_2
文章目录 八、进程信号1. 信号 未完待续 八、进程信号 1. 信号 除了可以使用 kill 命令和键盘来生成信号,我们也可以使用系统调用来生成信号。 kill函数可以对指定进程发送指定信号。 使用方法: int main(int argc, char *argv[]) {if (argc ! 3) {c…...
关于五度圈
五度圈简介 五度圈(Circle of Fifths)是一个展示各个调之间关系的图表。顺时针方向,每个调比前一个调高五度。逆时针方向,每个调比前一个调低五度。五度圈不仅展示了调性之间的关系,还能帮助你理解和记忆音符之间的关…...
电脑突然提示dll文件丢失,怎么选择正确的恢复方法?
电脑突然提示dll文件丢失?其实当你的电脑使用久了,出现这种dll文件丢失是非常的正常的,毕竟你总会有不恰当的操作吧?这些操作都是会导致dll文件丢失的。丢失了,我们直接进行相关的修复就好了,还是比较简单的…...
HTML(12)——背景属性
目录 背景属性 背景图 背景图平铺方式 背景图位置 背景图缩放 背景图固定 背景属性 属性描述background-color背景色background-image (bgi)背景图background-repeat (bgr)背景图平铺方式background-position (bgp)背景图位置background-size (bgz)背景图缩放backgro…...
C语言 指针——从函数返回字符串
目录 从函数返回字符指针 编程实现strcat()的功能 小结 从函数返回字符指针 编程实现strcat()的功能 小结 明确字符串被保存到了哪里,明确字符指针指向了哪里 指向字符串常量的字符指针 指向字符数组的字符指针 向函数传递字符串的方法 向函数传…...
java:aocache:基于aspectJ实现的方法缓存工具
背景 最近一直在做一些服务端的设计,经常遇到常量计算的问题,比如获取查找一个类的所有方法,获取有指定注解(Annnotation)的方法并查找注解的上特定的元注解是否有特定的值 。。。。总之逻辑很复杂,而且会频繁调用。 比如在服务端…...
UE4_材质_湿度着色器及Desaturation算法_ben材质教程
学习笔记,不喜勿喷!侵权立删,祝愿美好生活越来越好。 效果图: 原图: 1、使用初学者内容包的材质 我们这里使用虚幻自带的材质M_Brick_Clay_Old,复制一个更名为M_Brickclayoldwet材质。 2、添加去饱和度Desaturation节…...
AI问答-ERP:理解 ERP / 我国ERP发展现状 / ERP软件有哪些 / 华为自研ERP
一、理解ERP 1.1、定义 ERP(Enterprise Resource Planning)是企业资源计划的缩写,它集成了企业各个业务领域,包括采购、销售、库存、生产制造、财务等多个方面,进行全面管理、智能决策的一种企业管理系统。 1.2、功…...
C语言 | Leetcode C++题解之第199题二叉树的右视图
题目: 题解: #define MAX_NODE_NUM 100 int* rightSideView(struct TreeNode* root, int* returnSize){if (root NULL) {*returnSize 0;return NULL;}int *res (int *)malloc(sizeof(int) * MAX_NODE_NUM);int cnt 0;struct TreeNode **record (st…...
java:aocache的单实例缓存
上一篇博客《java:aocache:基于aspectJ实现的方法缓存工具》介绍了aocache的基本使用, 介绍AoCacheable注解时说过,AoCacheable可以定义在构造方法上,定义在构造方法,该构建方法就成了单实例模式。 也就是说,只要构建…...
c++11 abi 兼容性
理解 _GLIBCXX_USE_CXX11_ABI: 兼容性与现代化之间的平衡 随着 C 标准的不断演进,编译器和标准库实现也在不断更新,以支持新的语言特性和库功能。然而,这些更新有时会引入不兼容的更改,特别是应用程序二进制接口(ABI&…...
获取个人免费版Ubuntu Pro
首先上官网地址:Ubuntu Pro | Ubuntu 点击页面中的"Get Ubuntu Pro now" 将用途选为“Myself”,在此页面中Ubuntu说明了该版本只面向个人开发者,且最终只允许5台设备免费使用;因而部署设备的抉择就不得不慎重考虑了&am…...
Pinia的基本用法
Pinia的安装和引入 1.安装Pinia npm install pinia2. 在vue项目的main.js文件中引入pinia import { createApp } from vue import { createPinia } from pinia import App from ./App.vueconst pinia createPinia() const app createApp(App)app.use(pinia) app.mount(#ap…...
正版软件 | DeskScapes:将您的桌面变成生动的画布
您是否厌倦了静态的桌面背景?Stardock 的 DeskScapes 软件赋予您将任何图片或视频动画化的能力,让您的 Windows 桌面焕发活力。 动画桌面,艺术生活 使用 DeskScapes 您可以将任何静态图片或视频转化为桌面背景。不仅如此,通过 60 …...
OpenCV cv::Mat到 Eigen 的正确转换——cv2eigen
在进行计算机视觉项目时,我们经常需要处理相机位姿的变换。最近,我在项目中遇到了一个看似简单但实际上颇具挑战性的问题:从 OpenCV 的 cv::Mat 格式转换到 Eigen 库的格式。这个过程中遇到了一些问题,但最终找到了一个稳健的解决…...
PostgreSQL的扩展(extensions)-常用的扩展-pg_pathman
PostgreSQL的扩展(extensions)-常用的扩展-pg_pathman pg_pathman 是一个用于 PostgreSQL 的分区管理扩展。它提供了一种高效的方式来管理和使用数据库分区,可以显著提升查询性能,特别是在处理大规模数据集时。 安装 pg_pathman…...
数据结构之树
基础知识: 树是一种非线性结构,其严格的数学定义是:如果一组数据中除了第一个节点(第一个节点称为根节点,没有直接前驱节点)之外,其余任意节点有且仅有一个直接前驱,有零个或多个直接…...
6毛钱SOT-23封装28V、400mA 开关升压转换器,LCD偏置电源和白光LED应用芯片TPS61040
SOT-23-5 封装 TPS61040 丝印PHOI 1 特性 • 1.8V 至 6V 输入电压范围 • 可调节输出电压范围高达 28V • 400mA (TPS61040) 和 250mA (TPS61041) 内部开关电流 • 高达 1MHz 的开关频率 • 28μA 典型空载静态电流 • 1A 典型关断电流 • 内部软启动 • 采用 SOT23-5、TSOT23…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
