《Windows API每日一练》6.3 非客户区鼠标消息

上一节我们讨论客户区的鼠标消息,本节我们讨论非客户区鼠标消息。如果鼠标位于窗口内部除客户区外的其他区域,Windows就会向窗口过程发送一个“非客户区”鼠标消息。窗口的非客户区包括标题栏、菜单和窗口滚动条。

本节必须掌握的知识点:

        非客户区鼠标消息

6.3.1 非客户区鼠标消息

非客户区鼠标消息是指在 Windows 操作系统中,当鼠标位于窗口的非客户区域时发送的鼠标相关的消息。非客户区指的是窗口周围的边框和标题栏等区域,与窗口的客户区(即窗口内部可显示内容的区域)相对。

以下是一些常见的非客户区鼠标消息:

事件

消息

鼠标经过

WM_NCMOUSEMOVE

击中测试

WM_NCHITTEST

左键

WM_NCLBUTTONDOWNWM_NCLBUTTONUP

WM_NCLBUTTONDBLCLK(双击)

中键

WM_NCMBUTTONDOWNWM_NCMBUTTONUP

WM_NCMBUTTONDBLCLK(第二次按下)

右键

WM_NCRBUTTONDOWNWM_NCRBUTTONUPWM_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,从而结束了消息循环.整个程序也就退出了。

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

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

相关文章

微服务和kafka

一、微服务简介 1.单体架构 分布式--微服务--云原生 传统架构(单机系统),一个项目一个工程:比如商品、订单、支付、库存、登录、注册等等,统一部署,一个进程 all in one的架构方式,把所有的…

深入探讨C++的高级反射机制(2):写个能用的反射库

在现代软件开发中,反射是一种强大的特性,它可以支持程序在运行时查询和调用对象的属性和方法。 但是在C中,没有内置的反射机制。我们可以通过一些巧妙的技术模拟反射的部分功能。 上一篇文章写了个简单的反射功能,这回完善一下&a…

Vue3实现记住密码功能

1.首先安装 js-cookie、jsencrypt npm i js-cookie // 使用Cookie来实现记住密码功能 npm i jsencrypt //使用jsencrypt进行加密解密 2.完整代码 注:在此我使用了ant-design-vue组件库 若使用源码请自行配置ant-design-vue <template><h2 :style"{margin…

3.PyQt6常用基本控件

目录 常用控件 1.文本类控件 1.QLable标签控件 1.设置标签文本 2.设置标签文本和对齐方式 3.换行显示 4.添加超链接 5.为标签设置图片 6.获取标签文本 2.QLineEdit单行文本控件 3.QTextEdit多行富文本控件 4.QPlainTextEdit纯文本控件 5.QSpinBox整数数字选择控件 …

开发板以电脑为跳板连接互联网

标题 开发板以电脑为跳板连接互联网网络共享方式桥接方式 开发板以电脑为跳板连接互联网 分享下用网线直连电脑的开发板如何以电脑为跳板连接互联网的两个方法。 网络共享方式桥接方式 补充下&#xff0c;我的电脑连接的是无线网络&#xff0c;开发板和电脑是用网线进行连接的…

【第3章】MyBatis-Plus持久层接口之Service Interface(上)

文章目录 前言一、save1. 示例&#xff08;save&#xff09;2. 示例&#xff08;saveBatch&#xff09;3. 示例&#xff08;saveBatch 指定批次大小&#xff09; 二、saveOrUpdate1.示例&#xff08;saveOrUpdate&#xff09;2.示例&#xff08;saveOrUpdateBatch&#xff09;3…

Python 高级编程:文件操作与错误处理

在前几篇文章中&#xff0c;我们介绍了Python的基本语法、函数和模块以及面向对象编程。这些知识对于大部分日常编程问题已经足够&#xff0c;但对于需要分析大数据的人来说&#xff0c;这些还不够。本章将介绍Python的文件操作以及错误处理与调试。 目录 文件操作读文件写文…

GPTs与Assistant API:哪一个更适合您?

梗概 主要讲解了OpenAI推出的两种不同的人工智能工具——GPTs和Assistant API&#xff0c;并比较了它们各自的特点和适用场景&#xff0c;帮助用户选择最适合自己需求的工具。 GPTs&#xff08;生成预训练变换模型&#xff09; 核心特点&#xff1a; 生成能力&#xff1a;GPTs…

C语言单链表的算法之插入节点

