我已经实现了一个钩子过程,可以捕获一些
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
。
而且,我现在观察到的行为有所不同。整个字符串间歇性地出现,一次两个字符,似乎以光标闪烁的速度。
但是,当将字符串注入记事本时,程序会表现出无法解释的行为。仅显示 2-4 个字符,按下键盘上的其他键时会出现其余字符,每个键按下后都会出现几个字符。
这似乎是核心问题。您找到解决方案了吗?我有更简单的脚本,仅在新的 Windows 11 记事本中表现出这种非常奇怪的行为。
示例:
!^t:: { ;Type Time (formatted)
HotkeySleepWithCtrlAltRelease()
TimeString := FormatTime(,"M/d/yyyy h:mm tt")
SendText(TimeString)
}
(抱歉,我知道,不是答案;但没有足够的“声誉”来向OP发表评论)