Imports System.Runtime.InteropServices
Public Class UserActivityHook
Public Delegate Function HookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
Public KeyboardHookProcedure As HookProc
Public KeyDown As KeyEventHandler
Public KeyPress As KeyPressEventHandler
Public KeyUp As KeyEventHandler
Public OnMouseActivity As MouseEventHandler
Private Shared hKeyboardHook As Integer
Private Shared hMouseHook As Integer
Public MouseHookProcedure As HookProc
Public Const WH_KEYBOARD_LL As Integer = 13
Public Const WH_MOUSE_LL As Integer = 14
Private Const WM_KEYDOWN As Integer = 256
Private Const WM_KEYUP As Integer = 257
Private Const WM_LBUTTONDBLCLK As Integer = 515
Private Const WM_LBUTTONDOWN As Integer = 513
Private Const WM_LBUTTONUP As Integer = 514
Private Const WM_MBUTTONDBLCLK As Integer = 521
Private Const WM_MBUTTONDOWN As Integer = 519
Private Const WM_MBUTTONUP As Integer = 520
Private Const WM_MOUSEMOVE As Integer = 512
Private Const WM_RBUTTONDBLCLK As Integer = 518
Private Const WM_RBUTTONDOWN As Integer = 516
Private Const WM_RBUTTONUP As Integer = 517
Private Const WM_SYSKEYDOWN As Integer = 260
Private Const WM_SYSKEYUP As Integer = 261
#Region "dll imports"
' Methods
<DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)> _
Public Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
End Function
<DllImport("user32")> _
Public Shared Function GetKeyboardState(ByVal pbKeyState As Byte()) As Integer
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)> _
Public Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As HookProc, ByVal hInstance As IntPtr, ByVal threadId As Integer) As Integer
End Function
<DllImport("user32")> _
Public Shared Function ToAscii(ByVal uVirtKey As Integer, ByVal uScanCode As Integer, ByVal lpbKeyState As Byte(), ByVal lpwTransKey As Byte(), ByVal fuState As Integer) As Integer
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)> _
Public Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function
#End Region
#Region "Structures and whatnot"
<StructLayout(LayoutKind.Sequential)> _
Public Class KeyboardHookStruct
' Fields
Public dwExtraInfo As Integer
Public flags As Integer
Public scanCode As Integer
Public time As Integer
Public vkCode As Integer
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class MouseHookStruct
' Fields
Public dwExtraInfo As Integer
Public hwnd As Integer
Public pt As POINT
Public wHitTestCode As Integer
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class POINT
' Fields
Public x As Integer
Public y As Integer
End Class
#End Region
Public Sub New()
Start()
End Sub
Protected Overrides Sub Finalize()
Try
Me.Stop()
Finally
MyBase.Finalize()
End Try
End Sub
Public Sub Start()
If (UserActivityHook.hMouseHook = 0) Then
Me.MouseHookProcedure = New HookProc(AddressOf Me.MouseHookProc)
UserActivityHook.hMouseHook = UserActivityHook.SetWindowsHookEx(14, Me.MouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)), 0)
If (UserActivityHook.hMouseHook = 0) Then
Me.Stop()
Throw New Exception("SetWindowsHookEx failed.")
End If
End If
If (UserActivityHook.hKeyboardHook = 0) Then
Me.KeyboardHookProcedure = New HookProc(AddressOf Me.KeyboardHookProc)
UserActivityHook.hKeyboardHook = UserActivityHook.SetWindowsHookEx(13, Me.KeyboardHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)), 0)
If (UserActivityHook.hKeyboardHook = 0) Then
Me.Stop()
Throw New Exception("SetWindowsHookEx ist failed.")
End If
End If
End Sub
Public Sub [Stop]()
Dim flag1 As Boolean = True
Dim flag2 As Boolean = True
If (UserActivityHook.hMouseHook <> 0) Then
flag1 = UserActivityHook.UnhookWindowsHookEx(UserActivityHook.hMouseHook)
UserActivityHook.hMouseHook = 0
End If
If (UserActivityHook.hKeyboardHook <> 0) Then
flag2 = UserActivityHook.UnhookWindowsHookEx(UserActivityHook.hKeyboardHook)
UserActivityHook.hKeyboardHook = 0
End If
If (Not flag1 OrElse Not flag2) Then
Throw New Exception("UnhookWindowsHookEx failed.")
End If
End Sub
Private Function MouseHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
If ((nCode >= 0) AndAlso (Not Me.OnMouseActivity Is Nothing)) Then
Dim buttons1 As MouseButtons = MouseButtons.None
Dim num3 As Integer = wParam
If (num3 <> 513) Then
If (num3 = 516) Then
buttons1 = MouseButtons.Right
End If
Else
buttons1 = MouseButtons.Left
End If
Dim num1 As Integer = 0
If (buttons1 <> MouseButtons.None) Then
If ((wParam = 515) OrElse (wParam = 518)) Then
num1 = 2
Else
num1 = 1
End If
End If
Dim struct1 As MouseHookStruct = CType(Marshal.PtrToStructure(lParam, GetType(MouseHookStruct)), MouseHookStruct)
Dim args1 As New MouseEventArgs(buttons1, num1, struct1.pt.x, struct1.pt.y, 0)
Me.OnMouseActivity.Invoke(Me, args1)
End If
Return UserActivityHook.CallNextHookEx(UserActivityHook.hMouseHook, nCode, wParam, lParam)
End Function
Private Function KeyboardHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
If ((nCode >= 0) AndAlso (((Not Me.KeyDown Is Nothing) OrElse (Not Me.KeyUp Is Nothing)) OrElse (Not Me.KeyPress Is Nothing))) Then
Dim struct1 As KeyboardHookStruct = CType(Marshal.PtrToStructure(lParam, GetType(KeyboardHookStruct)), KeyboardHookStruct)
If ((Not Me.KeyDown Is Nothing) AndAlso ((wParam = 256) OrElse (wParam = 260))) Then
Dim args1 As New KeyEventArgs(CType(struct1.vkCode, Keys))
Me.KeyDown.Invoke(Me, args1)
End If
If ((Not Me.KeyPress Is Nothing) AndAlso (wParam = 256)) Then
Dim buffer1 As Byte() = New Byte(256 - 1) {}
UserActivityHook.GetKeyboardState(buffer1)
Dim buffer2 As Byte() = New Byte(2 - 1) {}
If (UserActivityHook.ToAscii(struct1.vkCode, struct1.scanCode, buffer1, buffer2, struct1.flags) = 1) Then
Dim args2 As New KeyPressEventArgs(Convert.ToChar(buffer2(0)))
Me.KeyPress.Invoke(Me, args2)
End If
End If
If ((Not Me.KeyUp Is Nothing) AndAlso ((wParam = 257) OrElse (wParam = 261))) Then
Dim args3 As New KeyEventArgs(CType(struct1.vkCode, Keys))
Me.KeyUp.Invoke(Me, args3)
End If
End If
Return UserActivityHook.CallNextHookEx(UserActivityHook.hKeyboardHook, nCode, wParam, lParam)
End Function
End Class