我的 MouseHook 阻止了其他应用程序的挂钩通知
My MouseHook is blocking the hook notifications of other applications
我已经实现了一个 LL 鼠标钩子,如果鼠标在指定区域移动,它会在鼠标接收到移动时进行捕获。
问题是当我的鼠标挂钩处于活动状态时,它会阻止其他应用程序的挂钩,其他应用程序试图捕获鼠标事件。
例如 FoldersPopup,它是一个小巧的免费应用程序,它在 windows 资源管理器标题栏上挂钩 中间 鼠标按钮以打开菜单,当我的挂钩是激活,那个程序的钩子不起作用。
我不知道这是否是我的挂钩或那些第 3 方挂钩的设计问题,但我认为是我的错,因为 MSDN 文档谈到了这种阻塞,而我当时并不理解所有这些值都应该 return 我在不同情况下的程序 return 正在计算一个值。
如果 class 实例被禁用(使用自定义 IsEnabled
属性),我 return 0
如果鼠标位置不在指定区域内(自定义WorkingArea
属性),我return0
如果nCode
参数是0,我return0
如果nCode
参数大于0,我return-1
如果nCode
参数小于0,我return下一个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
这里是完整的 mousehook 源代码,如果你想测试的话,它的普遍用法很容易测试这个问题的进一步答案,源代码只需要 1 copy/paste 步骤。
引用 MSDN 文档:
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.
不调用 CallNextHookEx
意味着其他应用程序不会收到该事件,因此您的观察是有道理的。如果您有意结束挂钩链,则不应调用 CallNextHookEx
。
我已经实现了一个 LL 鼠标钩子,如果鼠标在指定区域移动,它会在鼠标接收到移动时进行捕获。
问题是当我的鼠标挂钩处于活动状态时,它会阻止其他应用程序的挂钩,其他应用程序试图捕获鼠标事件。 例如 FoldersPopup,它是一个小巧的免费应用程序,它在 windows 资源管理器标题栏上挂钩 中间 鼠标按钮以打开菜单,当我的挂钩是激活,那个程序的钩子不起作用。
我不知道这是否是我的挂钩或那些第 3 方挂钩的设计问题,但我认为是我的错,因为 MSDN 文档谈到了这种阻塞,而我当时并不理解所有这些值都应该 return 我在不同情况下的程序 return 正在计算一个值。
如果 class 实例被禁用(使用自定义 IsEnabled
属性),我 return 0
如果鼠标位置不在指定区域内(自定义WorkingArea
属性),我return0
如果nCode
参数是0,我return0
如果nCode
参数大于0,我return-1
如果nCode
参数小于0,我return下一个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
这里是完整的 mousehook 源代码,如果你想测试的话,它的普遍用法很容易测试这个问题的进一步答案,源代码只需要 1 copy/paste 步骤。
引用 MSDN 文档:
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.
不调用 CallNextHookEx
意味着其他应用程序不会收到该事件,因此您的观察是有道理的。如果您有意结束挂钩链,则不应调用 CallNextHookEx
。