Search code examples
javawindowswinapijna

Sending Keystrokes to Hidden Window via JNA


Background:

I'm sending keystrokes to a program (Text Editor) that I hide and then Send the F7 Key and after that four keys of text (kind of a password). I'm using JNA Library and the SendMessage function of Win32API to send the messages, can't use sendInput() because I need to send to a specific window handle.

Code:

private static void sendInputToWindow(WinDef.HWND editorWindowHandle, char[] password) throws InterruptedException {
        User32.INSTANCE.ShowWindow(editorWindowHandle, WinUser.SW_HIDE);
        User32.INSTANCE.SetForegroundWindow(editorWindowHandle);
        User32.INSTANCE.SetFocus(editorWindowHandle);

        //F7 KEY SENT
        WinDef.WPARAM wparam = new WinDef.WPARAM(F7_VIRTUAL_KEY);
        WinDef.LPARAM lparam = new WinDef.LPARAM(0);
        log.debug("SENDING F7");
        User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_KEYDOWN, wparam, lparam);
        Thread.sleep(1000);
        log.debug("SENDING PASSWORD");
        // PASSWORD SENT
        User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[0]), lparam);
        User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[1]), lparam);
        User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[2]), lparam);
        User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[3]), lparam);
        Thread.sleep(500);
        log.debug("SENDING ENTER");
        // ENTER KEY SENT
        User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_KEYDOWN, new WinDef.WPARAM(ENTER_KEY), lparam);
    }

Problem:

When I am sending Keystrokes through SendMessage, after some time or randomly ( I don't know what's causing the issue here ) but sometimes it does not send the keystrokes at all!

So it's a hit or miss situation, most of the times it sends the keystrokes while other times it does not. I wonder if there is a better way to send keystrokes to a hidden window? or if I am doing something wrong here.

Thank You.


Solution

  • As stated in the commentary, SendInput is the most supported.

    I tried to use it in the Win32 console and found that it worked very well. The code is as follows.

    #include <iostream>
    #include <Windows.h>
    
    int main()
    {
        INPUT input[5];
        memset(input, 0, sizeof(input));
    
        input[0].type = input[1].type = input[2].type = input[3].type = input[4].type = INPUT_KEYBOARD; 
        SetForegroundWindow((HWND)0x000A09D8);//EDIT EDITOR HANDLE
    
        while (1)
        {       
            input[0].ki.wVk = '1';
            input[1].ki.wVk = '2';
            input[2].ki.wVk = '3';
            input[3].ki.wVk = '4';
            input[4].ki.wVk = VK_RETURN;
    
            SendInput(5, input, sizeof(INPUT));
            std::cout << GetLastError() << std::endl;
            Sleep(1000);
            input[0].ki.dwFlags = input[1].ki.dwFlags = input[2].ki.dwFlags = input[3].ki.dwFlags = input[4].ki.dwFlags = KEYEVENTF_KEYUP;
            SendInput(5, input, sizeof(INPUT));
            input[0].ki.dwFlags = input[1].ki.dwFlags = input[2].ki.dwFlags = input[3].ki.dwFlags = input[4].ki.dwFlags = 0;
            std::cout << GetLastError() << std::endl;
            Sleep(1000);
        }
    
        return 0;
    }
    

    print