SendInput() 并不是“发送”正确的移位字符?

发布于 2024-08-19 12:30:58 字数 379 浏览 9 评论 0原文

void WriteChar(char c)
{
    INPUT input = {0};
    input.type = INPUT_KEYBOARD;
    input.ki.wVk= VkKeyScanEx(c, GetKeyboardLayout(0) ) ;   
    SendInput(1,&input, sizeof(INPUT));
}

VkKeyScanEx 对“/”和“?”(相同的键)返回不同的键码,但是如果您尝试使用此方法写入包含“?”的消息,它只会写入“/”。我不知道发生了什么事。 ';' 也会发生同样的情况和 ':'。

我部分不理解按键代码和扫描代码。大多数字符都有虚拟键码,但是我找不到类似的问号。它们必须存在,但未列出?

void WriteChar(char c)
{
    INPUT input = {0};
    input.type = INPUT_KEYBOARD;
    input.ki.wVk= VkKeyScanEx(c, GetKeyboardLayout(0) ) ;   
    SendInput(1,&input, sizeof(INPUT));
}

VkKeyScanEx returns different key codes for '/' and '?'(same key), however if you try using this method to write a message containing '?', it will only write '/'. I don't know what's going on. Same thing occurs with ';' and ':'.

I partly don't understand key codes and scan codes. Most characters have a virtual key code, however I can't find something similar for question marks. They must exist, but aren't listed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花之痕靓丽 2024-08-26 12:30:58

扫描码是从键盘返回的原始键 ID。因此,101 个键的键盘(理论上)将有 101 个可以返回的唯一扫描代码。 (参见脚注1

虚拟键码是一组单独的代码,代表理想键盘上的键。无论 TAB 键在真实键盘上的哪个位置,以及使用什么扫描码,虚拟键码始终是 VK_TAB。 windows.h定义了不可打印虚拟键的VK_xxx代码,对于可打印虚拟键,虚拟键代码与ASCII值相同。

但虚拟键码仍然是键码。 “A”和“a”具有相同的虚拟键码,因此如果您想发送“A”,则必须向下发送 VK_SHIFT,然后向下发送“a”,然后向上发送“a”,然后向上发送 VK_SHIFT。

VkKeyScanEx() 将字符转换为扫描键和转换状态 请参阅本页下面的引用 http://msdn.microsoft.com/en-us/library/ms646332(VS.85).aspx

如果函数成功,返回值的低位字节包含虚拟键代码,高位字节包含移位状态,可以是以下标志位的组合。

因此,您不能只获取 VkKeyScanEx() 的返回值,您需要检查它是否标记了 Shift 键。并将 Shift 键作为单独的击键发送。

SHORT vk = VkKeyScanEx(c, ...);
if (vk & 0x100) // check upper byte for shift flag
{
   // send a shift key down
}
if (vk & 0x200) // check for ctrl flag
{
   // send a ctrl key down
}
input.ki.wVk = vk & 0xFF;

// send keyup for each of the keydown

您还必须为每次按键发送一个按键向上。

脚注:

1这仅是理论上的,实际上标准 PC 键盘会模拟您甚至无法再获得的旧 IBM 键盘,因此某些键可以根据另一个键返回 2 个不同的扫描代码,而其他情况下两个按键可以返回相同的扫描码。

Scan codes are the raw key ids returned from the keyboard. So a 101 key keyboard will (in theory) have 101 unique scan codes that it can return. (see footnote 1)

Virtual key codes are a separate set of codes that represent an key on an idealized keyboard. No matter where on a real keyboard the TAB key is, and what scancode is used for it, the virtual key code is always VK_TAB. windows.h defines VK_xxx codes for non-printable virtual keys, for the printable ones, the virtual key code is the same as the ASCII value.

But virtual key codes are still key codes. 'A' and 'a' have the same virtual key code, so if you want to send an 'A' then you have to send a VK_SHIFT down, then 'a' down, then 'a' up, then VK_SHIFT up.

VkKeyScanEx() converts a character into a scan key and shift state See the quote below from this page http://msdn.microsoft.com/en-us/library/ms646332(VS.85).aspx

If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains the shift state, which can be a combination of the following flag bits.

So you can't just take the return from VkKeyScanEx(), you need to check to see if it has a shift key flagged. and send the shift key as a separate keystroke

SHORT vk = VkKeyScanEx(c, ...);
if (vk & 0x100) // check upper byte for shift flag
{
   // send a shift key down
}
if (vk & 0x200) // check for ctrl flag
{
   // send a ctrl key down
}
input.ki.wVk = vk & 0xFF;

// send keyup for each of the keydown

You also have to send a keyup for every keydown.

Footnotes:

1 This is in theory only, in practice standard PC keyboards emulate a old IBM keyboard that you can't even get anymore, so some keys can return 2 different scan codes based on another key, while other in other cases two keys can return the same scan code.

┊风居住的梦幻卍 2024-08-26 12:30:58

尝试这样做。如果您使用 KEYEVENTF_UNICODE 执行此操作,则主机平台至少需要为 Windows 2000 或 XP。

INPUT input[ 2 ];

input[ 0 ].type = INPUT_KEYBOARD;
input[ 0 ].ki.wVk = 0;
input[ 0 ].ki.wScan = c;
input[ 0 ].ki.dwFlags = KEYEVENTF_UNICODE;
input[ 0 ].ki.time = 0;
input[ 0 ].ki.dwExtraInfo = GetMessageExtraInfo();

input[ 1 ].type = INPUT_KEYBOARD;
input[ 1 ].ki.wVk = 0;
input[ 1 ].ki.wScan = c;
input[ 1 ].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
input[ 1 ].ki.time = 0;
input[ 1 ].ki.dwExtraInfo = GetMessageExtraInfo();

SendInput( ( UINT )2, input, sizeof( *input ) );

从您没有正确填写输入结构并且未初始化一些必需的成员这一事实来看,我假设您还没有看到这方面的文档。请参阅 SendInput输入KEYBDINPUT

Try doing it like this. If you do it using KEYEVENTF_UNICODE, the host platform will need to be at least Windows 2000 or XP.

INPUT input[ 2 ];

input[ 0 ].type = INPUT_KEYBOARD;
input[ 0 ].ki.wVk = 0;
input[ 0 ].ki.wScan = c;
input[ 0 ].ki.dwFlags = KEYEVENTF_UNICODE;
input[ 0 ].ki.time = 0;
input[ 0 ].ki.dwExtraInfo = GetMessageExtraInfo();

input[ 1 ].type = INPUT_KEYBOARD;
input[ 1 ].ki.wVk = 0;
input[ 1 ].ki.wScan = c;
input[ 1 ].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
input[ 1 ].ki.time = 0;
input[ 1 ].ki.dwExtraInfo = GetMessageExtraInfo();

SendInput( ( UINT )2, input, sizeof( *input ) );

Judging from the fact that you didn't fill out your input structure correctly and left some required members uninitialised, I'd assume you haven't seen the documentation for this. See SendInput, INPUT and KEYBDINPUT.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文