我觉得很方便,可以使用SendInput将文本和控件混合为单个字符串,并将其发送到任何应用程序,例如
"\nHello\nWorld"
的结尾为
hit {Enter}
type "Hello"
hit {enter}
type "World"
在任何聊天应用程序中(例如)。
我有以下代码
void GenerateKey(WORD vk)
{
INPUT Input;
ZeroMemory(&Input, sizeof(Input));
Input.type = INPUT_KEYBOARD;
Input.ki.time = 0;
Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_UNICODE;
Input.ki.wVk = vk;
SendInput(1, &Input, sizeof(INPUT));
return;
}
void SendKeys(const LPCWSTR format, ...)
{
va_list args;
va_start(args, format);
WCHAR buffer[256];
vswprintf_s(buffer, format, args);
va_end(args);
BlockInput(true);
for (unsigned int i = 0; i<wcslen(buffer); ++i)
GenerateKey((WORD)VkKeyScan(buffer[i]));
BlockInput(false);
}
效果很好。但是问题是,这取决于当前使用的键盘布局。
我也尝试使用LoadKeyboardLayout,但以下内容完全无效
BlockInput(true);
HKL keyboard_layout = LoadKeyboardLayout("00000409", KLF_ACTIVATE);
for (unsigned int i = 0; i<wcslen(buffer); ++i)
GenerateKey((WORD)VkKeyScanExW(buffer[i], keyboard_layout));
BlockInput(false);
我也欢迎任何实现目标的想法。
SendMessage不能选择,因为它需要我获得窗口以及文本框的句柄。
答案 0 :(得分:2)
用SendInput()
调用cInputs==1
(几乎)始终是用户代码中的错误。不要做!与SendInput()
相比,使用keybd_event()
的主要好处之一是能够一次 atomical 原子提交一系列输入(因此,无需在以下情况下使用BlockInput()
全部)。
在这种情况下,为击键创建一个INPUT
的数组,然后仅调用SendInput()
1次。而且,对于KEYBDINPUT
documentation,KEYEVENTF_UNICODE
不会将虚拟键代码作为输入,而是会使用实际的Unicode文本字符(这意味着您不必手动处理键盘布局)。>
您也根本不会发送KEYEVENTF_KEYUP
事件。即使使用KEYEVENTF_UNICODE
,您也需要这些。
有关更多详细信息,请参见my previous answer至Sending Two or more chars using SendInput。
话虽如此,请尝试以下类似操作:
#include <vector>
#include <string>
void SendInputString(const std::wstring &str)
{
int len = str.length();
if (len == 0) return;
std::vector<INPUT> in(len*2);
ZeroMemory(&in[0], in.size()*sizeof(INPUT));
int i = 0, idx = 0;
while (i < len)
{
WORD ch = (WORD) str[i++];
if ((ch < 0xD800) || (ch > 0xDFFF))
{
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = ch;
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx] = in[idx-1];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
}
else
{
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = ch;
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = (WORD) str[i++];
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx] = in[idx-2];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
in[idx] = in[idx-2];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
}
}
SendInput(in.size(), &in[0], sizeof(INPUT));
}
void SendKeys(LPCWSTR format, ...)
{
std::wstring buffer;
va_list args;
va_start(args, format);
buffer.resize(_vscwprintf(format, args) + 1);
buffer.resize(vswprintf_s(&buffer[0], buffer.size(), format, args));
va_end(args);
SendInputString(buffer);
}