深刻:截获windows的消息并分析实例(DefWindowProc),以WM_NCHITTEST举例(Windows下每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息)
1,回调函数工作机制
回调函数由操作系统自动调用,回调函数的返回值当然也是返回给操作系统了。
2,截获操作系统发出的消息,截获到后,将另外一个消息返回给操作系统,已达到欺骗操作系统的目的。
下面还是以具体例子来说明比较好。
在 Windows下,每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息。通常情况下,要把这个消息直接交给 DefWindowProc 函数处理,该函数会返回一个值来告诉 Windows 鼠标按下的是窗口的哪一部分。Windows 利用这个返回值来决定要发送的鼠标消息的类型。例如,如果用鼠标左键单击窗口的标题栏,处理WM_NCHITTEST 消息的 DefWindowProc 函数会返回 HTCAPTION,然后 Windows 会再向该
窗口发送 WM_NCLBUTTONDOWN 消息。如果 DefWindowProc 的返回值是 HTCLIENT,Windows 就将鼠标所在位置的坐标从屏幕坐标转化成为客户区坐标,并且通过WM_LBUTTONDOWN 消息通知用户。
3,既然谈到了截获消息,势必要谈下由“消息产生消息”了,同样以例子来说明:
Windows用WM_NCHITTEST消息产生所有其它鼠标消息,这种由消息引出其它消息的想法在Windows中是很普遍的。举个例子,如果您在一个Windows程序的系统菜单图标上双击一下,那么程序将会终止。双击产生一系列的WM_NCHITTEST消息。由于鼠标定位在系统菜单图标上,因此DefWindowProc将传回HTSYSMENU的值,并且Windows把wParam等于HTSYSMENU的WM_NCLBUTTONDBLCLK消息放在消息队列中,也就是说WM_NCLBUTTONDBLCLK消息的wParam参数是HTSYSMENU,这个是由DefWindowProc返回的。 窗口消息处理程序通常把鼠标消息传递给DefWindowProc,当DefWindowProc接收到wParam参数等于HTSYSMENU的WM_NCLBUTTONDBLCLK消息时,它就把wParam参数等于SC_CLOSE的WM_SYSCOMMAND消息放入消息队列中(这个WM_SYSCOMMAND消息是在使用者从系统菜单中选择「Close」时产生的)。同样地,窗口消息处理程序也把这个消息传给DefWindowProc。DefWindowProc通过给窗口消息处理程序发送WM_CLOSE消息来处理该消息。
下面再以拖动窗口为例来说明:
单击鼠标,系统投递WM_NCHITTEST到消息队列,lParam参数记录了光标的移动目的位置,由DefWindowProc处理,该函数的返回值代表当前鼠标移动到了窗口的哪个部位,如HTCLIENT,HTCAPTION,由DefWindowProc处理WM_NCHITTEST,将控制权返回给系统。DefWindowProc返回HTCAPTION,此时操作系统返回什么消息呢?应该是WM_NCLBUTTON,其wParam参数包含了鼠标在窗口的哪个部位,lParam包含了鼠标的坐标位置。
如果应用程序没有对该消息响应,则由系统默认处理。
系统默认处理又是怎样的呢?系统发现wParam指示了鼠标点击的是标题栏,就会标识当前窗口处于“拖拽状态”(Windows内部记录了每个窗口的状态信息)。由于标识了“拖拽状态”,则从此刻起到鼠标键放开之前,你的鼠标移动状况完全由Windows跟踪。它根据鼠标的移动,使得窗口作“同步”移动。注意,这个过程中,窗口不会收到WM_NCMOUSEMOVE消息,因为窗口和鼠标是“同步”移动的,你的鼠标相对于窗口是静止的。(这些细节你可以自己写个示例来测试并分析得出,事实上我也是这么做的。如果我的观点有错误,欢迎指正)。
当放开鼠标左键时,系统产生WM_NCHITTEST消息,lParam包含当前坐标,该消息由DefWindowProcl处理,处理完成后,由DefWindowProc投递WM_NCLBUTTONUP消息,wParam参数表示当前光标所在窗口的部位,它是由DefWindowProc返回的,lParam代表光标的坐标。当然了这个消息同样由DefWindowProc来处理,处理完毕后,这个函数同时需要发出WM_SYSCOMMAND消息,它的wParam应该是SC_MOVE,代表窗口移动,该消息同样由DefWindowProc处理,处理完后,它在发出WM_MOVE消息,lParam代表了窗口左上角的坐标....先分析到这....
下面对上面的描述进行总结:
当光标移动或者鼠标按下或者释放时,系统产生WM_NCHITTEST消息,其中wParam为空,lParam参数记录了光标的x和y坐标。该消息由DefWindowProc处理,在合适的情况下(多数情况下其实都是这样),DefWindowProc又会向消息队列投递一个WM_SYSCOMMAND消息(注:当用户点击菜单命令时,发出这个消息),其wParam参数反应了用户单击了哪个菜单项命令。回调函数把这个消息给DefWindowProc处理,这个函数再投递一个WM_CLOSE(如果用户选择的是菜单的close命令)给用户程序消息队列。
//下面分析移动鼠标
4,鼠标消息,WM_NCHITTEST,WM_MOUSEMOVE,WM_NCMOUSEMOVE
如果鼠标在窗口移动,系统投递WM_NCHITTEST到消息队列,lParam参数记录了光标的移动目的位置,由DefWindowProc处理,该函数的返回值代表当前鼠标移动到了窗口的哪个部位,如HTCLIENT,HTCAPTION,将控制权返回给系统。
假设光标在标题栏,此时系统会投递一个WM_NCMOUSEMOVE到消息队列,wParam是上面DefWindowProc的返回值,代表了光标移动到了窗口的哪个部位,lParam代表了当前光标所在的坐标。
http://blog.sina.com.cn/s/blog_673ef8130100mw4b.html
深刻:截获windows的消息并分析实例(DefWindowProc),以WM_NCHITTEST举例(Windows下每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息)的更多相关文章
- Kafka 和 ZooKeeper 的分布式消息队列分析
1. Kafka 总体架构 基于 Kafka-ZooKeeper 的分布式消息队列系统总体架构如下: 如上图所示,一个典型的 Kafka 体系架构包括若干 Producer(消息生产者),若干 bro ...
- 【NX二次开发】分析曲线某位置的信息 UF_MODL_ask_curve_props
分析曲线某位置的信息:点.切线.主副法线.半径等 extern DllExport void ufsta(char *param, int *returnCode, int rlen) { UF_in ...
- windows消息机制与实例
windows发送窗口消息 所需工具:spy++,visual studio 2017,c#语言 技术路线:首先通过spy++获得所要操纵的窗口的句柄,函数的原型声明为: [DllImport(&qu ...
- windows XP系统内核文件分析(全)
Windows XP个别 System32 文件 System32 文件夹下个别要移除的文件 我们就要删除另外600 个 system32 文件...我们要一次把它们全都解决掉. 以下是我所删除的 S ...
- 如何利用wireshark对TCP消息进行分析
原文:https://www.cnblogs.com/studyofadeerlet/p/7485298.html 如何利用wireshark对TCP消息进行分析 (1) 几个概念介绍 1 seq ...
- Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)
事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...
- ANR问题分析实例
ANR监测机制包含三种: Service ANR,前台进程中Service生命周期不能超过20秒,后台进程中Service的生命周期不能超过200秒. 在启动Service时,抛出定时消息SERVIC ...
- 窗口、消息查看分析利器Spy++
Spy++ —— 窗口.消息查看分析利器 Spy++ —— 窗口.消息查看分析利器 2016年07月15日 00:25:22 阅读数:23170 1,简介 Microsoft Spy++是一个非常 ...
- [转]C#截获本机数据包方法实例
本文向大家介绍Windows Sockets的一些关于用C#实现的原始套接字(Raw Socket)的编程,以及在此基础上实现的网络封包监视技术.同Winsock1相比,Winsock2最明显的就是支 ...
随机推荐
- ConcurrentModificationException异常解决办法
今天在写一个带缓存功能的访问代理程序时出现了java.util.ConcurrentModificationException异常,因为该异常是非捕获型异常而且很少见,所以费了些时间才找到问题所在,原 ...
- OFBIZ分享:利用Nginx +Memcached架设高性能的服务
近年来利用Nginx和Memcached来提高站点的服务性能的作法,如一夜春风般的遍及大江南北,越来越多的门户站点和电子商务平台都採用它们来为自己的用户提供更好的服务体验.如:网易.淘宝.京东.凡客等 ...
- 泛虚拟化技术(以Xen为例)
一.概述 最主要的特点是:修改Guest OS的内核代码.通过修改内核,使Guest OS明白自己是运行在R-1,不要直接去运行特权指令,如果要运行就去Hypercall(主动VMM陷入). ...
- IIS - HTTP 错误 500.21 - Internal Server Error 处理程序“WebServiceHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
http://www.cnblogs.com/yc-755909659/p/3445278.html 首先观察,aspnet_regiis.exe文件是不是损坏的,如果是,重新下载,覆盖即可,在百度云 ...
- The parent project must have a packaging type of POM
在Eclipse中使用Maven添加模块时报错:The parent project must have a packaging type of POM 解决办法: 是将pom.xml 中的 < ...
- innerHeight与clientHeight、innerWidth与clientWidth、scrollLeft与pageXOffset等属性
区分innerHeight与clientHeight.innerWidth与clientWidth.scrollLeft与pageXOffset等属性 标签: innerheight clienthe ...
- Inverse Quadratic Interpolation (website)
Inverse Quadratic Interpolation: https://www.youtube.com/watch?v=0H7mVPTLF7Q : https://www.youtube. ...
- 关于CopyU!的常见问题解答
拷优(CopyU!)常见问题解答 本常见问题解答列举了一些常见的疑问及其解释,如果您对CopyU!有任何问题,请您首先查看本解答! 本解答将会保持随时更新! 一.使用篇: 1.问:我的杀毒软件 ...
- iOS UIButton详细介绍
昨天,做了项目中的一点,觉得细节还是很重要的.像一个普通的UIButton,给它调试字体格式,大小什么的,确实是蛮耗时间的. 今天打算详细的归纳归纳.. typedef NS_ENUM(NSInteg ...
- velocity中的velocityCounter不起作用的原因
今天用org.springframework.ui.velocity.VelocityEngineFactoryBean 时,velocityCounter这个变量的时候死活不起作用,折腾了良久也不行 ...