一&#xff1a;访问各个节点中的数据 &#xff08;1&#xff09;访问链表中的各个节点的有效数据&#xff0c;这个访问必须注意不能使用p、p1、p2&#xff0c;而只能使用phead &#xff08;2&#xff09;只能用头指针不能用各个节点自己的指针。因为在实际当中我们保存链表的时…

【嵌入式Linux】i.MX6ULL GPIO 中断服务函数注册与编写

文章目录 1 外部中断初始化与中断服务函数1.2 外部中断初始化函数 exti_init1.2.1 GPIO引脚配置1.2.2 中断使能与注册1.2.3 GIC_EnableIRQ()函数的分析 1.3 中断服务函数 gpio1_io20_irqhandler1.3.1 消抖处理1.3.2 中断事件处理1.3.3 清除中断标志 2 BUG处理2.1 问题描述2.2 解…

网易Filmly网盘影片播放器安卓TV版

我们在观看网盘内的影视时&#xff0c;想要高清/原画质观看视频&#xff0c;甚至倍速功能往往都需要开通网盘会员才可以&#xff0c;否则你只能使用”马赛克”画质观看。 最近网易上线了一款播放器&#xff1a;Filmly &#xff0c;它支持直连网盘影视资源&#xff0c;可以高速…

Optional避免判空嵌套过多,优雅解决空指针异常

背景 最近在处理json文件反序列化为实体类的时候&#xff0c;抛出空指针异常&#xff0c;发现很多地方没有判空逻辑。 增加判空逻辑后&#xff0c;嵌套太多导致代码很臃肿&#xff0c;因此学习用Optional来进行优化代码&#xff0c;增加可读性。 Optional使用场景 1. map自动…

深入理解计算机系统 CSAPP 家庭作业7.12

A:refptr (unsigned)(ADDR(r.symbol) r.addend - refaddr) 0x4004f8 (-4) - 0x4004ea 0xa B:refaddr 0x4004d0 0xa 0x4004da refptr 0x400500 (-4) - 0x4004da 0x22 ​​​​​​​

Python24 机器学习之决策树

1.什么是机器学习&#xff1f; 机器学习是人工智能&#xff08;AI&#xff09;的一个分支&#xff0c;它使计算机系统能够从经验中学习并根据这些学习的数据做出决策或预测&#xff0c;而无需进行明确的编程。简而言之&#xff0c;机器学习涉及算法和统计模型的使用&#xff0…

Hugo Barra对Apple Vision Pro 硬件和软件的详细评述

原文&#xff1a;hugo.blog/2024/03/11/vision-pro 这篇文章的作者是Hugo Barra。Hugo Barra曾是Meta公司&#xff08;前身为Facebook&#xff09;旗下Oculus VR/AR团队的负责人。他在2017年至2020年期间领导了Oculus的团队&#xff0c;参与了多个VR头显的开发和发布。Hugo Bar…

使用提示词调教AI

“AI 是我们的数字员工&#xff0c;了解员工的秉性 &#xff0c; 从调教提示词开始。” 网上流传最广的提示词方法论&#xff0c;是“你需要给大模型一个角色”。这确实是一个好的策略&#xff0c;因为小学老师&#xff0c;大学老师这样的角色&#xff0c;预设很多背景信息。这…

【数学建模】 函数极值与规划模型

文章目录 函数极值与规划模型1. 线性代数和线性规划的联系1.1 线性代数的基本概念1.2 线性规划的基本概念1.3 线性代数与线性规划的联系矩阵和向量线性方程组单纯形法内点法凸优化 1.4 例子 2. Numpy有关矩阵运算示例2.1 矩阵的创建2.2 矩阵的基本运算2.3 矩阵的合并2.4 矩阵的…

如何在Java中实现WebSocket?

如何在Java中实现WebSocket&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Java中实现WebSocket&#xff0c;WebSocket是一种…

个人对JavaScript面向对象的见解

引言 在当今的软件开发领域&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种非常流行的编程范式。它通过将现实世界中的对象模型化&#xff0c;使得软件开发更加接近人类看待世界的方式。面向对象编程提供了一种组织代…

Linux系统之nice命令的基本使用

Linux系统之nice命令的基本使用 一、nice命令介绍1.1 nice命令简介1.2 进程优先级介绍 二、nice命令基本语法2.1 nice命令的help帮助信息2.2 nice命令选项解释 三、nice命令的基本使用3.1 查看进程优先级3.2 使用nice启动进程3.3 提高优先级 四、注意事项 一、nice命令介绍 1.…