My MouseHook is blocking the hook notifications of other applications

I've implemented an LL mouse hook that captures when the mouse receives movement if the mouse is moving on an specified area.

The problem is that when my mouse hook is active, it blocks the hooks of other applications, other applications that tries to catch mouse events. Like for example FoldersPopup which is a tiny and free application that hooks the middle mouse button on the windows explorer title bars to open a menu, when my hook is active, the hook of that program does not works.

I don't know if it can be a design problem of my hook, or of those 3rd party hooks, but I think is my fault because MSDN documentation talks about that sort of blockings and I didn't understood at all which value should return my procedure in the different circunstances where I'm returning a value.

If the class instance is disabled (with a custom IsEnabled property), I return 0

If the mouse position is not inside the specified area (of a custom WorkingArea property), I return 0

If nCode parameter is 0 , I return 0

If nCode parameter is bigger than 0 , I return -1

If nCode param is less than 0 , I return the next CallNextHookEx integer value.

What I'm doing wrong?.

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

Here is the full mousehook source if you want to test, its universal usage so easy to test for further answers on this question, the source just needs 1 copy/paste step.

http://pastebin.com/gxfiqb0i


Quoting the MSDN documentation :

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.

Not calling CallNextHookEx means others application will not receive the event, so your observation makes sense. Not calling CallNextHookEx should be done if you intentionally want to end the hook chain.

链接地址: http://www.djcxy.com/p/61740.html

上一篇: 从Windows键盘挂接程序返回后崩溃

下一篇: 我的MouseHook阻止其他应用程序的挂钩通知