首页 > 编程语言 >VC++模拟键盘输入(keybd_event() 、 PostMessage() /SendMessage()、SendInput())详解

VC++模拟键盘输入(keybd_event() 、 PostMessage() /SendMessage()、SendInput())详解

时间:2022-11-24 16:49:11浏览次数:51  
标签:PostMessage 窗口 keyEvent 句柄 SendInput SendMessage keybd event

                                                                             VC++模拟键盘输入


找了一周,终于找到模拟键盘输入的方法了,不过话说还是要看靠谱的开源项目,才能快速找到解决问题的方法啊,废话不多说,进入主题。

原文出处:http://blog.csdn.net/entre_/article/details/46444487

模拟键盘的方法有三种(我只百度到三种,⊙﹏⊙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,就这些,花费了我一周多的时间啊,才弄好,希望可以帮助到需要的同志!!(原文出处:http://blog.csdn.net/entre_/article/details/46444487)








  

标签:PostMessage,窗口,keyEvent,句柄,SendInput,SendMessage,keybd,event
From: https://www.cnblogs.com/lidabo/p/16922325.html

相关文章