Link to home
Start Free TrialLog in
Avatar of arindam_bh
arindam_bh

asked on

Keyboard & Mouse Hook

Hello friends,
How to hook the keyboard and mouse using VB .net. I am developing a COM application involving Microsoft Internet Explorer and I needed to trap the keys & mouse and selectively allow the user to be able to type certain moments and prevent him in certain moments. Can someone provide the skeletal structure for doing the same? At present I am using the following skeleton, but it is not able to hook.
Can someone please help.
Thanks in Advance
Arindam

Friend Class frmMain
     Inherits System.Windows.Forms.Form

    Public Shared hHook As Long = 0
    Public Const WH_KEYBOARD As Short = 2
    Public Const KBH_MASK As Integer = &H20000000
    Public Const HC_ACTION = 0
    Public Const WM_LBUTTONDOWN = &H201
    Public Const WM_LBUTTONUP = &H202
    Public Const WM_RBUTTONDOWN = &H204
    Public Const WH_MOUSE = 7
    Public Delegate Function CallBack(ByVal nCode As Integer, ByVal wParam As Long, ByVal lParam As Long) As Integer

    Public HookProc As CallBack

    Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal HookProc As CallBack, ByVal hInstance As Long, ByVal wParam As Integer) As Integer

    Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long

    Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
     Const EM_UNDO As Short = &HC7s

    Private Declare Function OSWinHelp Lib "user32" Alias "WinHelpA" (ByVal hwnd As Integer, ByVal HelpFile As String, ByVal wCommand As Short, ByRef dwData As Integer) As Short
     
    Private Sub frmMain_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
        'Some Code
        installHook()
    End Sub

    Public Sub installHook()
        HookProc = New CallBack(AddressOf HookHandlerClass.HookProc)
        UnhookWindowsHookEx(hHook)
        hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf HookHandlerClass.HookProc, 0&, AppDomain.CurrentDomain.GetCurrentThreadId())
    End Sub
End Class






Imports System.Runtime.InteropServices
Public Class HookHandlerClass

    Public Shared hooked As Boolean
    Public Shared kHook As Long = 0
    Public Shared mHook As Long = 0
    Public Const WH_KEYBOARD As Short = 2
    Public Const KBH_MASK As Integer = &H20000000
    Public Const HC_ACTION = 0
    Public Const WM_RBUTTONDOWN = &H204
    Public Const WH_MOUSE = 7


    Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

    Public Overloads Shared Function HookProc( _
    ByVal nCode As Integer, _
    ByVal wParam As Long, _
    ByVal lParam As Long) As Integer
        Dim buffer As String
        MsgBox(nCode)
        buffer = lParam.ToString()
        MsgBox(buffer)
        HookProc = CallNextHookEx(kHook, nCode, wParam, lParam)
    End Function
End Class
Avatar of iboutchkine
iboutchkine

In the code editor's left dropdown list, select (Overrides). Then in the
right dropdown select WndProc. The new WndProc receives a Message object
as a parameter. Use its ToString method to display the message's name.

Call the base class's WndProc method to process the message normally. This
is very important! If you don't process the message normally, the form will
not be able to resize itself, draw its interior, and perform other standard
Windows functions.



Protected Overrides Sub WndProc(ByRef m As _
    System.Windows.Forms.Message)
    Debug.WriteLine(m.ToString)
'here you can intercept the window message and do whatever you want witth it

    MyBase.WndProc(m)
End Sub
Avatar of arindam_bh

ASKER

Thanks. The proposed solution looks to solve the issue but there is a new problem. I can't put any code block in the subroutine as it creates run time error after intercepting about 40 messages or so. I tried with writing down to a file instead of debug.writeline. It generates runtime error "System.NullReferenceException". I have tried putting other codes also and to my findings, it crashes with all codes other than debug.writeline.
So, I am not able to trap the messages and process them either.
Any help?
Thanks
Arindam
I have tried MessageBox.Show(m.ToString) instead of Debug.WriteLine(m.ToString)
 and it works fine. Are you getting error after intercepting 40 messages or always?
I have gone through several articles on hooking and finally could find out that Windows limits a time frame to process a message. After, this time frame is over, it is giving the run time error. So, what is required is that I should somehow nullify hte message and send it for normal processing. I can't consume any message. This is what appears to me......
ASKER CERTIFIED SOLUTION
Avatar of arindam_bh
arindam_bh

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Please ignore the previous code fragment. The wrong fragment is posted and I am sorry for that
The fragment will be


Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As IntPtr

        If (nCode < HC_ACTION) Then
            Return CallNextHookEx(m_KeyboardHook, nCode, wParam, lParam.ToInt32)

        ElseIf (nCode = HC_ACTION) Then
            If wParam = WM_KEYDOWN Or wParam = WM_SYSKEYDOWN Then
                P = CType(Marshal.PtrToStructure(lParam, GetType(KBDLLHOOKSTRUCT)), KBDLLHOOKSTRUCT)
                P.scanCode = Nothing
                P.vkCode = Nothing
                Marshal.StructureToPtr(P, lParam, True)
                Return lParam
        End If
    End Function
Avatar of Bob Learned
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

PAQ/Refund

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

TheLearnedOne
EE Cleanup Volunteer