SendInput() 在记事本中出现故障

问题描述 投票:0回答:1

我已经实现了一个钩子过程,可以捕获一些

Alt+letter
组合键并注入预定义的字符串。挂钩过程的示例如下所示。它使用 WinAPI 函数
LeftAlt+Q
检测热键
LeftAlt+A
ABCD1234
并在两种情况下注入字符串
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);
}

钩子程序是使用函数

SetWindowsHookExW()
安装的。

该程序在广泛的应用中按预期工作。我已经使用 WordPad、Notepad++、Chrome、Edge、命令提示符、PowerShell 和 Visual Studio 对其进行了测试。但是,当将字符串注入记事本时,程序会表现出无法解释的行为。仅显示 2-4 个字符,按下键盘上的其他键时会出现其余字符,每个键按下后都会出现几个字符。

这种行为是新的。几周前我在开发过程中使用记事本测试了这个程序,记事本工作得很好。我在多台电脑上使用这个程序,其中一些工作没有问题。所有电脑都使用 Windows 11。

编辑

AutoHotkey
是一个高级Windows应用程序,用于实现用户定义的热键。用户配置要使用的组合键以及按下热键时要执行的操作。我已将
AutoHotkey
配置为与我的应用程序中相同的热键和操作,并在 Windows 11 PC 上对其进行了测试。
AutoHotkey's
行为与我的应用程序相同:注入文本在所有测试的应用程序中都可以正常工作,但
Notepad

而且,我现在观察到的行为有所不同。整个字符串间歇性地出现,一次两个字符,似乎以光标闪烁的速度。

windows visual-studio winapi visual-c++ sendinput
1个回答
0
投票

但是,当将字符串注入记事本时,程序会表现出无法解释的行为。仅显示 2-4 个字符,按下键盘上的其他键时会出现其余字符,每个键按下后都会出现几个字符。

这似乎是核心问题。您找到解决方案了吗?我有更简单的脚本,仅在新的 Windows 11 记事本中表现出这种非常奇怪的行为。

示例:

!^t:: { ;Type Time (formatted)
    HotkeySleepWithCtrlAltRelease()
    TimeString := FormatTime(,"M/d/yyyy h:mm tt")
    SendText(TimeString)
    }

(抱歉,我知道,不是答案;但没有足够的“声誉”来向OP发表评论)

© www.soinside.com 2019 - 2024. All rights reserved.