0

I use VB.NET. I have coded part of the solution. That is, i set a hook on keyboards and get the characters typed in it. I use the following code:

Imports System.Runtime.InteropServices

Public Class Form1
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
    Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
    Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
    Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
    End Function
    <StructLayout(LayoutKind.Sequential)>
    Private Structure KBDLLHOOKSTRUCT
        Public vkCode As UInt32
        Public scanCode As UInt32
        Public flags As KBDLLHOOKSTRUCTFlags
        Public time As UInt32
        Public dwExtraInfo As UIntPtr
    End Structure
    <Flags()>
    Private Enum KBDLLHOOKSTRUCTFlags As UInt32
        LLKHF_EXTENDED = &H1
        LLKHF_INJECTED = &H10
        LLKHF_ALTDOWN = &H20
        LLKHF_UP = &H80
    End Enum
    Public Shared Event KeyDown(ByVal Key As Keys)
    Public Shared Event KeyUp(ByVal Key As Keys)
    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const HC_ACTION As Integer = 0
    Private Const WM_KEYDOWN = &H100
    Private Const WM_KEYUP = &H101
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_SYSKEYUP = &H105
    Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
    Private HHookID As IntPtr = IntPtr.Zero
    Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        If (nCode = HC_ACTION) Then
            Dim struct As KBDLLHOOKSTRUCT
            Dim KeyboardSruct As KBDLLHOOKSTRUCT = Marshal.PtrToStructure(lParam, GetType(KBDLLHOOKSTRUCT))
            Select Case wParam
                Case WM_KEYDOWN, WM_SYSKEYDOWN
                    If KeyboardSruct.vkCode <> 160 Then
                        Console.WriteLine(KeyboardSruct.vkCode)
                        Console.WriteLine(Chr(KeyboardSruct.vkCode))
                        rt1.AppendText(Chr(KeyboardSruct.vkCode))
                    End If
            End Select
        End If
        'Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
    End Function
    Protected Overrides Sub Finalize()
        If Not HHookID = IntPtr.Zero Then
            UnhookWindowsHookEx(HHookID)
        End If
        MyBase.Finalize()
    End Sub

    Private Sub KeyboardHook_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        If HHookID = IntPtr.Zero Then
            Throw New Exception("Could not set keyboard hook")
        End If

    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub
End Class

But what im looking for is select only the desired keyboard and once catched the pressed keys, avoid the rest of the windows system receive the pressed keys from this keyboard. That is, i need to have exclusive control on the desired keyboard to my app and on desired control inside the app.

Any help about how to do this? Thanks in advance.

Juan Lugo
  • 1
  • 4
  • To hook a specific keyboard, look for examples that use [Raw Input](https://learn.microsoft.com/en-us/windows/win32/inputdev/raw-input?redirectedfrom=MSDN), [SO examples and info](https://stackoverflow.com/q/13076060/2330053). – Idle_Mind Nov 29 '20 at 23:19
  • Thanks for the links. Using some raw input samples, i got the hook on the desired keyboard. My problem now is only how to avoid the messages from keyboard catched arrives to other windows in the operating system... – Juan Lugo Nov 30 '20 at 12:52

1 Answers1

0

use Return CType(1, IntPtr) for avoid the messages from keyboard catched arrives to other windows in the operating system

Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    If (nCode = HC_ACTION) Then
        Dim struct As KBDLLHOOKSTRUCT
        Dim KeyboardSruct As KBDLLHOOKSTRUCT = Marshal.PtrToStructure(lParam, GetType(KBDLLHOOKSTRUCT))
        Select Case wParam
            Case WM_KEYDOWN, WM_SYSKEYDOWN
                If KeyboardSruct.vkCode <> 160 Then
                    Console.WriteLine(KeyboardSruct.vkCode)
                    Console.WriteLine(Chr(KeyboardSruct.vkCode))
                    rt1.AppendText(Chr(KeyboardSruct.vkCode))
                    Return CType(1, IntPtr) ' Inhibit operation
                End If
        End Select
    End If
    Return CallNextHookEx(HHookID, nCode, wParam, lParam)
End Function
XCoder
  • 57
  • 1
  • 5
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Adrian Mole Oct 28 '21 at 22:30