关于WM_NCHITTEST消息

news/2024/7/10 22:31:50 标签: windows, button, 测试, 2010

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

 

 

http://tech.sina.com.cn/s/2006-07-25/09051053459.shtml


http://www.niftyadmin.cn/n/1710917.html

相关文章

Pandas-------文件读写操作和处理缺失数据

一.文件读写操作 1.csv 定义:逗号分隔值有时也叫做字符分隔值,其文件以纯文本形式存储表格数据,纯文件意味着该文件是一个字符序列, 不含必须像二进制数字那样被解读的数据。csv文件常常用于保存数据,Pandas提供了对该…

springboot调用第三方接口_SpringBoot+SpringCloud面试题整理

什么是SpringBoot?1、用来简化spring初始搭建和开发过程使用特定的方式进行配置(properties或者yml文件)2、创建独立的spring引用程序main方法运行3、嵌入Tomcat无需部署war包,直接打成jar包nohup java -jar – & 启动就好4、简化了maven的配置4、自…

[转]IE Cookie文件格式说明

1、Cookie文件的实质 Cookie实际上是Web服务端与客户端(典型的是浏览器)交互时彼此传递的一部分内容,内容可以是任意的,但要在允许的长度范围之内。客户端会 将它保存在本地机器上(如IE便会保存在本地的一个txt文件中…

Json和Csv文件存储

一.Json文件存储 json,通过对象和数组的结合来表示数据,构造简洁但是结构化程度非常高,是一种轻量级的数据交换格式。一个简单的json对象 [ { name:Bob,"gender":"male","birthday":"1995-10-10"} ,…

python爬虫伪装浏览器_Python伪装浏览器爬虫读取网页内容

Python伪装浏览器爬虫读取网页内容昨天在OSC上看到有段代码,解析HTML相关的,我突然就想到了Python,用Python实现同样功能应该也不难吧,于是我开始试着用Python读取网页内容,不过过程有点纠结。声明:以下代码…

Pandas-------规整数据和分组运算

一.规整数据 1.轴向连接 默认情况下是沿0轴连接,当然也可以指定 当两个数组元素个数不同时,会用 NaN 代替 指定轴连接方向为1轴 设定多级索引 可能出出现这种情况 例如,设定的索引名相同,但不对应,连接时会如何呢…

开源中文bi_主流开源 BI 产品对比

现在市场上开源 BI 产品比较多,各个产品的侧重点不同,有的以报表为主、有的以可视化为主、有的以查询分析为主。这里我们选取了一些主流的开源 BI 产品,从产品功能、可视化能力、数据源支持以及使用文档等方面进行对比,希望对你有…

Pandas-------矢量化字符串与时间

1.矢量化字符串 对字符串的一些操作 变小写,求长度等 当然也支持索引和切片 一.时间 在Python中有对时间的描述,datatime模块,这里使用的是 pytz 1.时间的物理量 (1)地区时间的转换 当然对于时间,也是…