拾取元素时出现“穿透”,经过 WindowsAPI 拾取目标控件元素信息时,鼠标拾取元素的同时还执行了目标控件上的操做,这种状况是不容许的。(PS:经过单击进行拾取,常规状况下已作了屏蔽,不会执行目标控件的操做)ide
通过分析和测试,得出结论。误操做的控件绑定的不是 Click事件 而是 MouseUp事件测试
在正确捕获到目标元素后会取消 CallNextHookEx事件 的执行,从而达到单击时屏蔽目标控件操做的目的。优化
目的是为了捕获“单击操做”,但 WindowsApi 只有 MouseDown 和 MouseUp事件。因而将两次都算做单击事件,并作了些许优化。即两次事件的间隔时间小于200ms则第二次事件执行时直接 return。spa
对于绑定了 Click事件 的控件在第二次捕获操做后直接return, CallNextHookEx 检测不到完整的Click操做直接等于屏蔽效果。
对于绑定了 MouseUp事件 的控件在第二次捕获后直接return, CallNextHookEx 恰好能够检测到MouseUp事件就继续执行。
顺着此思路,第二次捕获后 return 时取消 CallNextHookEx事件 便可。设计
以为别人的想法有点“多此一举”,毕竟先捕获两次在屏蔽一次还出了问题,就想进行优化。换一种思路,若尝试只捕获一次,是否就不存在此问题?code
第一次尝试理解出错,捕获了 MouseDown事件,觉得会屏蔽 MouseUp事件。结果没捕获 MouseUp事件 致使目标控件的 MouseUp事件 直接执行了。
反过来捕获 MouseUp 就能够了。blog
一开始以为我这种写法还挺好,结果存在巨大的漏洞,即目标控件绑定了MouseDown事件我这种方式又会出现“穿透”。别人的写法虽然冗余但不存在此问题。事件
初学时还有另外一种想法:即都不执行 CallNextHookEx 事件会怎样,结果鼠标移动事件都没法触发,致使鼠标没法移动class
if (wParam == WM_LBUTTONDOWN) if (wParam == WM_LBUTTONUP) 鼠标移动512 ox200 鼠标按下513 0x201 鼠标弹起514 0x202 WM_LBUTTONDOWN 鼠标按下 WM_LBUTTONUP 鼠标弹起
MouseHookProc(int nCode, int wParam, IntPtr lParam) sed
int CallNextHookEx( int idHook, int nCode, int wParam, IntPtr lParam)
测试用例:建立一个含三种事件的Java应用和C#应用(问题暴露在一个Java应用上,日常处理Windows平台的应用较多)
因为一开始不知道系统是如何屏蔽原目标控件事件的,给问题分析带来很大的难度