SendInput() malfunctions in Notepad

243 Views Asked by At

I've implemented a hook procedure that catches some Alt+letter key combinations and injects predefined strings. An example of a hook procedure is shown below. It detects the hotkeys LeftAlt+Q and LeftAlt+A and injects the string ABCD1234 in both cases, using the WinAPI function SendInput().

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

void DisplayString()
{
    INPUT in[24] = { 0 };
    int i;
    for (i = 0; i < ARRAYSIZE(in); i++) in[i].type = INPUT_KEYBOARD;
    i = 0;
    in[i++].ki.wVk = VK_CONTROL;    // CTRL
    in[i].ki.wVk = VK_CONTROL;      // CTRL Up
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i].ki.wVk = VK_LMENU;        // LeftAlt Up
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = VK_LSHIFT;     // LeftShift down
    in[i++].ki.wVk = 'A';
    in[i].ki.wVk = 'A';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = 'B';
    in[i].ki.wVk = 'B';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = 'C';
    in[i].ki.wVk = 'C';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = 'D';
    in[i].ki.wVk = 'D';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i].ki.wVk = VK_LSHIFT;    // LeftShift Up
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = '1';
    in[i].ki.wVk = '1';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = '2';
    in[i].ki.wVk = '2';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = '3';
    in[i].ki.wVk = '3';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = '4';
    in[i].ki.wVk = '4';
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    in[i++].ki.wVk = VK_CONTROL;    // CTRL
    in[i++].ki.wVk = VK_LMENU;      // LeftAlt Down
    in[i].ki.wVk = VK_CONTROL;      // CTRL Up
    in[i++].ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(ARRAYSIZE(in), in, sizeof(INPUT));
}

HHOOK hHook{ NULL };

#define     VK_HOT_1        0x51
#define     VK_HOT_2        0x41

extern "C" __declspec(dllexport)
LRESULT CALLBACK KeyboardHookProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code < 0) return CallNextHookEx(hHook, code, wParam, lParam);

    // If LeftAlt pressed
    if (wParam == WM_SYSKEYDOWN && (GetAsyncKeyState(VK_LMENU) & 0x80000000))
    {
        DWORD vkCode = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;  // virtual-key code
        if (vkCode == VK_HOT_1 || vkCode == VK_HOT_2)
        {
            DisplayString();
            return 1;
        }
    }
    return CallNextHookEx(hHook, code, wParam, lParam);
}

The hook procedure is installed using the function SetWindowsHookExW().

The program works as expected in a broad range of applications. I've tested it with WordPad, Notepad++, Chrome, Edge, Command Prompt, PowerShell, and Visual Studio. However, the program exhibits unexplained behavior when the string is injected into Notepad. Only 2-4 characters come up, and the rest appear when additional keys are pressed on the keyboard, with a couple of characters following each key down.

This behavior is new. I used Notepad to test this program during development some weeks ago, and Notepad worked fine. I'm using this program on several PCs, and some work problem-free. All the PCs use Windows 11.

EDIT: AutoHotkey is an advanced Windows app for implementing user-defined hotkeys. The user configures the key combinations to use, and the action to perform when a hotkey is pressed. I've configured AutoHotkey for the same hotkeys and actions as in my application and tested it on a Windows 11 PC. AutoHotkey's behavior is the same as that of my application: injecting text works fine in all tested apps but Notepad.

Moreover, the behavior I observe now is different. The whole string comes out intermittently, two characters at a time, seemingly at the rate of cursor blinks.

0

There are 0 best solutions below