C# 虚拟鼠标和键盘按键(三)【SendInput】

1. 概述

在前面两篇“C# 虚拟键盘按键(一)【SendKeys】”和“C# 虚拟键盘按键(二)【keybd_event】”文章中,我们讲了虚拟键盘按键的方法,它们只能虚拟键盘的按键操作,不能虚拟鼠标。本文介绍的Window API的SendInput函数,不仅能虚拟键盘,而且还能虚拟鼠标,同时微软用它取代了我们第二文章中说的keybd_event方法,所以相对来说功能更加丰富和先进,并且我们也能更多地了解一些键盘和鼠标的结构体和一些Window消息。

2. 说明

2.1 下面代码需要用到的引用是:

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
using System.Drawing;

代码有1000多行看起来比较多些,但实际上代码中前面的几个类和结构体是用作定义的。Window全部的鼠标键盘虚拟代码和Window系统配置,我把它们定义成VKCODE类和SystemMetricsHelper类,可以当字典参考。代码中真正用到的是最后一个类SendKeyboardMouse,我们只要用调用它就行。这个类我没有象第二篇文章介绍keybd_event函数中那样去继承VKCODE类,如果大家想做,可以自己去继承一下,这里就略过了。
2.2 键盘信息的结构体我没有做注释,我们看看大概就知道怎么用了。鼠标结构体虽然看起来简单,但是它比键盘相对麻烦,需要了解一些参数。所以我在鼠标结构体中给出了比较详细的注释,如果还不能解决大家的问题,可以参考微软的帮助文档。
2.3 SendKeyboardMouse类是我们直接使用的类,模拟键盘部分比较简单,有按下键,弹起(释放)键,以及敲击(按下后再释放)键三个方法。模拟鼠标部分共有模拟鼠标的滚轮运动,移动,带轨迹移动,左键按下,右键按下,左键弹起(释放),右键弹起,左键双击,右键双击九个方法。
注意:模拟鼠标左键按下,右键按下,左键弹起,右键弹起这四个方法的任何一个方法,都能激发Window的鼠标单击事件,左键双击,右键双击这两个方法之中的任何一个方法,同样都能激发Window的鼠标双击事件。

