I am replacing an AutoHotkey script with a VB.net application. Part of the script involves sending keystrokes to an active application. VB uses SendInput and does send the keystrokes, but the application doesn't "get" them, but when AutoHotkey sends the same key to the same application, it works. I have verified that VB is indeed sending the keys properly. Does anyone know how to imitate the autohotkey Send function?

Xcelled194

It looks like the window your sending the key strokes to needs to be the active window.

I was able to use these additional functions to do that.

I created a seperate VS project named TestKeyInput. This code brings that window up and types Dim s as string into TestKeyInput's compiler.

One other thing: I modified that sendInputs sub to take in a short instead of a char and then use the Keys enumeration to send the keys. No more convertToInt16.

Hope this helps you

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        Dim WINDOW_HANDLE As IntPtr = FindWindow(Nothing, "TestKeyInput - Microsoft Visual Studio (Administrator)")
        Dim WINDOW_THREAD_ID As IntPtr = GetWindowThreadProcessId(WINDOW_HANDLE, IntPtr.Zero)

        If WINDOW_THREAD_ID = IntPtr.Zero Then Exit Sub
        If AttachThreadInput(GetCurrentThreadId(), WINDOW_THREAD_ID, True) = False Then Exit Sub

        ShowWindow(WINDOW_HANDLE, 1) 'If the window is minimized, bring it up
        SetForegroundWindow(WINDOW_HANDLE) 'Now bring it to front

        SendInputs.SendKey(Keys.D)
        SendInputs.SendKey(Keys.I)
        SendInputs.SendKey(Keys.M)
        SendInputs.SendKey(Keys.Space)
        SendInputs.SendKey(Keys.S)
        SendInputs.SendKey(Keys.Space)
        SendInputs.SendKey(Keys.A)
        SendInputs.SendKey(Keys.S)
        SendInputs.SendKey(Keys.Space)
        SendInputs.SendKey(Keys.S)
        SendInputs.SendKey(Keys.T)
        SendInputs.SendKey(Keys.R)
        SendInputs.SendKey(Keys.I)
        SendInputs.SendKey(Keys.N)
        SendInputs.SendKey(Keys.G)

        AttachThreadInput(GetCurrentThreadId(), WINDOW_THREAD_ID, False)
    End Sub

New Functions

<System.Runtime.InteropServices.DllImport("user32.dll")> _
   Public Function FindWindow( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String) As IntPtr
    End Function

    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Public Function GetWindowThreadProcessId( _
        ByVal hWnd As IntPtr, _
        ByVal lpwdProcessId As IntPtr) As IntPtr
    End Function

    <System.Runtime.InteropServices.DllImport("kernel32.dll")> _
    Public Function GetCurrentThreadId() As IntPtr
    End Function

    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Public Function AttachThreadInput( _
        ByVal idAttach As IntPtr, _
        ByVal idAttachTo As IntPtr, _
        ByVal fAttach As Boolean) As Boolean
    End Function

    <System.Runtime.InteropServices.DllImport("user32.dll")> _
   Public Function ShowWindow( _
        ByVal hWnd As IntPtr, _
        ByVal nCmdShow As Integer) As Boolean
    End Function

    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Public Function SetForegroundWindow( _
        ByVal hWnd As IntPtr) As Boolean
    End Function

Thats not my problem. The window is active, and if I activate notepad instead, the keystrokes do send. No, its an issue of the actual Send method, if that makes sense.

I was able to get key strokes in notepad with the above code.

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        Dim WINDOW_HANDLE As IntPtr = FindWindow(Nothing, "test - Notepad")
        Dim WINDOW_THREAD_ID As IntPtr = GetWindowThreadProcessId(WINDOW_HANDLE, IntPtr.Zero)

        If WINDOW_THREAD_ID = IntPtr.Zero Then Exit Sub
        If AttachThreadInput(GetCurrentThreadId(), WINDOW_THREAD_ID, True) = False Then Exit Sub

        ShowWindow(WINDOW_HANDLE, 1) 'If the window is minimized, bring it up
        SetForegroundWindow(WINDOW_HANDLE) 'Bring it to front

        SendInputs.SendKey(Keys.D)
        SendInputs.SendKey(Keys.I)
        SendInputs.SendKey(Keys.M)
        SendInputs.SendKey(Keys.Space)
        SendInputs.SendKey(Keys.S)
        SendInputs.SendKey(Keys.Space)
        SendInputs.SendKey(Keys.A)
        SendInputs.SendKey(Keys.S)
        SendInputs.SendKey(Keys.Space)
        SendInputs.SendKey(Keys.S)
        SendInputs.SendKey(Keys.T)
        SendInputs.SendKey(Keys.R)
        SendInputs.SendKey(Keys.I)
        SendInputs.SendKey(Keys.N)
        SendInputs.SendKey(Keys.G)

        AttachThreadInput(GetCurrentThreadId(), WINDOW_THREAD_ID, False)
    End Sub

I think I understand what your saying.

It's only going to work on the active app.

Do you have control over the app your sending key strokes to?

If so I have a way to receive key and mouse events global wide.

How do I say it? The keystrokes are getting to the proper application. its just ignoring them.

SendInput is the more powerful way to send keys without failure.
All other language (AutoIt, Delphi, VBA, dot.net, etc.) has a SEND command
that is not trustable.

AutoHotkey uses a different Windows API from Send statement from VB.
In my app, I usually make a call to a autohotkey .ahk file, passing the keys like parameters.
Other options is research the Windows API to make it in VB.NET directly


;------ Key.ahk------------
; Autohotkey Syntax
if %0%=0
return
SendInput %1%
;--------------------------


And then I use

Dim p As Process
Dim Teclas As String
Teclas = "....."
p.StartInfo.Filename = "C:\...\AutoHotkey.exe"
p.StartInfo.Arguments = "C:\....\Key.ahk " & Teclas
p.Start
This article has been dead for over six months. Start a new discussion instead.