我有一种情况,我正在处理一个窗体上的双击鼠标单击事件&。在这两种情况下都必须加载,但是当发生双击时,我不希望执行附加到单击事件的代码。拦截单击或双击鼠标 - 仅执行双击代码双击
有没有办法拦截鼠标点击,并检查双或单,然后适当地执行正确的事件?
也许通过拦截窗口的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