3. 代码

    #region 虚拟代码(键盘鼠标)
    public class VKCODE
    {
   
        public const byte VK_LBUTTON = 0x01;//鼠标左键
        public const byte VK_RBUTTON = 0x02;//鼠标右键
        public const byte VK_CANCEL = 0x03;//控制中断处理
        public const byte VK_MBUTTON = 0x04;//鼠标中键
        public const byte VK_XBUTTON1 = 0x05;//X1 鼠标按钮
        public const byte VK_XBUTTON2 = 0x06;//X2 鼠标按钮
        //public const byte VK_ = 0x07;//保留
        public const byte VK_BACK = 0x08;//BACKSPACE 键
        public const byte VK_TAB = 0x09;//Tab 键
        //public const byte VK_ = 0x0A;//预留
        //public const byte VK_ = 0x0B;//预留
        public const byte VK_CLEAR = 0x0C;//CLEAR 键
        public const byte VK_RETURN = 0x0D;//Enter 键
        //public const byte VK_ = 0x0E;//未分配
        //public const byte VK_ = 0x0F;//未分配
        public const byte VK_SHIFT = 0x10;//SHIFT 键
        public const byte VK_CONTROL = 0x11;//CTRL 键
        public const byte VK_MENU = 0x12;//Alt 键
        public const byte VK_PAUSE = 0x13;//PAUSE 键
        public const byte VK_CAPITAL = 0x14;//CAPS LOCK 键
        public const byte VK_KANA = 0x15;//IME Kana 模式
        public const byte VK_HANGUL = 0x15;//IME Hanguel 模式
        public const byte VK_IME_ON = 0x16;//IME 打开
        public const byte VK_JUNJA = 0x17;//IME Junja 模式
        public const byte VK_FINAL = 0x18;//IME 最终模式
        public const byte VK_HANJA = 0x19;//IME Hanja 模式
        public const byte VK_KANJI = 0x19;//IME Kanji 模式
        public const byte VK_IME_OFF = 0x1A;//IME 关闭
        public const byte VK_ESCAPE = 0x1B;//ESC 键
        public const byte VK_CONVERT = 0x1C;//IME 转换
        public const byte VK_NONCONVERT = 0x1D;//IME 不转换
        public const byte VK_ACCEPT = 0x1E;//IME 接受
        public const byte VK_MODECHANGE = 0x1F;//IME 模式更改请求
        public const byte VK_SPACE = 0x20;//空格键
        public const byte VK_PRIOR = 0x21;//PAGE UP 键
        public const byte VK_NEXT = 0x22;//PAGE DOWN 键
        public const byte VK_END = 0x23;//END 键
        public const byte VK_HOME = 0x24;//HOME 键
        public const byte VK_LEFT = 0x25;//LEFT ARROW 键
        public const byte VK_UP = 0x26;//UP ARROW 键
        public const byte VK_RIGHT = 0x27;//RIGHT ARROW 键
        public const byte VK_DOWN = 0x28;//DOWN ARROW 键
        public const byte VK_SELECT = 0x29;//SELECT 键
        public const byte VK_PRINT = 0x2A;//PRINT 键
        public const byte VK_EXECUTE = 0x2B;//EXECUTE 键
        public const byte VK_SNAPSHOT = 0x2C;//PRINT SCREEN 键
        public const byte VK_INSERT = 0x2D;//INS 键
        public const byte VK_DELETE = 0x2E;//DEL 键
        public const byte VK_HELP = 0x2F;//HELP 键
        public const byte VK_D0 = 0x30;//0 键
        public const byte VK_D1 = 0x31;//1 键
        public const byte VK_D2 = 0x32;//2 键
        public const byte VK_D3 = 0x33;//3 键
        public const byte VK_D4 = 0x34;//4 键
        public const byte VK_D5 = 0x35;//5 键
        public const byte VK_D6 = 0x36;//6 键
        public const byte VK_D7 = 0x37;//7 键
        public const byte VK_D8 = 0x38;//8 键
        public const byte VK_D9 = 0x39;//9 键
        //public const byte VK_ = 0x3A;//未定义
        //public const byte VK_ = 0x3B;//未定义
        //public const byte VK_ = 0x3C;//未定义
        //public const byte VK_ = 0x3D;//未定义
        //public const byte VK_ = 0x3E;//未定义
        //public const byte VK_ = 0x3F;//未定义
        //public const byte VK_ = 0x40;//未定义
        public const byte VK_A = 0x41;//A 键
        public const byte VK_B = 0x42;//B 键
        public const byte VK_C = 0x43;//C 键
        public const byte VK_D = 0x44;//D 键
        public const byte VK_E = 0x45;//E 键
        public const byte VK_F = 0x46;//F 键
        public const byte VK_G = 0x47;//G 键
        public const byte VK_H = 0x48;//H 键
        public const byte VK_I = 0x49;//I 键
        public const byte VK_J = 0x4A;//J 键
        public const byte VK_K = 0x4B;//K 键
        public const byte VK_L = 0x4C;//L 键
        public const byte VK_M = 0x4D;//M 键
        public const byte VK_N = 0x4E;//N 键
        public const byte VK_O = 0x4F;//O 键
        public const byte VK_P = 0x50;//P 键
        public const byte VK_Q = 0x51;//Q 键
        public const byte VK_R = 0x52;//R 键
        public const byte VK_S = 0x53;//S 键
        public const byte VK_T = 0x54;//T 键
        public const byte VK_U = 0x55;//U 键
        public const byte VK_V = 0x56;//V 键
        public const byte VK_W = 0x57;//W 键
        public const byte VK_X = 0x58;//X 键
        public const byte VK_Y = 0x59;//Y 键
        public const byte VK_Z = 0x5A;//Z 键
        public const byte VK_LWIN = 0x5B;//左 Windows 键
        public const byte VK_RWIN = 0x5C;//右侧 Windows 键
        public const byte VK_APPS = 0x5D;//应用程序密钥
        //public const byte VK_ = 0x5E;//预留
        public const byte VK_SLEEP = 0x5F;//计算机休眠键
        public const byte VK_NUMPAD0 = 0x60;//数字键盘 0 键
        public const byte VK_NUMPAD1 = 0x61;//数字键盘 1 键
        public const byte VK_NUMPAD2 = 0x62;//数字键盘 2 键
        public const byte VK_NUMPAD3 = 0x63;//数字键盘 3 键
        public const byte VK_NUMPAD4 = 0x64;//数字键盘 4 键
        public const byte VK_NUMPAD5 = 0x65;//数字键盘 5 键
        public const byte VK_NUMPAD6 = 0x66;//数字键盘 6 键
        public const byte VK_NUMPAD7 = 0x67;//数字键盘 7 键
        public const byte VK_NUMPAD8 = 0x68;//数字键盘 8 键
        public const byte VK_NUMPAD9 = 0x69;//数字键盘 9 键
        public const byte VK_MULTIPLY = 0x6A;//乘号键
        public const byte VK_ADD = 0x6B;//加号键
        public const byte VK_SEPARATOR = 0x6C;//分隔符键
        public const byte VK_SUBTRACT = 0x6D;//减号键
        public const byte VK_DECIMAL = 0x6E;//句点键
        public const byte VK_DIVIDE = 0x6F;//除号键
        public const byte VK_F1 = 0x70;//F1 键
        public const byte VK_F2 = 0x71;//F2 键
        public const byte VK_F3 = 0x72;//F3 键
        public const byte VK_F4 = 0x73;//F4 键
        public const byte VK_F5 = 0x74;//F5 键
        public const byte VK_F6 = 0x75;//F6 键
        public const byte VK_F7 = 0x76;//F7 键
        public const byte VK_F8 = 0x77;//F8 键
        public const byte VK_F9 = 0x78;//F9 键
        public const byte VK_F10 = 0x79;//F10 键
        public const byte VK_F11 = 0x7A;//F11 键
        public const byte VK_F12 = 0x7B;//F12 键
        public const byte VK_F13 = 0x7C;//F13 键
        public const byte VK_F14 = 0x7D;//F14 键
        public const byte VK_F15 = 0x7E;//F15 键
        public const byte VK_F16 = 0x7F;//F16 键
        public const byte VK_F17 = 0x80;//F17 键
        public const byte VK_F18 = 0x81;//F18 键
        public const byte VK_F19 = 0x82;//F19 键
        public const byte VK_F20 = 0x83;//F20 键
        public const byte VK_F21 = 0x84;//F21 键
        public const byte VK_F22 = 0x85;//F22 键
        public const byte VK_F23 = 0x86;//F23 键
        public const byte VK_F24 = 0x87;//F24 键
        //public const byte VK_ = 0x88;//保留
        //public const byte VK_ = 0x89;//保留
        //public const byte VK_ = 0x8A;//保留
        //public const byte VK_ = 0x8B;//保留
        //public const byte VK_ = 0x8C;//保留
        //public const byte VK_ = 0x8D;//保留
        //public const byte VK_ = 0x8E;//保留
        //public const byte VK_ = 0x8F;//保留
        public const byte VK_NUMLOCK = 0x90;//NUM LOCK 键
        public const byte VK_SCROLL = 0x91;//SCROLL LOCK 键
        //public const byte VK_ = 0x92;//OEM 特有
        //public const byte VK_ = 0x93;//OEM 特有
        //public const byte VK_ = 0x94;//OEM 特有
        //public const byte VK_ = 0x95;//OEM 特有
        //public const byte VK_ = 0x96;//OEM 特有
        //public const byte VK_ = 0x97;//未分配
        //public const byte VK_ = 0x98;//未分配
        //public const byte VK_ = 0x99;//未分配
        //public const byte VK_ = 0x9A;//未分配
        //public const byte VK_ = 0x9B;//未分配
        //public const byte VK_ = 0x9C;//未分配
        //public const byte VK_ = 0x9D;//未分配
        //public const byte VK_ = 0x9E;//未分配
        //public const byte VK_ = 0x9F;//未分配
        public const byte VK_LSHIFT = 0xA0;//左 SHIFT 键
        public const byte VK_RSHIFT = 0xA1;//右 SHIFT 键
        public const byte VK_LCONTROL = 0xA2;/
模拟鼠标键盘 注意:不支持Windows 8 / 8.1。 Interceptor是Windows键盘驱动程序的包装器(包装http://oblita.com/Interception)。 使用驱动程序,Interceptor可以模拟按键鼠标点击... 使用DirectX的游戏,通常不接受使用SendInput()的击键 Windows的受保护区域,如Windows登录屏幕或UAC调暗屏幕 任何应用程序 因为驱动程序模拟击键鼠标单击,所以目标窗口必须处于活动状态(即,在发送击键鼠标点击时,不能在另一个窗口上执行多任务)。 如何使用 下载并构建此项目并在项目中引用其DLL。 下载'interception.dll',这是一个由驱动程序作者编写的独立库。将它放在与可执行文件相同的目录中。这是必需的。 从作者的网页下载并安装“install-interception.exe”。安装后重新启动计算机。 在您的代码中,要加载驱动程序,请调用(阅读下面的代码注释;您必须设置过滤模式以捕获按键事件或发送按键操作!): Input input = new Input(); // Be sure to set your keyboard filter to be able to capture key presses and simulate key presses // KeyboardFilterMode.All captures all events; 'Down' only captures presses for non-special keys; 'Up' only captures releases for non-special keys; 'E0' and 'E1' capture presses/releases for special keys input.KeyboardFilterMode = KeyboardFilterMode.All; // You can set a MouseFilterMode as well, but you don't need to set a MouseFilterMode to simulate mouse clicks // Finally, load the driver input.Load(); 做你的东西。 input.MoveMouseTo(5, 5); // Please note this doesn't use the driver to move the mouse; it uses System.Windows.Forms.Cursor.Position input.MoveMouseBy(25, 25); // Same as above ^ input.SendLeftClick(); input.KeyDelay = 1; // See below for explanation; not necessary in non-game apps input.SendKeys(Keys.Enter); // Presses the ENTER key down and then up (this constitutes a key press) // Or you can do the same thing above using these two lines of code input.SendKeys(Keys.Enter, KeyState.Down); Thread.Sleep(1); // For use in games, be sure to sleep the thread so the game can capture all events. A lagging game cannot process input quickly, and you so you may have to adjust this to as much as 40 millisecond delay. Outside of a game, a delay of even 0 milliseconds can work (instant key presses). input.SendKeys(Keys.Enter, KeyState.Up); input.SendText("hello, I am typing!"); /* All these following characters / numbers / symbols work */ input.SendText("abcdefghijklmnopqrstuvwxyz"); input.SendText("1234567890"); input.SendText("!@#$%^&*()"); input.SendText("[]\\;',./"); input.SendText("{}|:\"?"); // And finally input.Unload(); 笔记: BadImageFormatException如果您没有为解决方案中的所有项目(包括此项目)使用正确的体系结构(x86或x64),则可能会获得。因此,您可能必须下载此项目的源代码才能将其重建为正确的体系结构。这应该很简单,构建过程应该没有错误。 您必须从http://oblita.com/Interception下载'interception.dll' 。 如果你已经完成了以上所有操作(正确安装了拦截驱动程序,将interception.dll放在你的项目文件夹中),你仍然无法发送击键: 驱动程序有一个限制,即它不能在不接收至少一次击键的情况下发送击键。这是因为驱动程序不知道键盘是哪个设备ID,因此它必须等待接收击键以从击键中推断出设备ID。 总之,在发送击键之前,请始终按键盘一次。点按任意键。然后你可以发送击键。这不适用于接收击键,因为通过接收击键,您当然已经按下了一个键。 MoveMouseTo()MoveMouseBy()完全忽略键盘驱动程序。它使用System.Windows.Forms.Position来设置获取游标的位置(它为下面的各个函数调用标准的Win32 API)。 原因是,在探索键盘驱动程序的鼠标移动功能时,我注意到它没有按像素单位移动光标,而是似乎通过加速移动光标。当我想将光标移动到某个位置时,这会不断产生不一致的值。因为Win32游标设置API通常不被游戏等阻止,所以我发现只需调用这些标准API即可,而无需使用驱动程序。请注意,这仅适用于设置光标位置。拦截光标仍然可以正常工作。例如,您可以使用Interceptor反转鼠标的xy轴。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值