我的MouseHook阻止其他应用程序的挂钩通知
我已经实现了一个LL鼠标钩子,当鼠标在指定区域移动时,捕捉鼠标的移动。
问题是,当我的鼠标挂钩处于活动状态时,它会阻止其他应用程序的钩子,其他应用程序试图捕获鼠标事件。 比如FoldersPopup,它是一个小巧且免费的应用程序,它钩住windows资源管理器标题栏上的中间鼠标按钮以打开菜单,当我的钩子处于活动状态时,该程序的钩子不起作用。
我不知道它是否可以成为我的钩子或第三方钩子的设计问题,但我认为是我的错,因为MSDN文档讨论了这种类型的阻塞,而且我根本不明白哪个值应该返回我的程序在不同的环境中,我返回一个值。
如果类实例被禁用(使用自定义IsEnabled
属性),则返回0
如果鼠标位置不在指定区域(自定义的WorkingArea
属性)内,则返回0
如果nCode
参数为0 ,则返回0
如果nCode
参数大于0 ,则返回-1
如果nCode
参数小于0 ,则返回下一个CallNextHookEx
整数值。
我做错了什么?
Public Class MyMouseHook
' ( More code removed )
Public Sub New()
End Sub
' ( More code removed )
''' <summary>
''' Processes the mouse windows messages and raises it's corresponding events.
''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
''' </summary>
''' <param name="nCode">
''' A code the hook procedure uses to determine how to process the message.
''' If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function
''' without further processing and should return the value returned by CallNextHookEx.
''' </param>
''' <param name="wParam">The identifier of the mouse message.</param>
''' <param name="lParam"> A pointer to an <see cref="NativeMethods.MSLLHOOKSTRUCT"/> structure.</param>
''' <returns>
''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
''' it is highly recommended that you call CallNextHookEx and return the value it returns;
''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
''' and may behave incorrectly as a result.
''' If the hook procedure processed the message,
''' it may return a nonzero value to prevent the system from passing the
''' message to the rest of the hook chain or the target window procedure.
''' </returns>
Private Function LowLevelMouseProc(ByVal nCode As Integer,
ByVal wParam As NativeMethods.WindowsMessages,
ByVal lParam As IntPtr) As Integer
' This class contains an 'IsEnabled' property to
' disable the mouse hook instance.
' If 'IsEnabled' is disabled then I return,
' to avoid the code processing below.
If Not Me.IsEnabled Then
Return 0
End If
If nCode = 0 Then
' The class contains a 'WorkingArea' property that
' limits the hook to work only if the
' mouse coordinates are inside that working area.
Dim x As Integer
Dim y As Integer
Dim mouseStruct As NativeMethods.MsllHookStruct =
CType(Marshal.PtrToStructure(lParam, mouseStruct.GetType()),
NativeMethods.MsllHookStruct)
' ( More code removed )
' If mouse coordinates are not inside the 'WorkingArea' then return,
' to avoid the code processing below.
If x <= Me.WorkingArea.Width AndAlso
y < Me.WorkingArea.Height AndAlso
mouseStruct.Pt.X > Me.WorkingArea.Width Then
Return 0
' ( More code removed )
End If
Select Case wParam
Case NativeMethods.WindowsMessages.WM_MOUSEMOVE
RaiseEvent MouseMove(Me, New Point(x, y))
Case Else
' Do Nothing
Exit Select
End Select
Return 0
ElseIf nCode < 0 Then
Return CInt(NativeMethods.CallNextHookEx(MouseHook,
nCode,
New IntPtr(wParam),
lParam))
Else ' nCode > 0
Return -1
End If
End Function
End Class
这里是完整的鼠标源,如果你想测试,它的通用用法很容易测试这个问题的进一步答案,源只需要1个复制/粘贴步骤。
http://pastebin.com/gxfiqb0i
引用MSDN文档:
如果nCode小于零,则挂钩过程必须返回CallNextHookEx返回的值。
如果nCode大于或等于零,并且挂钩过程不处理该消息,强烈建议您调用CallNextHookEx并返回它返回的值; 否则,已安装WH_MOUSE_LL挂接的其他应用程序将不会收到挂接通知,并可能因此导致行为不正确。 如果钩子过程处理了消息,它可能会返回一个非零值,以防止系统将消息传递给钩子链或目标窗口过程的其余部分。
不调用CallNextHookEx
意味着其他应用程序不会收到事件,所以您的观察是有道理的。 如果您有意要结束挂钩链,则不应调用CallNextHookEx
。
上一篇: My MouseHook is blocking the hook notifications of other applications