Advertisement
CorrM

KeyboardWorker By CorrM

Apr 7th, 2017
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 8.41 KB | None | 0 0
  1. Imports System.Runtime.InteropServices
  2. Imports System.Windows.Forms
  3. Imports System.Drawing
  4. Imports System.Reflection
  5. Imports System.Globalization
  6.  
  7. Module Module1
  8.     Dim WithEvents kbHook As New KeyboardWorker
  9.  
  10.     Private Sub kbHook_KeyDown(ByVal xKey As System.Windows.Forms.Keys) Handles kbHook.KeyDown
  11.         ' To Change Current Culture In this program (it's important) (Maybe in console app only :D not tested in forms app)
  12.         InputLanguage.CurrentInputLanguage = InputLanguage.FromCulture(KeyboardWorker.GetCurrentCulture())
  13.  
  14.         ' Just For Test
  15.         Debug.Write(kbHook.ToUnicode(xKey))
  16.     End Sub
  17.  
  18.     Sub Main()
  19.         ' Start Hook
  20.         kbHook.Start()
  21.  
  22.         ' Msg Loop Don't Remove, You Can put this code in thread, (Console/Forms app must use this loop)
  23.         Dim msg As KeyboardWorker.WinMSG
  24.         While KeyboardWorker.GetMessage(msg, IntPtr.Zero, 0, 0) <> 0 : End While
  25.     End Sub
  26.  
  27. End Module
  28.  
  29. Public Class KeyboardWorker
  30.     Structure WinMSG
  31.         Dim hwnd As Long
  32.         Dim message As Long
  33.         Dim wParam As Long
  34.         Dim lParam As Long
  35.         Dim time As Long
  36.         Dim pt As Point
  37.     End Structure
  38.  
  39.     Public Enum MapVirtualKeyMapTypes As UInt32
  40.         ''' <summary>uCode is a virtual-key code and is translated into a scan code.
  41.         ''' If it is a virtual-key code that does not distinguish between left- and
  42.         ''' right-hand keys, the left-hand scan code is returned.
  43.         ''' If there is no translation, the function returns 0.
  44.         ''' </summary>
  45.         ''' <remarks></remarks>
  46.         MAPVK_VK_TO_VSC = &H0
  47.  
  48.         ''' <summary>uCode is a scan code and is translated into a virtual-key code that
  49.         ''' does not distinguish between left- and right-hand keys. If there is no
  50.         ''' translation, the function returns 0.
  51.         ''' </summary>
  52.         ''' <remarks></remarks>
  53.         MAPVK_VSC_TO_VK = &H1
  54.  
  55.         ''' <summary>uCode is a virtual-key code and is translated into an unshifted
  56.         ''' character value in the low-order word of the return value. Dead keys (diacritics)
  57.         ''' are indicated by setting the top bit of the return value. If there is no
  58.         ''' translation, the function returns 0.
  59.         ''' </summary>
  60.         ''' <remarks></remarks>
  61.         MAPVK_VK_TO_CHAR = &H2
  62.  
  63.         ''' <summary>Windows NT/2000/XP: uCode is a scan code and is translated into a
  64.         ''' virtual-key code that distinguishes between left- and right-hand keys. If
  65.         ''' there is no translation, the function returns 0.
  66.         ''' </summary>
  67.         ''' <remarks></remarks>
  68.         MAPVK_VSC_TO_VK_EX = &H3
  69.  
  70.         ''' <summary>Not currently documented
  71.         ''' </summary>
  72.         ''' <remarks></remarks>
  73.         MAPVK_VK_TO_VSC_EX = &H4
  74.     End Enum
  75.  
  76.     <StructLayout(LayoutKind.Sequential)>
  77.     Private Structure KBDLLHOOKSTRUCT
  78.         Public vkCode As UInt32
  79.         Public scanCode As UInt32
  80.         Public flags As KBDLLHOOKSTRUCTFlags
  81.         Public time As UInt32
  82.         Public dwExtraInfo As UIntPtr
  83.     End Structure
  84.  
  85.     <Flags()>
  86.     Private Enum KBDLLHOOKSTRUCTFlags As UInt32
  87.         LLKHF_EXTENDED = &H1
  88.         LLKHF_INJECTED = &H10
  89.         LLKHF_ALTDOWN = &H20
  90.         LLKHF_UP = &H80
  91.     End Enum
  92.  
  93.     Public Shared Event KeyDown(ByVal Key As Keys)
  94.     Public Shared Event KeyUp(ByVal Key As Keys)
  95.  
  96.     Private Const WH_KEYBOARD_LL As Integer = 13
  97.     Private Const HC_ACTION As Integer = 0
  98.     Private Const WM_KEYDOWN = &H100
  99.     Private Const WM_KEYUP = &H101
  100.     Private Const WM_SYSKEYDOWN = &H104
  101.     Private Const WM_SYSKEYUP = &H105
  102.  
  103.     Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
  104.     Private HHookID As IntPtr = IntPtr.Zero
  105.  
  106.     Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
  107.    
  108.  
  109.     <DllImport("user32.dll")>
  110.     Public Shared Function DispatchMessage(ByRef lpmsg As WinMSG) As IntPtr
  111.     End Function
  112.  
  113.     <DllImport("user32.dll")>
  114.     Public Shared Function GetMessage(
  115.      ByRef lpMsg As WinMSG,
  116.      ByVal hWnd As IntPtr,
  117.      ByVal wMsgFilterMin As UInteger,
  118.      ByVal wMsgFilterMax As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
  119.     End Function
  120.  
  121.     <DllImport("user32.dll")>
  122.     Public Shared Function TranslateMessage(ByRef lpMsg As WinMSG) As <MarshalAs(UnmanagedType.Bool)> Boolean
  123.     End Function
  124.  
  125.     <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
  126.     Public Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
  127.     End Function
  128.  
  129.     <DllImport("kernel32.dll")> _
  130.     Public Shared Function GetCurrentThreadId() As UInteger
  131.     End Function
  132.  
  133.     <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
  134.     Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
  135.     End Function
  136.  
  137.     <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
  138.     Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
  139.     End Function
  140.  
  141.     <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
  142.     Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
  143.     End Function
  144.  
  145.     <DllImport("USER32.DLL", CharSet:=CharSet.Unicode)> _
  146.     Public Shared Function ToUnicode(virtualKey As UInteger, scanCode As UInteger, keyStates As Byte(), <MarshalAs(UnmanagedType.LPArray)> <Out> chars As Char(), charMaxCount As Integer, flags As UInteger) As Integer
  147.     End Function
  148.  
  149.     <DllImport("user32.dll", SetLastError:=True)> _
  150.     Private Shared Function GetForegroundWindow() As IntPtr
  151.     End Function
  152.  
  153.     <DllImport("user32.dll", SetLastError:=True)> _
  154.     Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As IntPtr) As UInteger
  155.     End Function
  156.  
  157.     <DllImport("user32.dll")> _
  158.     Private Shared Function GetKeyboardLayout(idThread As UInteger) As IntPtr
  159.     End Function
  160.  
  161.     <DllImport("User32.dll", SetLastError:=False, CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)> _
  162.     Public Shared Function MapVirtualKey(ByVal uCode As UInt32, ByVal uMapType As MapVirtualKeyMapTypes) As UInt32
  163.     End Function
  164.  
  165.     Public Function ToUnicode(xKey As Windows.Forms.Keys) As Char
  166.         Dim keyStates(255) As Byte
  167.         Dim chars(1) As Char
  168.  
  169.         ToUnicode(xKey,
  170.                   MapVirtualKey(xKey, MapVirtualKeyMapTypes.MAPVK_VK_TO_VSC),
  171.                   keyStates,
  172.                   chars,
  173.                   chars.Length,
  174.                   0)
  175.  
  176.         Return chars(0)
  177.     End Function
  178.    
  179.     Public Shared Function GetCurrentCulture() As CultureInfo
  180.         Dim hKL As IntPtr = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero))
  181.         Return New System.Globalization.CultureInfo(hKL.ToInt32() And &HFFFF)
  182.     End Function
  183.  
  184.  
  185.     Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
  186.         If (nCode = HC_ACTION) Then
  187.             Dim struct As KBDLLHOOKSTRUCT
  188.             Select Case wParam
  189.                 Case WM_KEYDOWN, WM_SYSKEYDOWN
  190.                     struct = CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT)
  191.  
  192.                     Dim xKey As Keys = struct.vkCode
  193.                     RaiseEvent KeyDown(xKey)
  194.  
  195.                     'Case WM_KEYUP, WM_SYSKEYUP
  196.                     '    Dim xKey As Keys = CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode
  197.                     '    RaiseEvent KeyUp(xKey)
  198.             End Select
  199.         End If
  200.  
  201.         Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
  202.     End Function
  203.  
  204.     Public Sub Start()
  205.         HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0)
  206.         If HHookID = IntPtr.Zero Then
  207.             Throw New Exception("Could not set keyboard hook")
  208.         End If
  209.     End Sub
  210.  
  211.     Protected Overrides Sub Finalize()
  212.         If Not HHookID = IntPtr.Zero Then
  213.             UnhookWindowsHookEx(HHookID)
  214.         End If
  215.         MyBase.Finalize()
  216.     End Sub
  217.  
  218. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement