[VB.NET] Global mouse-hook problem

Discussion in 'Mixed Languages' started by stevemk14ebr, May 4, 2013.

  1. stevemk14ebr

    stevemk14ebr MDL Senior Member

    Jun 23, 2010
    267
    48
    10
    #1 stevemk14ebr, May 4, 2013
    Last edited by a moderator: Apr 20, 2017
    i have supposedly global mouse hook that isn't quite working right it should be calling an event every time the action happens no matter what has focus, for example say double mouse click, but it only calls the event when the mouse cursor is over the form , and i can't figure out why here's my code:

    hook module:
    Code:
    Imports System.Runtime.InteropServices
    Module MouseHook
        ' Standard MSDN Code.
        Private Const HC_ACTION As Integer = 0
        Private Const WH_MOUSE_LL As Integer = 14
        Private Const WM_MOUSEMOVE As Integer = &H200
        Private Const WM_LBUTTONDOWN As Integer = &H201
        Private Const WM_LBUTTONUP As Integer = &H202
        Private Const WM_LBUTTONDBLCLK As Integer = &H203
        Private Const WM_RBUTTONDOWN As Integer = &H204
        Private Const WM_RBUTTONUP As Integer = &H205
        Private Const WM_RBUTTONDBLCLK As Integer = &H206
        Private Const WM_MBUTTONDOWN As Integer = &H207
        Private Const WM_MBUTTONUP As Integer = &H208
        Private Const WM_MBUTTONDBLCLK As Integer = &H209
        Private Const WM_MOUSEWHEEL As Integer = &H20A
    
        Public Event Mouse_Move()
        Public Event Mouse_Left_Down()
        Public Event Mouse_Left_Up()
        Public Event Mouse_Left_DoubleClick()
        Public Event Mouse_Right_Down()
        Public Event Mouse_Right_Up()
        Public Event Mouse_Right_DoubleClick()
        Public Event Mouse_Middle_Down()
        Public Event Mouse_Middle_Up()
        Public Event Mouse_Middle_DoubleClick()
        Public Event Mouse_Wheel()
    
        Public Delegate Function CallBack( _
            ByVal nCode As Integer, _
            ByVal wParam As IntPtr, _
            ByVal lParam As IntPtr) As Integer
    
        'Declare the mouse hook constant.
        'For other hook types, obtain these values from Winuser.h in Microsoft SDK.
        ' Or online documentation. 
        Public WH_MOUSE As Integer = 7
        Public hHook As Integer = 0
    
        'Keep the reference so that the delegate is not garbage collected.
        Public hookproc As CallBack
    
        'Import for the SetWindowsHookEx function.
        <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
         Public Function SetWindowsHookEx _
              (ByVal idHook As Integer, ByVal HookProc As CallBack, _
               ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
        End Function
    
        'Import for the CallNextHookEx function.
        <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
         Public Function CallNextHookEx _
              (ByVal idHook As Integer, ByVal nCode As Integer, _
               ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        End Function
        'Import for the UnhookWindowsHookEx function.
        <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
             Public Function UnhookWindowsHookEx _
                  (ByVal idHook As Integer) As Boolean
        End Function
    
        
    
        'MouseHookStruct structure declaration.
        <StructLayout(LayoutKind.Sequential)> Public Structure MouseHookStruct
            Public pt As Point
            Public hwnd As Integer
            Public wHitTestCode As Integer
            Public dwExtraInfo As Integer
        End Structure
    
        Public Function MouseHookProc( _
      ByVal nCode As Integer, _
      ByVal wParam As IntPtr, _
      ByVal lParam As IntPtr) As Integer
            Dim MyMouseHookStruct As New MouseHookStruct()
    
            MyMouseHookStruct = CType(Marshal.PtrToStructure(lParam, MyMouseHookStruct.GetType()), MouseHookStruct)
    
            If (nCode < 0) Then
                'Return CallNextHookEx(hHook, nCode, wParam, lParam)
            End If
    
            If (nCode = HC_ACTION) Then
                Select Case wParam
                    Case WM_MOUSEMOVE
                        RaiseEvent Mouse_Move()
                    Case WM_LBUTTONDOWN
                        RaiseEvent Mouse_Left_Down()
                    Case WM_LBUTTONUP
                        RaiseEvent Mouse_Left_Up()
                    Case WM_LBUTTONDBLCLK
                        RaiseEvent Mouse_Left_DoubleClick()
                    Case WM_RBUTTONDOWN
                        RaiseEvent Mouse_Right_Down()
                    Case WM_RBUTTONUP
                        RaiseEvent Mouse_Right_Up()
                    Case WM_RBUTTONDBLCLK
                        RaiseEvent Mouse_Right_DoubleClick()
                    Case WM_MBUTTONDOWN
                        RaiseEvent Mouse_Middle_Down()
                    Case WM_MBUTTONUP
                        RaiseEvent Mouse_Middle_Up()
                    Case WM_MBUTTONDBLCLK
                        RaiseEvent Mouse_Middle_DoubleClick()
                    Case WM_MOUSEWHEEL
                        RaiseEvent Mouse_Wheel()
                End Select
            End If
    
    
    
            Return CallNextHookEx(hHook, nCode, wParam, lParam)
    
        End Function
    implementation:
    Code:
     
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            hookproc = AddressOf MouseHookProc
            hHook = SetWindowsHookEx(WH_MOUSE, hookproc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, AppDomain.GetCurrentThreadId())
            AddHandler MouseHook.Mouse_Left_DoubleClick, AddressOf Me.mouseleftdc
    
        End Sub
       
        Private Sub mouseleftdc()
            
            MessageBox.Show("double clicked")
        End Sub
    would love help on this one guys
     
  2. Michaela Joy

    Michaela Joy MDL Crazy Lady

    Jul 26, 2012
    4,068
    4,649
    150
    I had a similar problem with using global hook functions in Delphi. For Me, I had to create a DLL and call the hook functions from there.

    Take a look here.

    http://vbcity.com/forums/t/120595.aspx

    Best of luck. :)

    :Miki.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. stevemk14ebr

    stevemk14ebr MDL Senior Member

    Jun 23, 2010
    267
    48
    10
    #3 stevemk14ebr, May 5, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    omg i read that link and the guys says he replaced WH_MOUSE with WH_MOUSE_LL for global, i it turns out im using wh_mouse which is the not global one, hopefully it's as easy as change the code to this

    Code:
     hookproc = AddressOf MouseHookProc
            hHook = SetWindowsHookEx(WH_MOUSE_LL, hookproc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, AppDomain.GetCurrentThreadId())
            AddHandler MouseHook.Mouse_Left_DoubleClick, AddressOf Me.mouseleftdc
    Edit: After attempting to change the code to
    Code:
      hookproc = AddressOf MouseHookProc
            hHook = SetWindowsHookEx(WH_MOUSE_LL, hookproc, IntPtr.Zero, AppDomain.GetCurrentThreadId())
            AddHandler MouseHook.Mouse_Middle_DoubleClick, AddressOf Me.mouseleftdc
    I can confirm it now broke the hook altogether (doesn't even raise the event when over the form) any ideas why, it should be working as i'm not use WH_MOUSE_LL the global variant of the hook
     
  4. Michaela Joy

    Michaela Joy MDL Crazy Lady

    Jul 26, 2012
    4,068
    4,649
    150
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. stevemk14ebr

    stevemk14ebr MDL Senior Member

    Jun 23, 2010
    267
    48
    10
    #5 stevemk14ebr, May 5, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    i had actually found that dll but the problem was everytime i got a sample project setup the dll would always have an internal error example console would show "A first chance exception has occurred in WindowsHookLib" and i was unable to get it to work, i was using the add referance option in visual studio to include it in my project, but couldn't figure out how to do the
    Code:
    Imports WindowsHookLib
    that the demo projects use, it doesn't seem to work the same as modules where you just drag it into the solution explorer and say
    Code:
    Imports projectname.modulename
    Edit: I mixed some code up from what i found online and old sources and little from me and finally got this, everything except double clicks work, although if you know how to import that dll i am still very interested
    Code:
    Imports System.Runtime.InteropServices
    
    Public Class Form1
        Private Structure MSLLHOOKSTRUCT
            Public pt As Point
            Public mouseData As Int32
            Public flags As Int32
            Public time As Int32
            Public extra As IntPtr
        End Structure
        Public Event Mouse_Move()
        Public Event Mouse_Left_Down()
        Public Event Mouse_Left_Up()
        Public Event Mouse_Left_DoubleClick()
        Public Event Mouse_Right_Down()
        Public Event Mouse_Right_Up()
        Public Event Mouse_Right_DoubleClick()
        Public Event Mouse_Middle_Down()
        Public Event Mouse_Middle_Up()
        Public Event Mouse_Middle_DoubleClick()
        Public Event Mouse_Wheel()
    
        Private _mouseHook As IntPtr
        Private Const WH_MOUSE_LL As Int32 = 14
        Private Const WM_MOUSEMOVE As Integer = &H200
        Private Const WM_LBUTTONDOWN As Integer = &H201
        Private Const WM_LBUTTONUP As Integer = &H202
        Private Const WM_LBUTTONDBLCLK As Integer = &H203
        Private Const WM_RBUTTONDOWN As Integer = &H204
        Private Const WM_RBUTTONUP As Integer = &H205
        Private Const WM_RBUTTONDBLCLK As Integer = &H206
        Private Const WM_MBUTTONDOWN As Integer = &H207
        Private Const WM_MBUTTONUP As Integer = &H208
        Private Const WM_MBUTTONDBLCLK As Integer = &H209
        Private Const WM_MOUSEWHEEL As Integer = &H20A
        Private Delegate Function MouseHookDelegate(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
        <MarshalAs(UnmanagedType.FunctionPtr)> Private _mouseProc As MouseHookDelegate
        Private Declare Function SetWindowsHookExW Lib "user32.dll" (ByVal idHook As Int32, ByVal HookProc As MouseHookDelegate, ByVal hInstance As IntPtr, ByVal wParam As Int32) As IntPtr
        Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hook As IntPtr) As Boolean
        Private Declare Function CallNextHookEx Lib "user32.dll" (ByVal idHook As Int32, ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
        Private Declare Function GetCurrentThreadId Lib "kernel32.dll" () As Integer
        Private Declare Function GetModuleHandleW Lib "kernel32.dll" (ByVal fakezero As IntPtr) As IntPtr
    
    
        Public Function HookMouse() As Boolean
            Debug.Print("Mouse Hooked")
            If _mouseHook = IntPtr.Zero Then
                _mouseProc = New MouseHookDelegate(AddressOf MouseHookProc)
                _mouseHook = SetWindowsHookExW(WH_MOUSE_LL, _mouseProc, GetModuleHandleW(IntPtr.Zero), 0)
            End If
            Return _mouseHook <> IntPtr.Zero
        End Function
    
        Public Sub UnHookMouse()
            Debug.Print("Mouse UnHooked")
            If _mouseHook = IntPtr.Zero Then Return
            UnhookWindowsHookEx(_mouseHook)
            _mouseHook = IntPtr.Zero
        End Sub
    
        Private Function MouseHookProc(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
            Select Case wParam
                Case WM_MOUSEMOVE
                    RaiseEvent Mouse_Move()
                Case WM_LBUTTONDOWN
                    RaiseEvent Mouse_Left_Down()
                Case WM_LBUTTONUP
                    RaiseEvent Mouse_Left_Up()
                Case WM_LBUTTONDBLCLK
                    RaiseEvent Mouse_Left_DoubleClick()
                Case WM_RBUTTONDOWN
                    RaiseEvent Mouse_Right_Down()
                Case WM_RBUTTONUP
                    RaiseEvent Mouse_Right_Up()
                Case WM_RBUTTONDBLCLK
                    RaiseEvent Mouse_Right_DoubleClick()
                Case WM_MBUTTONDOWN
                    RaiseEvent Mouse_Middle_Down()
                Case WM_MBUTTONUP
                    RaiseEvent Mouse_Middle_Up()
                Case WM_MBUTTONDBLCLK
                    RaiseEvent Mouse_Middle_DoubleClick()
                Case WM_MOUSEWHEEL
                    RaiseEvent Mouse_Wheel()
            End Select
           
    
            Return CallNextHookEx(WH_MOUSE_LL, nCode, wParam, lParam)
        End Function
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            HookMouse()
        End Sub
    
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
            UnHookMouse()
        End Sub
    End Class