c - 如何使用 SendInput() 指定 kbd 修饰符?

标签 c winapi keyboard-events

我正在使用 Windows API SendInput() 调用来模拟键盘事件。以下代码片段(省略不相关的细节)非常适合发送字符序列:

wchar_t txt = ...;
INPUT *input = ...;
size_t nInput = 0;

for (unsigned int j = 0; j < length; j++) {
    input[nInput].ki.wVk = 0;
    input[nInput].ki.wScan = txt[j];
    input[nInput].ki.dwFlags = KEYEVENTF_UNICODE;
    nInput++;
    input[nInput].ki.wVk = 0;
    input[nInput].ki.wScan = txt[j];
    input[nInput].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
    nInput++;
}
SendInput(nInput, input, sizeoF(INPUT));

现在我正在尝试发送带有修饰符的单个按键。我尝试了以下代码:

bool control, alt shift;
wchar_t chr;

if (control) {
    input[nInput].ki.wVk = VK_CONTROL;
    input[nInput].ki.dwFlags = 0;
    nInput++;
}
if (alt) {
    input[nInput].ki.wVk = VK_MENU;
    input[nInput].ki.dwFlags = 0;
    nInput++;
}
if (shift) {
    input[nInput].ki.wVk = VK_SHIFT;
    input[nInput].ki.dwFlags = 0;
    nInput++;
}

input[nInput].ki.wVk = 0;
input[nInput].ki.wScan = chr;
input[nInput].ki.dwFlags = KEYEVENTF_UNICODE;
nInput++;
input[nInput].ki.wVk = 0;
input[nInput].ki.wScan = chr;
input[nInput].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
nInput++;

if (shift) {
    input[nInput].ki.wVk = VK_SHIFT;
    input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
    nInput++;
}
if (alt) {
    input[nInput].ki.wVk = VK_MENU;
    input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
    nInput++;
}
if (control) {
    input[nInput].ki.wVk = VK_CONTROL;
    input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
    nInput++;
}
SendInput(nInput, input, sizeof(INPUT));

但是,修饰符似乎无法通过,即,即使将 control 设置为 true,事件序列也会作为普通按键接收。

最佳答案

Pax's answer没有成功,但它引导我找到了正确的解决方案。简而言之:不要对单个按键使用 KEYEVENTF_UNICODE ,而是将字符转换为虚拟键代码,并以这种方式发送。相关代码如下:

SHORT virtKey = VkKeyScan((TCHAR) chr);
input[nInput].ki.wVk = LOBYTE(virtKey);
input[nInput].ki.dwFlags = 0;
nInput++;
input[nInput].ki.wVk = LOBYTE(virtKey);
input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
nInput++;

我还没有测试这对于映射到非英语键盘布局的非 ASCII unicode 字符如何工作,以及当我的应用程序的布局集与前面的应用程序的布局集不同时会发生什么。

关于c - 如何使用 SendInput() 指定 kbd 修饰符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/661817/

相关文章:

c - pthread_mutex_lock 和 pthread_cond_wait/signal 导致死锁

c++ - 如果Spark的数据会在堆外缓存,它会有字节级规范吗?

c++ - 在同一个套接字上调用 shutdown 和 closesocket 两次

c++ - 递归同步

c - memcpy 遇到问题

c - 修改linux内核后编译速度慢

c++ - Windows:如何让子进程在不关闭输入匿名管道的情况下读取它?

c++ - 控制台键盘按下检测库或标准选项?

delphi - 为什么我的表单的 OnKeyDown 事件处理程序没有触发?

javascript - 按下键时显示弹出窗口