如何使用SendInput()函数发送超过2字节的Unicode字符?
解决SendInput发送超出2字节Unicode字符的问题
对于U+1D495这类超出基本多语言平面(BMP,U+0000到U+FFFF)的Unicode字符,Windows需要通过UTF-16代理对来处理,你需要把单个32位字符拆分为两个16位的代理码元,分别模拟按键的按下和释放事件。
具体步骤
- 拆分代理对:将UTF-32字符转换为对应的高代理(Surrogate High)和低代理(Surrogate Low)。以U+1D495为例:
- 高代理值:
0xD835 - 低代理值:
0xDC95
- 高代理值:
- 构造INPUT事件:每个代理码元需要单独发送
KEYDOWN和KEYUP事件,总共需要4个INPUT结构体。
完整代码示例
#include <Windows.h> void SendUnicodeChar(wchar_t highSurrogate, wchar_t lowSurrogate) { INPUT inputs[4] = {0}; // 发送高代理按下事件 inputs[0].type = INPUT_KEYBOARD; inputs[0].ki.dwFlags = KEYEVENTF_UNICODE; inputs[0].ki.wScan = highSurrogate; // 发送高代理释放事件 inputs[1].type = INPUT_KEYBOARD; inputs[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; inputs[1].ki.wScan = highSurrogate; // 发送低代理按下事件 inputs[2].type = INPUT_KEYBOARD; inputs[2].ki.dwFlags = KEYEVENTF_UNICODE; inputs[2].ki.wScan = lowSurrogate; // 发送低代理释放事件 inputs[3].type = INPUT_KEYBOARD; inputs[3].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; inputs[3].ki.wScan = lowSurrogate; // 执行输入 SendInput(_countof(inputs), inputs, sizeof(INPUT)); } int main() { // 拆分U+1D495为代理对 wchar_t high = 0xD835; wchar_t low = 0xDC95; SendUnicodeChar(high, low); return 0; }
补充说明
- 代理对的通用计算规则:对于UTF-32值
U(U > 0xFFFF),高代理 =0xD800 + ((U - 0x10000) >> 10),低代理 =0xDC00 + ((U - 0x10000) & 0x3FF)。你可以封装成通用函数自动拆分任意UTF-32字符。 - 不推荐用
SendMessage直接发WM_CHAR模拟输入,这种方式无法触发部分依赖键盘硬件事件的应用逻辑,SendInput模拟的是真实键盘输入流程,兼容性更好。
内容的提问来源于stack exchange,提问作者benwu93
相关产品推荐
相关产品推荐

