我竟是小丑

問題描述

表象

拾取元素時出現「穿透」,經過 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

CallNextHookEx 

 int CallNextHookEx( int idHook, int nCode, int wParam, IntPtr lParam) 

測試過程

測試用例:建立一個含三種事件的Java應用和C#應用(問題暴露在一個Java應用上,日常處理Windows平臺的應用較多)

  • 推測一:兩種應用分別來測試,究竟與平臺是否相關聯。經過測試發現與平臺關聯性不大
  • 推測二:是否和Web端的事件冒泡相似。經過一些測試發現兩者並不想通
  • 推測三:控件註冊的事件不同,經過按住鼠標不放,可以捕獲且不觸發事件,大體推測與綁定的事件相關
  • 推測四:我點在了哪裏?應用仍是遮蓋層,程序本來設計的有遮蓋層,算是干擾項。經過質詢同事瞭解到咱們並無點在遮蓋層上。

因爲一開始不知道系統是如何屏蔽原目標控件事件的,給問題分析帶來很大的難度

相關文章
相關標籤/搜索