拾取元素時出現「穿透」,經過 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平臺的應用較多)
因爲一開始不知道系統是如何屏蔽原目標控件事件的,給問題分析帶來很大的難度