65.9K
CodeProject 正在变化。 阅读更多。
Home

InputManager 库 - 跟踪用户输入并模拟输入(鼠标和键盘)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (37投票s)

2010年10月13日

CPOL

5分钟阅读

viewsIcon

336066

downloadIcon

24300

一个包含用于模拟用户输入和跟踪用户输入(鼠标和键盘)的类的库,使用 C# 和 VB.NET 编写。

引言

InputManager 库允许您完全控制用户的所有常见输入。从跟踪(挂钩)用户输入到模拟用户输入。它允许您在一个易于使用的库中发送和接收全局鼠标和键盘消息。它支持 DirectX 输入模拟,这意味着您可以将鼠标或键盘消息发送到您想要的任何 DirectX 游戏,并且游戏将正确地将其注册。

使用此库,您可以创建一个完整的宏录制应用程序;它文档齐全,并且可以轻松地与任何应用程序一起使用。

背景

在开始创建我自己的宏录制应用程序(今天称为 Mouse Recorder Pro)的旅程中,我需要找到一种方法来注册鼠标和键盘消息并跟踪它们。在 Mouse Recorder Pro 的多次版本更新后,以及在我自己的编码技能提高之后,我创建了这个库来帮助他人。

该库中的挂钩类不是我写的(但经过我修改),说实话。我不记得帮助过它的人是谁,但如果我能找到他,我会更新这篇文章。

其他类是我写的,经过一些研究和大量阅读。我遇到的主要问题是能够注册 DirectX 游戏中的用户输入,后来我成功地解决了这个问题。

概念(或者,它是如何工作的)

该库是用 VB.NET 编写的,并在许多系统上进行了测试(作为其在 Mouse Recorder Pro 商业应用程序中的一部分使用)。

键盘和鼠标消息是使用 SendInput API 发送的,这比其他 API 更灵活。使用 SendInput API,您的应用程序可以以低级别(如 DirectX)发送鼠标和键盘消息。这允许您在任何 DirectX 游戏中注册这些消息。

鼠标和键盘挂钩类允许您跟踪用户输入。这些类使用 SetWindowsHookEx API。此 API 将任何新的鼠标或键盘消息“绑定”到挂钩类中的特定方法。每次有新消息到达时,Windows 都会调用该方法。在该方法中,会引发一个事件以通知您有新的输入消息到达。

Screenshot.jpg

Mouse Recorder Pro 2 - 它使用了 InputManager 库!

使用代码

要使用此库,我们首先需要在我们的项目中添加一个对它的引用;从上面的链接下载 InputManager 库,并将其解压缩。现在执行以下操作

  1. 打开您的项目。
  2. 右键单击“References”并选择“Add Reference”。
  3. 选择“Browse”选项卡,然后选择解压缩的“InputManager.dll”。
  4. 接受所有对话框。
  5. 为了让此项目在 Debug 模式下工作,请双击 Properties,然后转到“Debug”,并取消选中“Enable the Visual Studio hosting process”。

我无法在 .NET Framework 4 中使用挂钩类(用于跟踪),因此如果您使用的是 .NET Framework 4,请通过转到项目属性并选择不同的 .NET Framework 版本,将目标框架更改为 3.5 或任何低于 3.5 的框架。

现在,让我们添加 “using” 语句,以便编码更轻松。添加以下 “using” 语句

using InputManager;

好的,让我们了解如何使用这个库。

跟踪用户鼠标和键盘消息

InputManagerHookExample.jpg

在顶部下载此挂钩示例

要跟踪用户鼠标和键盘消息,我们需要设置一个挂钩。我们如何做到这一点?使用 InputManager,这非常容易。

要跟踪用户键盘消息,在您的 Form_Load 事件处理方法中,添加以下代码

//Adding keyboard event handlers and installing the hook
KeyboardHook.KeyDown += new KeyboardHook.KeyDownEventHandler(KeyboardHook_KeyDown);
KeyboardHook.KeyUp += new KeyboardHook.KeyUpEventHandler(KeyboardHook_KeyUp);
KeyboardHook.InstallHook();

前两行允许我们跟踪键盘消息。这是通过我们将创建的两个方法来处理这些事件。第三行告诉 InputManager 库设置挂钩并开始读取键盘消息。

现在让我们添加之前提到的两个方法

void KeyboardHook_KeyUp(int vkCode)
{
    //Everytime the users releases a certain key up,
    //your application will go to this line
    //Use the vKCode argument to determine which key has been released
}

void KeyboardHook_KeyDown(int vkCode)
{
    //Everytime the users holds a certain key down,
    //your application will go to this line
    //Use the vKCode argument to determine which key is held down
}

要将这些按键转换为 string 而不是虚拟键码,请使用这种简单技术

string keyString = ((Keys)vkCode).ToString();
//Using the Keys Enum ToString method for translating

要跟踪用户鼠标消息,在您的 Form_Load 事件处理方法中,添加以下代码

//Adding mouse event handlers and installing the hook
MouseHook.MouseEvent += new MouseHook.MouseEventEventHandler(MouseHook_MouseEvent);
MouseHook.MouseMove += new MouseHook.MouseMoveEventHandler(MouseHook_MouseMove);
MouseHook.WheelEvent += new MouseHook.WheelEventEventHandler(MouseHook_WheelEvent);
MouseHook.InstallHook();

