用WM_NCHITTEST消息欺骗Windows(一)
2007-02-02 14:26

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

一个容易想到的方案是,处理鼠标消息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消息,因为窗口和鼠标是“同步”移动的,你的鼠标相对于窗口是静止的。(这些细节你可以自己写个示例来测试并分析得出,事实上我也是这么做的。如果我的观点有错误,欢迎指正)。

转自:http://blog.csdn.net/scollins/article/details/5517536

WM_NCHITTEST后鼠标消息收不到

问题: 
我出来的WM_NCHITTEST,但同时又想处理WM_RBUTTONUP,可以结果却是两者无法共存。而我的需求就是“两者共存”。

问题原因: 
对 WM_NCHITTEST与WM_LBUTTONDOWN、WM_NCLBUTTONDOWN、WM_LBUTTONUP、 WM_NCLBUTTONUP、WM_RBUTTONUP、WM_NCRBUTTONUP、WM_MOUSEMOVE、WM_NCMOUSEMOVE的关系理解错误

具体分析: 
无标题窗口拖动,我们一般是采用:
响应WM_NCHITTEST消息,返回HTCAPTION来实现。
但是,如果在这同时还要处理鼠标的消息,如WM_LBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONUP、WM_MOUSEMOVE,你会发现,这些消息都收不到了。

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

解决烦方案:
 
呵呵,自然是同时处理WM_NCHITTEST和WM_NCRBUTTONUP,而不处理WM_RBUTTONUP

:) 现在你应该知道本文的标题其实是有问题的了吧,不过这确实是我当时的“问题”。

转自:http://blog.csdn.net/debehe/article/details/4412959

WM_NCHITTEST消息相关推荐

  1. 关于WM_NCHITTEST消息(移动无标题对话框多个)

    我为了移动一个无标题栏的窗体,使用了WM_NCHITTEST消息,这个消息大概如下: 通常,我们拖动对话框窗口的标题栏来移动窗口,但有时候,我们想通过鼠标在客户区上拖动来移动窗口. 一个容易想到的方案 ...

  2. 关于WM_NCHITTEST消息

    通常,我们拖动对话框窗口的标题栏来移动窗口,但有时候,我们想通过鼠标在客户区上拖动来移动窗口. 在OnLButtonDown中添加代码如下代码也可以完成窗体拖动: ::PostMessage(m_hW ...

  3. [转]关于WM_NCHITTEST消息

    http://www.cnblogs.com/GnagWang/archive/2010/09/12/1824394.html 我为了移动一个无标题栏的窗体,使用了WM_NCHITTEST消息,这个消 ...

  4. WM_NCHITTEST消息欺骗Windows(一)

    用WM_NCHITTEST消息欺骗Windows(一) 2007-02-02 14:26 通常,我们拖动对话框窗口的标题栏来移动窗口,但有时候,我们想通过鼠标在客户区上拖动来移动窗口. 一个容易想到的 ...

  5. VC++ 鼠标非显示区域命中测试消息WM_NCHITTEST和相关编程问题学习1

    此消息代表非显示区域命中测试:非显示区域,应该指窗口客户区以外的区域: 这个消息优先于所有其他的显示区域和非显示区域鼠标消息:其中lParam参数含有鼠标位置的x和y屏幕坐标,wParam 这里没有用 ...

  6. windows 编程 —— 消息与参数(滚动条、键盘、鼠标)

    目录: 滚动条 键盘 鼠标 滚动条ScrollBar 发送消息:WM_VSCROLL和WM_HSCROLL 参数wParam:wParam消息参数被分为一个低字组和一个高字组.wParam的低字组是一 ...

  7. 窗口发送消息参数详解

    窗口发送消息参数详解 //    窗口.发送消息    函数功能: 将指定的消息发送到一个窗口,同win32 api 里面的SendMessage等同的效果 中文函数原型: 发送消息(hwnd,msg ...

  8. Windows的消息定义大全

    消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了. 例如:单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.           消息本身是作为 ...

  9. Windows消息类型及说明

    WM_ Window Message 窗口消息,一般用在SendMessage,PostMessage这样的消息函数中 SM_ Static Message 静态标签消息 SS_ Static Sty ...

最新文章

  1. Non-Maximum Suppression,NMS非极大值抑制
  2. [NC15748]旅游 树形dp基础
  3. Boruvka求最小生成树
  4. java facets_Java UIComponent.getFacets方法代码示例
  5. 使用WINS服务器实现跨网段名称注册解析和释放
  6. jchdl - GSL Node
  7. 协作与协同有什么区别_OA软件, BPM系统, 移动办公系统, 协同办公系统到底有什么区别...
  8. 26. Leetcode 206. 反转链表 (链表-反转链表)
  9. struts2在加载首页是访问action
  10. 怎样将WPS转换word格式?如何进行操作
  11. 历史上唯独倒闭的两家银行,看看他们是如何破产的
  12. Java生鲜电商平台-缓存架构实战
  13. LINUX系统无线网频繁断开_Ubuntu系统安装amp;amp;解决WiFi不可用
  14. 边缘计算精华问答 | 边缘计算需要IaaS、PaaS、SaaS等服务能力吗?
  15. 关于子网掩码的是是非非
  16. python中df占位符_PYTHON 中的%s %占位符用法
  17. 微软发布下一代VS 2010和Framework 4.0
  18. UML建模工具最近更新(-2022年7月)(1)Papyrus、EA
  19. 【读书笔记】大数据 数据挖掘 相关
  20. 【学习强化学习】三、Q learning和Sarsa算法

热门文章

  1. 相继上一篇,thingsboard的二次开发环境配置和简单的logo替换
  2. Mercury——又一个 MSN 谈天序次递次
  3. qrobot开发总结之android手势识别
  4. RabbitMQ简介(一)
  5. [FROM WOJ]#1935 魔法树
  6. TWS蓝牙耳机中应用的接近传感芯片
  7. 【sdx62】WCN6855 WCN6856 bdf and firmware说明
  8. 倾听客户声音 华为无线亮相美国CTIA展
  9. Starling Tweens
  10. idea在pom.xml中加入dependency后里external libraries的引用不显示解决办法