我有一種情況,我正在處理一個窗體上的雙擊鼠標單擊事件&。在這兩種情況下都必須加載,但是當發生雙擊時,我不希望執行附加到單擊事件的代碼。攔截單擊或雙擊鼠標 - 僅執行雙擊代碼雙擊
有沒有辦法攔截鼠標點擊,並檢查雙或單,然後適當地執行正確的事件?
也許通過攔截窗口的WndProc或者什麼?
我有一種情況,我正在處理一個窗體上的雙擊鼠標單擊事件&。在這兩種情況下都必須加載,但是當發生雙擊時,我不希望執行附加到單擊事件的代碼。攔截單擊或雙擊鼠標 - 僅執行雙擊代碼雙擊
有沒有辦法攔截鼠標點擊,並檢查雙或單,然後適當地執行正確的事件?
也許通過攔截窗口的WndProc或者什麼?
不,這幾乎是不可能的,除非你有時間機器。一旦您瞭解了Windows如何區分雙擊和單擊,它並沒有什麼意義。
事實證明,Raymond Chen(Windows Shell團隊的開發人員)在標題爲「Logical consequences of the way Windows converts single-clicks into double-clicks」的博客中解釋了這一點。
具體而言,Windows只知道將某些內容解釋爲雙擊,因爲在GetDoubleClickTime
function指定的時間間隔內發生了秒的點擊。因爲需要千里眼(正如雷蒙德如此雄辯地說),以確定前面的時間,如果事情將是單擊或雙擊,窗口管理器繼續並在收到第一次點擊後發送WM_LBUTTONDOWN
message。 WM_LBUTTONDBLCLK
message僅在稍後發送,在第二次點擊確認後實際表示雙擊。結果是,您的應用程序將始終收到兩個WM_LBUTTONDOWN
消息收到的每個WM_LBUTTONDBLCLK
消息。
現在,.NET Framework設計人員瞭解此過程如何工作並設計了相應引發的事件。當然,他們不能對雙擊之前始終發生的單擊操作做任何事情,但是如果確定用戶希望成爲雙擊事件的一部分,他們就能夠抑制第二次點擊消息。作爲Control.MouseClick
event的文件(這大致對應於WM_LBUTTONDOWN
消息)告訴我們:發生在時間上足夠接近,如由用戶操作系統的鼠標設置確定
兩個單點擊,將生成一個
MouseDoubleClick
事件而不是第二次MouseClick
事件。
,我掛上面確實,但是,提出了應用和開發誰堅持設計一個可能的解決方法雷蒙德的博客文章,其中的雙擊動作是無關的單單擊操作(雖然我們都不建議你實際上做到這一點):
現在假設你是一個程序,但仍想繼續雙擊操作與單擊操作無關的可疑設計。你是做什麼?
那麼,你可以做的一件事就是在收到
WM_LBUTTONDOWN
消息時不做任何事情,除了設置一個定時器在GetDoubleClickTime()
毫秒內觸發。 [已更正上午10點]如果在此時間內收到WM_LBUTTONDBLCLK
消息,則最終是雙擊。如果你不這樣做,那麼它一定是單擊,所以你可以做你的單擊動作(雖然有點晚)。
我刪除了我的答案,因爲我完全錯過了問題的要點。 – ChrisF 2011-01-27 09:48:55
這裏是做你要求的代碼。
Public Class Form1
Const WM_LBUTTONDOWN As Integer = &H201
Const WM_LBUTTONDBLCLK As Integer = &H203
Private WithEvents tmrDoubleClicks As Timer
Dim isDblClk As Boolean
Dim firstClickTime As Date
Dim doubleClickInterval As Integer
Sub New()
' This call is required by the designer.
InitializeComponent()
tmrDoubleClicks = New Timer
' Add any initialization after the InitializeComponent() call.
tmrDoubleClicks.Interval = 50
doubleClickInterval = CInt(Val(Microsoft.Win32.Registry.CurrentUser.
OpenSubKey("Control Panel\Mouse").
GetValue("DoubleClickSpeed", 1000)))
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
If disposing AndAlso tmrDoubleClicks IsNot Nothing Then
tmrDoubleClicks.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_LBUTTONDOWN
If Not isDblClk Then
firstClickTime = Now
tmrDoubleClicks.Start()
End If
Case WM_LBUTTONDBLCLK
isDblClk = True
tmrDoubleClicks.Stop()
DoubleClickActivity()
isDblClk = False
Case Else
MyBase.WndProc(m)
End Select
End Sub
Private Sub DoubleClickActivity()
'implement double click activity here
Dim r As New Random(Now.TimeOfDay.Seconds)
Me.BackColor = Color.FromArgb(r.Next(0, 255),
r.Next(0, 255),
r.Next(0, 255))
End Sub
Private Sub SingleClickActivity()
'implement single click activity here
Beep()
End Sub
Private Sub tmrDoubleClicks_Tick(ByVal sender As Object,
ByVal e As System.EventArgs
) Handles tmrDoubleClicks.Tick
If Now.Subtract(firstClickTime).TotalMilliseconds >
doubleClickInterval Then
'since there was no other click within the doubleclick speed,
'stop waiting and fire the single click activity
isDblClk = False
tmrDoubleClicks.Stop()
SingleClickActivity()
End If
End Sub
End Class
此代碼的癥結在於延遲觸發點擊事件,直到雙擊時間過去。如果在該時間內,則在該時間內發生另一個點擊事件,雙擊事件被調用而不調用點擊事件。但是,如果沒有雙擊,則會調用點擊事件。
這種延遲在具有較長雙擊速度的計算機上尤爲明顯。在典型的計算機上,雙擊速度爲500ms,因此代碼會在點擊發生後的500ms到600ms之間運行點擊事件。
這是WinForms還是WPF? – ChrisF 2011-01-27 09:32:56
這是WinForms – 2011-01-27 09:33:15