前三行告诉 InputManager 库为每种鼠标消息类型(鼠标按钮事件、鼠标移动事件和滚轮滚动事件)添加事件处理程序。我们将在下面添加处理这些消息的方法。第四行告诉 InputManager 类安装挂钩并开始接收消息。

让我们添加处理这些消息的方法

void MouseHook_WheelEvent(MouseHook.MouseWheelEvents wEvent)
{
    //Event time the wheel was scrolled the application will go to this line
    //Using the wEvent argument we can detect 
    //if the mouse was scrolled forward or backward
}

void MouseHook_MouseMove(MouseHook.POINT ptLocat)
{
    //Everytime the mouse moved, the application will go to this line
    //Using the ptLocat arguments you can detect 
    //which point the mouse cursor moved to
}

void MouseHook_MouseEvent(MouseHook.MouseEvents mEvent)
{
    //Everytime a mouse button changed it's state 
    //(from up to down or down to up) the application will go to this line
    //Using the mEvent argument we can detect which button changed it's state
}

要在 MouseHook_WheelEvent 方法中检测滚轮是向上还是向下滚动,我们使用 MouseHook.MouseWheelEvents 枚举

string scrollDirection;
if (wEvent == MouseHook.MouseWheelEvents.ScrollDown)
    scrollDirection = "scrolled down";
else scrollDirection = "scrolled up";

要检测鼠标每次移动时的位置(X 和 Y),我们在 MouseHook_MouseMove 方法中使用 ptLocat 参数

textBox1.Text = "The mouse cursor moved to: " + ptLocat.x + ", " + ptLocat.y;
//Updating a textbox text to the current mouse position

要检测哪个按钮改变了状态,我们在 MouseHook_MouseEvent 方法中使用 mEvent 参数

textBox1.Text = "Mouse button changed state to: " + mEvent.ToString();
//Updates the textbox to show which button changed it's state last time

您可以使用 switch 语句来分别处理每个鼠标按钮/状态更改

switch (mEvent)
{
   case MouseHook.MouseEvents.LeftDown:
       //Left button is down, do something here
       break;

   case MouseHook.MouseEvents.LeftUp:
        //Left button is up, do something here
         break;
}

发送鼠标和键盘消息(支持 DirectX)

要发送键盘消息(按键),我们使用 InputManager 库中的 Keyboard 类。

要发送按键按下/按键抬起消息,我们使用 Keyboard.KeyDownKeyboard.KeyUp 方法。在文本框中写入“hello”的示例

ExampleText.Focus(); //Sets focus on the example text

//Writing Hello with keys sending
Keyboard.KeyDown(Keys.H);
Keyboard.KeyUp(Keys.H);

Keyboard.KeyDown(Keys.E);
Keyboard.KeyUp(Keys.E);

Keyboard.KeyDown(Keys.L);
Keyboard.KeyUp(Keys.L);

Keyboard.KeyDown(Keys.L);
Keyboard.KeyUp(Keys.L);

Keyboard.KeyDown(Keys.O);
Keyboard.KeyUp(Keys.O);

要发送快捷键,我们使用 Keyboard.ShortcutKeys 方法,并带一个 Keys 数组

ExampleText.Focus(); //Sets focus on the example textbox

//Sends Shift + Control + Left to select a word
Keys[] keys = new Keys[] { Keys.RShiftKey, Keys.RControlKey, Keys.Left };
Keyboard.ShortcutKeys(keys);

要发送鼠标消息(鼠标按键、鼠标移动、滚轮滚动),我们使用 InputManager 库中的 Mouse 类。

将鼠标移动到特定位置(以屏幕坐标表示),我们使用 Mouse.Move 方法

Mouse.Move(Point.X, Point.Y);
//Moves the mouse to a certain location on the screen

执行鼠标单击消息,我们使用 Mouse.PressButton 方法

Mouse.PressButton(Mouse.MouseKeys.Left); //Performing a left click

发送鼠标按钮按下或抬起消息,我们使用 Mouse.ButtonDown/Mouse.ButtonUp 方法

Mouse.ButtonDown(Mouse.MouseKeys.Left); //Holding the left mouse down
Mouse.ButtonUp(Mouse.MouseKeys.Left); //Releasing the left mouse button

向上或向下滚动,我们使用 Mouse.Scroll 方法

Mouse.Scroll(Mouse.ScrollDirection.Down); //Scroling down
Mouse.Scroll(Mouse.ScrollDirection.Up); //Scrolling up

InputManagerSendingMessagesExample.jpg

在顶部下载此输入模拟示例

关注点

编写这个库(其中的一部分)非常有趣,也有些挑战。还有其他发送鼠标和键盘消息的方法,使用不同的 API,它们不支持 DirectX 并且更容易使用,但我希望简化它并创建自己的库,这样您甚至不需要知道 API 的含义。使用这个库,您可以轻松地发送和接收输入消息!

历史

  • 2010.10.13:添加了关于库如何工作的解释(其背后的概念)。
© . All rights reserved.