?
Solved

Keyboard & Mouse Hook

Posted on 2003-03-27
8
Medium Priority
?
1,474 Views
Last Modified: 2012-08-14
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
0
Comment
Question by:arindam_bh
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
8 Comments
 
LVL 28

Expert Comment

by:iboutchkine
ID: 8224759
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
0
 

Author Comment

by:arindam_bh
ID: 8229679
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
0
 
LVL 28

Expert Comment

by:iboutchkine
ID: 8230751
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?
0
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 

Author Comment

by:arindam_bh
ID: 8236186
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......
0
 

Accepted Solution

by:
arindam_bh earned 0 total points
ID: 8237465
Hi,
I find the following article explain why I was facing the problem.
--------------------------------
There are many situations when it's need to disable some combinations of keys from a VB program. For instance, ALT-TAB, CTRL-ESC, ALT-ESC or others like these. Other combinations could be tested at form level using KeyPreview property and KeyPress / KeyDown / KeyUp events. All system keystrokes won't fire key events in a form (or other controls) because they are handled internally by the system. Since application threads never receive messages for these keystrokes, there is no way that an application can intercept them and prevent the normal processing. This behavior is "by design" and ensures that a user can always switch to another application’s window even if an application’s thread enters an infinite loop or hangs. The question is how we can intercept this keystrokes? The solution could be achieved using hooks. A hook is a point in the Microsoft Windows message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure. For Windows NT SP3 (or higher), Microsoft introduced a new hook: WH_KEYBOARD_LL. This hook is called the low-level hook because it is notified of keystrokes just after the user enters them and before the system gets a chance to process them. This hook has a serious drawback: the thread processing the hook filter function could enter an infinite loop or hang. If this happens, then the system will no longer process keystrokes properly and the user will become incredibly frustrated. To alleviate this situation, Microsoft places a time limit on low-level hooks. When the system sends a notification to a low-level keyboard hook’s filter function, the system allows that function a fixed amount of time to execute. If the function does not return in the allotted time, the system ignores the hook filter function and processes the keystroke normally. The amount of time allowed (in milliseconds) is set via the LowLevelHooksTimeout value under the following registry subkey: HKEY_CURRENT_USER\Control Panel\Desktop. The program (VB) is disabling some of these combinations (ALT-TAB, CTRL-ESC and ALT-ESC) as long as the option is checked.
------------------------------
So, finally, I could find out that the following code works. Here I consume the keystrokes and then pass on to the windows for processing (which is apparently doing nothing)
Here is the code fragment.
    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)

                'Set Flag
                If P.vkCode = 37 Or P.vkCode = 38 Or P.vkCode = 39 Or P.vkCode = 40 Or P.vkCode = 113 Then
                    F2Pressed = False
                End If

                'Set Flag
                If P.vkCode = 113 Then
                    F2Pressed = True
                End If

                'Prevent editing

                If F2Pressed = False And P.vkCode <> 37 And P.vkCode <> 38 And P.vkCode <> 39 And P.vkCode <> 40 Then
                    P.scanCode = Nothing
                    P.vkCode = Nothing
                    Marshal.StructureToPtr(P, lParam, True)
                    Return lParam
                End If
            End If
        End If
    End Function


All the rest remains unchanged.......


 
0
 

Author Comment

by:arindam_bh
ID: 8237476
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
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9725515
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
0

Featured Post

Use Filtering Commands to Process Files in Linux

Learn how to manipulate data with the help of various filtering commands such as `cat`, `fmt`, `pr`, and others in Linux.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question