[转]关于WM_NCHITTEST消息

http://www.cnblogs.com/GnagWang/archive/2010/09/12/1824394.html

我为了移动一个无标题栏的窗体,使用了WM_NCHITTEST消息,这个消息大概如下:

通常,我们拖动对话框窗口的标题栏来移动窗口,但有时候,我们想通过鼠标在客户区上拖动来移动窗口。

一个容易想到的方案是,处理鼠标消息WM_LBUTTONDOWN和WM_LBUTTONUP。在OnLButtonUp函数中计算鼠标位置的变化,调用MoveWindow实现窗口的移动。

注意,拖动标题栏移动窗口的时候,会出现一个矩形框,它提示了窗口移动的当前位置。当鼠标左键放开的时候,窗口就移动到矩形框所在位置。而我们的实现方案中没有这个功能。

要实现此功能,我们必须自己来画这些矩形。

事实上,我们没有必要自己来做这件事情,因为Windows已经给我们做好了。

试想,如果我能够欺骗Windows,告诉它现在鼠标正在拖动的是标题栏而不是客户区,那么窗口移动操作就由Windows来代劳了。

要欺骗Windows并不像想像中的困难,甚至非常简单。

我们利用一个消息:WM_NCHITTEST。

MSDN对它的解释是:

The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse.

这个消息是当鼠标移动或者有鼠标键按下时候发出的。

Windows用这个消息来做什么? “HITTEST”就是“命中测试”的意思,WM_NCHITTEST消息用来获取鼠标当前命中的位置。

WM_NCHITTEST的消息响应函数会根据鼠标当前的坐标来判断鼠标命中了窗口的哪个部位,消息响应函数的返回值指出了部位,例如它可能会返回HTCAPTION,或者HTCLIENT等。(其返回值有很多,请查阅MSDN)。

为了便于理解,我先描述一下Windows对鼠标键按下的响应流程:

1. 确定鼠标键点击的是哪个窗口。Windows会用表记录当前屏幕上各个窗口的区域坐标,当鼠标驱动程序通知Windows鼠标键按下了,Windows根据鼠标的坐标确定它点击的是哪个窗口。

2. 确定鼠标键点击的是窗口的哪个部位。Windows会向鼠标键点击的窗口发送WM_NCHITTEST消息,来询问鼠标键点击的是窗口的哪个部位。(WM_NCHITTEST的消息响应函数的返回值会通知Windows)。通常来说,WM_NCHITTEST消息是系统来处理的,用户一般不会主动去处理它(也就是说,WM_NCHITTEST的消息响应函数通常采用的是Windows默认的处理函数)。

3. 根据鼠标键点击的部位给窗口发送相应的消息。例如:如果WM_NCHITTEST的消息响应函数的返回值是HTCLIENT,表示鼠标点击的是客户区,则Windows会向窗口发送WM_LBUTTONDOWN消息;如果WM_NCHITTEST的消息响应函数的返回值不是HTCLIENT(可能是HTCAPTION、HTCLOSE、HTMAXBUTTON等),即鼠标点击的是非客户区,Windows就会向窗口发送WM_NCLBUTTONDOWN消息。

我们有必要详细讨论一下:如果WM_NCHITTEST的消息响应函数的返回值是HTCAPTION,即指示了鼠标点击了标题栏,接下去Windows的处理是怎样的?

上面已经提到,接下来,Windows会向窗口发送WM_NCLBUTTONDOWN消息。

MSDN对WM_NCLBUTTONDOWN消息描述如下:

WM_NCLBUTTONDOWN

nHittest = (INT) wParam; // hit-test value

pts = MAKEPOINTS(lParam); // position of cursor

WM_NCLBUTTONDOWN的wParam指示了鼠标点击的窗口部位,lParam指示了当前鼠标的坐标。

如果应用程序没有对该消息响应,则由系统默认处理。

系统默认处理又是怎样的呢?系统发现wParam指示了鼠标点击的是标题栏,就会标识当前窗口处于“拖拽状态”(Windows内部记录了每个窗口的状态信息)。由于标识了“拖拽状态”,则从此刻起到鼠标键放开之前,你的鼠标移动状况完全由Windows跟踪。它根据鼠标的移动,使得窗口作“同步”移动。

