深刻:截获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最明显的就是支 ...
随机推荐
- c++ 中CImage类Load函数,路径中含有空格应对策略!
最近,在写一些东西的时候,需要用到CImage类将JPG各式的图片转换成BMP图片,传入的是图片的绝对地址:如C:\Users\Administrator\Documents\Visual Studi ...
- μC/OS学习资料(附Ebook)
注意:下载地址位于文末. μC/OS-各版本源码 <嵌入式实时操作系统μC/OS-II> <嵌入式实时操作系统μC/OS-III> <μC/OSII2.52源码中文译注- ...
- OC中线程的状态相关
1.线程的状态NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; ...
- 开始着手Oracle中Scott用户的管理系统
准备好长时间,一直想把最近所学用于实践,正好想到Oracle的Scott用户的表设计还算合理,且自己也很熟悉,现将整个系统的架构设定如下: 1.数据库不用说,Oracle 11g 的 Scott 用户 ...
- teamviewer无法启动
在 Linux.Mac OS X和 Windows下都可以用,但在 Linux 下无法启动时怎么办? 笔者回家工作时,都会用 Teamviewer 连线到其他 Linux 桌面,但某天起 Teamvi ...
- boost 轻量级信号量
#include <boost/thread/condition_variable.hpp> #include <boost/thread/mutex.hpp> #in ...
- Android Content Provider的启动过程源码分析
本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...
- Qt 多线程 详细函数说明及其事例
转:http://www.cnblogs.com/hicjiajia/archive/2011/02/03/1948955.html Qt线程类 Qt 包含下面一些线程相关的类:QThread 提供了 ...
- Delphi + Asm - TBits类的学习
技术交流,DH讲解. 在D2010的classes中有个TBits类,这个类主要是位操作的. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 TBits = class privat ...
- hdu 3350
hdu 3350 题意:让你求运算式的结果和运算过程中加法的次数 (a) > (b) ? (a) : (b) 大于取a,小于等于取b MAX( 1 + 2 , 3) 因为(a) > (b) ...