VC++模拟键盘输入(keybd_event() 、 PostMessage() /SendMessage()、SendInput())详解
扫描二维码
随时随地手机看文章
[摘要:VC摹拟键盘输进 找了一周,终究找到摹拟键盘输进的方式了,不外话道照样要看靠谱的开源项目,才干快速找到办理题目的方式啊,空话未几道,进进主题。 摹拟键盘的方式有三种(我]
VC++模拟键盘输入
找了一周,终于找到模拟键盘输入的方法了,不过话说还是要看靠谱的开源项目,才能快速找到解决问题的方法啊,废话不多说,进入主题。
模拟键盘的方法有三种(我只百度到三种,⊙﹏⊙b汗):keybd_event() 、 PostMessage() /SendMessage()、SendInput(),方法内的参数暂省略。。。
首先,keybd_event()方法原型:
VOID keybd_event(
BYTE bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWORD dwFlags, // flags specifying various function options
DWORD dwExtraInfo // additional data associated with keystroke
);
网上大部分流传的都是这么写的:(我想说就因为看到他们这么说的,然后我尝试了好多方式,都没有成功,只能说好吧,我的扫描码必须设置,我不一般可以了吧,囧!!)
)
最后幸亏看到tightvnc的源码才看到他们都是使用扫描码了,然后我尝试了一下:
//输入字符'A',通过,就这么通过了,对于一个菜鸟来说,我找的好辛苦!!至少花费了我两天时间
keybd_event(65,MapVirtualKey(0x41, 0),0,0);
Sleep(300);
keybd_event(65,MapVirtualKey(0x41, 0),KEYEVENTF_KEYUP,0);
其次,PostMessage()/SendMessage()方法原型:
B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
参数
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
(HWND_BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口。备注:需要以
HWND_BROADCAST方式通信的应用程序应当用函数 RegisterwindwosMessage来获得应用程序间通信的独特的消息。
NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样。)
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。
PostMessage()和SendMessage()是有区别的,前者是传到指定窗口句柄即可,类似于UDP传输协议,后者是传到指定句柄后,要一直等到其传送的参数被指定窗口收到,并且返回结果,类似于TCP传输协议。
俺用这个方法验证的是往TXT文本框输入内容:
//向txt文本窗口传送字符,成功
:: SendMessage(HWND(0x0004097E),WM_CHAR,WPARAM('a'),0); //发送一个字符a
说明HWND(0x0004097E)是获取TXT文本输入框的句柄(用VS2008 工具栏下的spy++获取到,再强制转型一下,强调一下,是输入框的句柄,而不是TXT的句柄——输入框的句柄是TXT文本框下面的一个子句柄,不太懂可以百度一下,主要是我没尝试就不介绍如何全部获取TXT文本内所有的句柄了,包括菜单栏句柄等等)
最后介绍一下SendInput的使用方法:
UINT SendInput(
UINT nInputs, // count of input events
LPINPUT pInputs, // array of input events
int cbSize // size of structure
);
此方法需要用到的数据结构INPUT,结构如下:
typedef struct tagINPUT {
DWORD type;
union {
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
} INPUT, *PINPUT;
SendInput方法可以模拟传输键盘和鼠标的功能。以键盘输入为例:
void inputKey()
{
::SetForegroundWindow(hWnd);//把接收窗口放在最前,同时使窗口获取焦点(好吧,说的像android,获取焦点。。。)
INPUT keyEvent = {0};
keyEvent.type = INPUT_KEYBOARD;//如果是鼠标设置鼠标的INPUT_MOUSE
keyEvent.ki.wVk = 0x41;//字符A
keyEvent.ki.wScan = MapVirtualKey(0x41, 0);//又像前面别人说的,可能一般不需要设置吧,我觉得还是这样靠谱,
//之前我没映射就没成功,不信你试试,you can you up!!
:: SendInput(1, &keyEvent, sizeof(keyEvent));
Sleep(1000); //别为为啥,就想让他睡会
keyEvent.ki.dwFlags = KEYEVENTF_KEYUP;//默认keyEvent.ki.dwFlags = 0 ,即 KEYEVENTF_KEYDOWN
::SendInput(1, &keyEvent, sizeof(keyEvent));
}
OK,就这些,花费了我一周多的时间啊,才弄好,希望可以帮助到需要的同志!!