Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Keyboard & Mouse Hook

Posted on 2003-03-27
8
Medium Priority
?
1,536 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
  • 4
  • 2
7 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
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 

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

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

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

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Simulator games are perfect for generating sample realistic data streams, especially for learning data analysis. It is even useful for demoing offerings such as Azure stream analytics, PowerBI etc.
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …

580 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