C++学习笔记之SendInput()模拟键盘输入的问题
2017-10-15 17:15
579 查看
写在前面
本人刚入C++开发,有很多也是不懂。在网上找了一个模拟键盘输入的代码,结果输入中文没问题,输入英文却导致字符被中文输入法的框给截了,加上翻墙软件貌似又被截了一大波,真尼玛日了天美了。正文部分
正确的做法就是将字符转换为UNICODE编码即可。以下来自于某博客的摘抄:
那么,有没有不依赖活动窗口输入法状态的方式呢?
其实是有的,使用SendInput模拟键盘输入时,其参数是KEYBDINPUT结构,通过将其dwFlags成员设置KEYEVENTF_UNICODE就可以了。使用此方式,只需将KEYBDINPUT.wScan设置为字符的Unicode编码即可。对于英文字符,不需要关闭活动窗口的输入法;对于中文字符,也不要求活动窗口打开输入法和将字符转换为输入法编码。
相关代码看这里:
INPUT input[2]; 20 memset(input, 0, sizeof(input)); 21 //按下 向下方向键 22 input[0].ki.wVk = keyvalue; 23 input[0].type = INPUT_KEYBOARD; 24 //松开 向下方向键 25 input[1].ki.wVk = data; //你的字符 26 input[1].type = INPUT_KEYBOARD; 27 input[1].ki.dwFlags = KEYEVENTF_KEYUP; 28 //该函数合成键盘事件和鼠标事件,用来模拟鼠标或者键盘操作。事件将被插入在鼠标或者键盘处理队列里面 29 SendInput(2, input, sizeof(INPUT));
完整程序:
首先是,头文件必须包含以下两个: #include <winable.h> #include <atlconv.h> 前者是SendInput函数要用到,后者是字符串转换的时候要用到。 void SendAscii(wchar_t data, BOOL shift) { INPUT input[2]; memset(input, 0, 2 * sizeof(INPUT)); if (shift) { input[0].type = INPUT_KEYBOARD; input[0].ki.wVk = VK_SHIFT; SendInput(1, input, sizeof(INPUT)); } input[0].type = INPUT_KEYBOARD; input[0].ki.wVk = data; input[1].type = INPUT_KEYBOARD; input[1].ki.wVk = data; input[1].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(2, input, sizeof(INPUT)); if (shift) { input[0].type = INPUT_KEYBOARD; input[0].ki.wVk = VK_SHIFT; input[0].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, input, sizeof(INPUT)); } } void SendUnicode(wchar_t data) { INPUT input[2]; memset(input, 0, 2 * sizeof(INPUT)); input[0].type = INPUT_KEYBOARD; input[0].ki.wVk = 0; input[0].ki.wScan = data; input[0].ki.dwFlags = 0x4;//KEYEVENTF_UNICODE; input[1].type = INPUT_KEYBOARD; input[1].ki.wVk = 0; input[1].ki.wScan = data; input[1].ki.dwFlags = KEYEVENTF_KEYUP | 0x4;//KEYEVENTF_UNICODE; SendInput(2, input, sizeof(INPUT)); } //为方便使用,下面这个函数包装了前两个函数。 void SendKeys(CString msg) { short vk; BOOL shift; USES_CONVERSION; wchar_t* data = T2W(msg.GetBuffer(0)); int len = wcslen(data); for(int i=0;i<len;i++) { if (data[i]>=0 && data[i]<256) //ascii字符 { vk = VkKeyScanW(data[i]); if (vk == -1) { SendUnicode(data[i]); } else { if (vk < 0) { vk = ~vk + 0x1; } shift = vk >> 8 & 0x1; if (GetKeyState(VK_CAPITAL) & 0x1) { if (data[i]>='a' && data[i]<='z' || data[i]>='A' && data[i]<='Z') { shift = !shift; } } SendAscii(vk & 0xFF, shift); } } else //unicode字符 { SendUnicode(data[i]); } } } 直接调用SendKeys函数就可以在当前光标的位置自动输入指定的字符串,下面的例子演示了如何自动打开记事本程序并输入一段话: void CSendInputDlg::OnTest() { ShellExecute(NULL, NULL, "notepad.exe", NULL, NULL, SW_SHOWNORMAL); Sleep(500); //为了确保记事本程序打开完毕,稍等片刻 CWnd *pWnd = FindWindow(NULL, "无标题 - 记事本"); if (pWnd) { pWnd->SetForegroundWindow(); SendKeys("我是sway,我爱中国!\nI love China!\nEmail: xmujava@163.com\t\n2010-05-21 \b\b"); } }
相关文章推荐
- SendInput模拟键盘输入的问题
- SendInput模拟键盘输入的问题 <转>
- SendInput模拟键盘输入的问题
- SendInput模拟键盘输入的问题
- SendInput模拟键盘输入的问题
- SendInput模拟键盘输入的问题
- WPF and Silverlight 学习笔记(十四):键盘输入、鼠标输入、焦点处理[转]
- keybd_event函数模拟键盘输入的问题
- Java学习笔记8:用键盘输入1~9,列出相对应的乘法口诀
- WPF and Silverlight 学习笔记(十四):键盘输入、鼠标输入、焦点处理
- C++ Standard Stl -- SGI STL源码学习笔记(06) stl_vector 与 一些问题的细化 2 push_back函数剖析
- 【菜鸟C++学习笔记】24. 常见的引用注意问题
- IOS学习笔记 ­­­­­­— UITextField 输入完毕关闭键盘方法
- IOS学习笔记36—解决键盘遮挡输入框(UITextField)问题
- C++学习笔记--标准输入输出
- WPF and Silverlight 学习笔记(十四):键盘输入、鼠标输入、焦点处理
- 王爽《汇编语言》(第二版) 学习笔记 (第十七章 使用BIOS进行键盘输入和磁盘读写)
- <寒江独钓>学习笔记 -- 第四章 Hook分发函数 过滤键盘输入
- WPF and Silverlight 学习笔记:键盘输入、鼠标输入、焦点处理
- C++学习笔记之输入和输出