注意,这个过程中,窗口不会收到WM_NCMOUSEMOVE消息,因为窗口和鼠标是“同步”移动的,你的鼠标相对于窗口是静止的。

 

但问题同时也出现了, 我想在右键这个窗体的时候弹出一个菜单, 当我完成 MSG_WM_RBUTTONDOWN 这个消息的时候,发现窗体收不到这个消息, 将WM_NCHITTEST消息的实现去掉就可以了,看了一原因是:

因为你在WM_NCHITTEST中处理了鼠标消息,把他定位成HTCAPTION,也就是鼠标在标题栏上,而标题栏属于非客户区(NC);
非客户区的事件消息都是以WM_NC开头的。也就是说,当你的WM_NCHITTEST返回HTCAPTION时,原来可以用WM_LBUTTONUP处理的消息,你只能用WM_NCLBUTTONUP来处理。

 

解决方法:

同时处理WM_NCHITTEST和WM_NCRBUTTONUP,而不处理WM_RBUTTONUP

转载于:https://www.cnblogs.com/sky1991/p/3264264.html

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

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

相关文章

LeetCode228场周赛解题报告

LeetCode228场周赛解题报告 生成交替二进制字符串的最少操作数 原题链接 https://leetcode-cn.com/contest/weekly-contest-228/problems/minimum-changes-to-make-alternating-binary-string/ 解题思路 直接进行暴力的将二进制字符串枚举,首个字符是0&#xf…

表现形式CSS

CSS(Cascading StyleSheets的缩写),翻译为“层叠样式表”或者“级联样式表”,简称样式表 Cascading StyleSheets 的首字母缩写,意思是层叠样式表。有了CSS,html中大部分表现样式的标签就废弃不用了&#x…

LeetCode 第 206 场周赛(733/4491,前16.3%)

文章目录1. 比赛结果2. 题目1. LeetCode 5511. 二进制矩阵中的特殊位置 easy2. LeetCode 5512. 统计不开心的朋友 medium3. LeetCode 5513. 连接所有点的最小费用 medium4. LeetCode 5514. 检查字符串是否可以通过排序子字符串得到另一个字符串 hard1. 比赛结果 做出来3题。继…

lightoj 1026 无向图 求桥

题目链接&#xff1a;http://lightoj.com/volume_showproblem.php?problem1026 #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace …

python基础知识点小结(2021/2/9)

python基础知识点小结(2021/2/9)持续更新中~~ 入门小知识 cmd 在cmd上进行python&#xff0c;直接输入 python\quad pythonpython退出cmd输入 exit()\quad exit()exit()到指定文件夹上运行python文件 python路径文件名.py\quad python 路径文件名.pypython路径文件名.py pyt…

CSS_属性入门

width设置元素(标签)的宽度&#xff0c;如&#xff1a;width:100px; height设置元素(标签)的高度&#xff0c;如&#xff1a;height:200px; background设置元素背景色或者背景图片&#xff0c;如&#xff1a;background:gold; 设置元素背景色为金色 画图演示 边框内边距,外边…

03.结构化机器学习项目 W1.机器学习策略(1)

文章目录1. 机器学习策略2. 正交化 Orthogonalization3. 单一数字评估指标4. 满足和优化指标5. 训练/开发/测试集划分6. 开发集和测试集的大小7. 什么时候该改变开发/测试集和指标8. 人类的表现水准9. 可避免偏差10. 理解人的表现11. 超过人的表现12. 改善你的模型的表现测试题…

CSS—常用选择器

选择器是指通过一定的语法规则选取到对应的HTML标记&#xff0c;然后给这个对应的HTML标记设置样式 1.标签选择器 写法:标签名{属性:值;属性:值} 标签选择器影响范围大&#xff0c;一般用来做一些通用设置&#xff0c;或用在层级选择器中。 举例&#xff1a; div{color:red}…

Educational Codeforces Round 104 (Rated for Div. 2)A~E解题报告

