博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在VC中使用SendInput函数实现中文的自动输入
阅读量:6073 次
发布时间:2019-06-20

本文共 2527 字,大约阅读时间需要 8 分钟。

   很早以前写了一个刷卡程序,功能是定时监控读卡器,当发现有IC卡放到读卡器上后,自动识别出卡号,然后带着这个卡号搜索一个英文用户名和卡号的对照表,最后把英文用户名直接自动输入到当前光标所在的位置。本来程序一直用得好好的,可是最近遇到了一个新问题——因为用户名现在居然可以用中文了!所以这下麻烦大了……

   原先实现英文的自动输入,用的是keybd_event函数,直接模拟键盘事件。但是要输入中文,貌似没有输入法还是不行,难道还要我先用keybd_event调出输入法,然后输入拼音?这个思路想想就很恐怖,所以赶紧就上网搜解决方案去了。可是搜了一圈下来,只有寥寥几篇提到解决方案,虽然网上搜索结果众多,但是基本上就是这几个版本贴来贴去,浪费了我好多时间。

   不幸的事情还在后头,虽然有人提到SendInput函数可以输入中文,但是语焉不详,按照他提供的点滴的代码,我死活就是没有试出来。所以最后中文搜索的结果,除了认识了这个SendInput函数之外,没有更多的收获。后来不死心,换了英文搜索,还真找到了一个比较接近我需求的,老外写的VB版本的SendInput的例子,试验了以下,果然可以输入中文。大喜之下,决定花点时间研究一下人家的源代码,然后写一个VC的版本。

   摸索了两天之后,发现实现中文自动输入还真不难,因为SendInput确实支持,所以终于可以不用输入法了,万幸。特意整理了几个函数,共享一下。

   首先是,头文件必须包含以下两个:

#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: \b\b");
 }
}

转载地址:http://vmngx.baihongyu.com/

你可能感兴趣的文章
nagios+cacti+nrpe+nconf整合最后报错解决
查看>>
OGG运维优化脚本(十七)-信息同步类--配置备份
查看>>
关于计算机网络维护工作的若干思考
查看>>
MySQL的权限有哪些
查看>>
canvas 压缩图片上传
查看>>
linux下搭建基于Eclipse的arm的开发环境
查看>>
加密解密过程以及openssl自建CA
查看>>
CentOS 5.4 +apache 2.4.2 编译安装SVN服务器 neon (含所需软件包)
查看>>
RHEL6.3配置文件共享(2) autofs服务
查看>>
第 10 章 容器监控 - 083 - Prometheus 架构
查看>>
Linux RedHat 6.4 MySQL5.6源码包安装
查看>>
需要auth验证的post请求(python)
查看>>
Java IO2:RandomAccessFile
查看>>
Linux下软件的安装
查看>>
面向对象:继承
查看>>
Docker私有仓库--Harbor搭建
查看>>
我的友情链接
查看>>
js中的闭包简单总结
查看>>
恳求分页治理方法完成虚拟内存
查看>>
学习笔记--mysql5.7新版本
查看>>