Answer 2
Hi Dylan,
Welcome to VB.NET forums!
You also can have a look at keyboard hook in this scenario.
A hook is a
point in the system message-handling mechanism where an
application can install a subroutine to
monitor the message traffic in the system. This is where certain types of messages will be processed before they reach the target
window procedure. For a detailed introduction on hooks, please refer to
http://msdn.microsoft.com/en-us/library/ms632589(VS.85).aspx To set a Windows hook, we call the Windows API SetWindowsHookEx from the user32.dll. This function installs an application-defined hook procedure in the system hook chain associated with the certain hook type. We use the Windows API CallNextHookEx from the user32.dll to pass the hook information to the next hook procedure in the current hook chain. The Windows API UnhookWindowsHookEx is used to remove a hook procedure installed in a hook chain by the SetWindowsHookEx function.
In order to set a low level mouse and keyboard hook in VB.NET, we P/Invoke Windows API SetWindowsHookEx, CallNextHookEx, UnhookWindowsHookEx, and GetModuleHandle.
The first parameter of SetWindowsHookEx specifies the
type of hook procedure to be installed. Here we use WH_KEYBOARD_LL or WH_MOUSE_LL .
The second parameter is the pointer to the hook procedure. In C# we pass the delegate of the hook callback function to this parameter.
The third parameter is the handle of the module containing the hook procedure. Therefore, we call the GetModuleHandle to retrieve the current module handle of the C# hook application.
The fourth parameter specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same
desktop as the calling thread.
To conclude the hook procedure, we use CallNextHookEx function to pass the hook information to the next hook procedure in the current hook chain.
When we want to stop the low level mouse or keyboard hook, we can use the UnhookWindowsHookEx function to remove the hook procedure installed. The parameter is the hook ID we get from the SetWindowsHookEx function.
Take a look at following code snippet. I mainly refer to
this article . You can also read following articles for your reference.
How to set a Windows hook in Visual C# .NET
http://support.microsoft.com/kb/318804
Windows Hooks in the .NET Framework
http://msdn.microsoft.com/en-us/magazine/cc188966.aspx
Processing Global Mouse and Keyboard Hooks in C#
http://www.codeproject.com/KB/cs/globalhook.aspx
Global System Hooks in .NET
http://www.codeproject.com/KB/system/globalsystemhook.aspx
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Drawing
Imports System.Threading
Public Class Form1
'Dim mc As MyHook = New MyHook
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Keyboard.HookKeyboard(Me)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Keyboard.UnhookKeyboard()
End Sub
End Class
Module Keyboard
<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Public Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
End Function
Public Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Integer) As Integer
Public Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" (ByVal idHook As Integer, _
ByVal lpfn As KeyboardHookDelegate, ByVal hmod As IntPtr, _
ByVal dwThreadId As Integer) As Integer
Private Declare Function GetAsyncKeyState Lib "user32" _
(ByVal vKey As Integer) As Integer
Private Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Integer, _
ByVal nCode As Integer, _
ByVal wParam As Integer, _
ByVal lParam As KBDLLHOOKSTRUCT) As Integer
Public Structure KBDLLHOOKSTRUCT
Public vkCode As Integer
Public scanCode As Integer
Public flags As Integer
Public time As Integer
Public dwExtraInfo As Integer
End Structure
' Low-Level Keyboard Constants
Private Const HC_ACTION As Integer = 0
Private Const LLKHF_EXTENDED As Integer = &H1
Private Const LLKHF_INJECTED As Integer = &H10
Private Const LLKHF_ALTDOWN As Integer = &H20
Private Const LLKHF_UP As Integer = &H80
' Virtual Keys
Public Const VK_TAB As Integer = &H9
Public Const VK_CONTROL As Integer = &H11
Public Const VK_ESCAPE As Integer = &H1B
Public Const VK_DELETE As Integer = &H2E
Private Const WH_KEYBOARD_LL As Integer = 13
Public KeyboardHandle As Integer
' Implement this function to block as many
' key combinations as you'd like
Public Function IsHooked( _
ByRef Hookstruct As KBDLLHOOKSTRUCT) As Boolean
Debug.WriteLine("Hookstruct.vkCode: " & Hookstruct.vkCode)
Debug.WriteLine(Hookstruct.vkCode = VK_ESCAPE)
Debug.WriteLine(Hookstruct.vkCode = VK_TAB)
'MessageBox.Show(Hookstruct.vkCode.ToString)
If (Hookstruct.vkCode = VK_ESCAPE) And _
CBool(GetAsyncKeyState(VK_CONTROL) _
And &H8000) Then
Call HookedState("Ctrl + Esc blocked")
Return True
End If
If (Hookstruct.vkCode = VK_TAB) And _
CBool(Hookstruct.flags And _
LLKHF_ALTDOWN) Then
Call HookedState("Alt + Tab blockd")
Return True
End If
If (Hookstruct.vkCode = VK_ESCAPE) And _
CBool(Hookstruct.flags And _
LLKHF_ALTDOWN) Then
Call HookedState("Alt + Escape blocked")
Return True
End If
'' disable PrintScreen here
If (Hookstruct.vkCode = 44) Then
Call HookedState("Print blocked")
Return True
End If
Return False
End Function
Private Sub HookedState(ByVal Text As String)
Debug.WriteLine(Text)
End Sub
Public Function KeyboardCallback(ByVal Code As Integer, _
ByVal wParam As Integer, _
ByRef lParam As KBDLLHOOKSTRUCT) As Integer
If (Code = HC_ACTION) Then
Debug.WriteLine("Calling IsHooked")
If (IsHooked(lParam)) Then
Return 1
End If
End If
Return CallNextHookEx(KeyboardHandle, _
Code, wParam, lParam)
End Function
Public Delegate Function KeyboardHookDelegate( _
ByVal Code As Integer, _
ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) _
As Integer
<MarshalAs(UnmanagedType.FunctionPtr)> _
Private callback As KeyboardHookDelegate
Public Sub HookKeyboard(ByRef f As Form)
callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)
KeyboardHandle = SetWindowsHookEx(WH_KEYBOARD_LL, callback, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0)
MessageBox.Show(KeyboardHandle.ToString)
Call CheckHooked()
End Sub
Public Sub CheckHooked()
If (Hooked()) Then
Debug.WriteLine("Keyboard hooked")
Else
Debug.WriteLine("Keyboard hook failed: " & Err.LastDllError)
End If
End Sub
Private Function Hooked() As Boolean
Hooked = KeyboardHandle <> 0
End Function
Public Sub UnhookKeyboard()
If (Hooked()) Then
Call UnhookWindowsHookEx(KeyboardHandle)
End If
End Sub
End Module
If you have any further issues, feel free to tell us.
Best regards,
Riquel
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.