Educational Codeforces Round 104 (Rated for Div. 2) A. Arena \quad原题链接 http://codeforces.com/contest/1487/problem/A \quad解题思路 首先&#xff0c;我们看战斗次数是无限的&#xff0c;任意非最小值的英雄都有赢得次数&#xff0c;既然有场次可以赢&#xff0…

LeetCode 1130. 叶值的最小代价生成树(区间DP/单调栈贪心)

文章目录1. 题目2. 解题2.1 DP2.2 单调栈贪心1. 题目 给你一个正整数数组 arr&#xff0c;考虑所有满足以下条件的二叉树&#xff1a; 每个节点都有 0 个或是 2 个子节点。数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。&#xff08;知识回顾&#xff1a;如果一个…

CSS属性提升

CSS样式 属性提高 text-align设置文字水平对齐方式&#xff0c;如text-align:center 设置文字水平居中 text-indent设置文字首行缩进&#xff0c;如&#xff1a;text-indent:24px; 设置文字首行缩进24px font-style设置字体是否倾斜&#xff0c;如&#xff1a;font-style:no…

03.结构化机器学习项目 W2.机器学习策略(2)

文章目录1. 进行误差分析2. 清除标注错误的数据3. 快速搭建你的第一个系统&#xff0c;并进行迭代4. 使用来自不同分布的数据&#xff0c;进行训练和测试5. 数据分布不匹配时&#xff0c;偏差与方差的分析6. 定位数据不匹配问题7. 迁移学习 Transfer learning8. 多任务学习 Mul…

属性和索引器的使用

索引器允许您按照处理数组的方式索引类、结构或接口。参数相当于中介。 http://msdn.microsoft.com/zh-cn/library/2549tw02(vvs.80).aspx 转载于:https://www.cnblogs.com/iammackong/p/3268187.html

列表与表单

有序标签orderlist - 基本用法 - -<ol> - <li>列表内容</li> - <li>列表内容</li> - ..... - </ol> - 快速构建表格的快捷键 ol>(li>a)*4 无序标签 unorderlist -->经常使用 -<ul> …

Codeforces Round #702 (Div. 3)解题报告

Codeforces Round #702 (Div. 3) 全部题解 读错题意&#xff0c;写了半天真是心态爆炸&#xff0c;总的来看这次题目不难的。 A. Dense Array http://codeforces.com/contest/1490/problem/A 解题思路 相邻的数字必然是倘若不满足的话是需要插入数据的&#xff0c;那么我们…

LeetCode 930. 和相同的二元子数组(哈希+前缀和)

文章目录1. 题目2. 解题1. 题目 在由若干 0 和 1 组成的数组 A 中&#xff0c;有多少个和为 S 的非空子数组。 示例&#xff1a; 输入&#xff1a;A [1,0,1,0,1], S 2 输出&#xff1a;4 解释&#xff1a; 如下面黑体所示&#xff0c;有 4 个满足题目要求的子数组&#xff…

poj 3469(网络流模版)

题目链接&#xff1a;http://poj.org/problem?id3469 思路&#xff1a;终于把网络流的模版测试好了&#xff0c;在Dinic和Sap之间还是选择了Sap,事实证明Sap确实比Dinic效率高&#xff0c;在此贴出自己的网络流模版&#xff1a; 1 #include<iostream>2 #include<cstd…

盒子的真实宽高

盒子的宽 两边border 两边padding 盒子的高度 上下border 上下padding

leetcode第 46 场双周赛

题目A https://leetcode-cn.com/problems/longest-nice-substring/ 因为 length≤100length \leq 100length≤100&#xff0c;我们直接就可以遍历子串然后更新答案。 class Solution { public:bool Check(string s){unordered_set<int> m;for (auto u : s)m.insert(u);…

margin相关技巧

1、设置元素水平居中; margin:0 auto; margin负值让元素位移及合并边框 外边距合并&#xff1a; 外边距合并指的是:当两个垂直外边距相遇时,他们将行程一个外边距.合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者:一个格子距下30px,下面的格子距上100px,边距…