鼠标和键盘跟踪与模拟器
Brian Geiman 的全局鼠标和键盘库的修订版
引言
你是否曾想过要有一个程序来记录然后模拟某些键盘和鼠标操作,但却不知道如何实现?那么我可能有一个解决方案给你。
这是 Brian Geiman 的 全局鼠标和键盘库 的一个修订版本。
本文主要关注 `MouseKeyboardLibrary` 解决方案中包含的全局宏录制器示例。另一个名为 `HookTestForm` 的窗体非常简单,正如其名所示。
然而,当我测试和尝试全局宏录制器时,我感觉有些东西缺失了。它是一个完美的例子,我并没有错,但如果你想愚弄你的朋友,它做不到。
这就是我喜爱Code Project 开源许可证的原因,我拿了这个窗体并进行了修订。荣耀归于开源。
这是修订后的结果。
做了什么
清理过程
如果你读过我的 使用 C# 和 YouTube API 管理 YouTube 1.6,这里有很多相同的过程。
当创建一个新窗体时,Microsoft Visual Studio 总是会把最常用的引用放在一个列表中,等着你去使用它们(比如 `System`、`System.Drawing`、`System.Windows.Forms`)。基本上,额外的项被加载并待在那里,希望你能使用它们。但是,如果你不使用它们,它们会拖慢你的应用程序的启动和响应时间。
我移除了所有运行程序不需要的项。
以前
操作后
应用程序启动时间的差异非常明显。当然,你需要移除 `using` 引用才能看到整个应用程序的性能提升。
完成这些之后,我对代码进行了一些空白清理。一个完美的例子是,当你尝试在 `form.designer` 之外编写窗体设计器代码时,你不需要输入所有内容:
mouseHook.MouseMove += new MouseEventHandler(mouseHook_MouseMove);
你只需要输入:
mouseHook.MouseMove += mouseHook_MouseMove;
编译器会处理剩下的事情。
现在我们来谈谈大多数人几乎不在意但却非常重要的事情。让我们谈谈线程安全!线程安全是我最喜欢的话题,因为多线程程序在当今社会越来越普遍。这与竞态条件/风险有关。如果你正在创建一个执行特定过程的程序,你希望确保它能够毫无问题地执行该过程,而不会与其他线程产生冲突。
在 C# 中,你拥有分配属性来控制属性的语义的最高权限。当你分配属性时,你有机会更改其内存可见性语义。
举个例子,当你有一个字段,其值和含义都不会改变时,比如:
private KeyboardHook keyboardHook = new KeyboardHook();
你可以添加一个 `readonly` 字段
private readonly KeyboardHook keyboardHook = new KeyboardHook();
来使其线程安全。它会改变值的编译和声明方式。有关 `readonly` 的更多信息,请参考这里,了解它是如何工作的以及为什么它很重要。
现在我们来检查冗余。
当你初始化一个字段时,如果一个值没有同时附加到它,不要担心。只需确保当字段被使用时它有一个值。MacroForm 是一个编写得很好的程序,只有一个字段具有冗余的默认值。
那个字段是 `lastTimeRecorded` `int` 字段。它之所以冗余,是因为在第一次使用时,它被初始化为 `Environment.TickCount`。因此,它一开始就完全覆盖了默认值。对于 `int` 来说,这没有任何区别,但如果你使用的是 `object`,根据 `object` 的复杂程度,可能会浪费几秒钟。
新增功能
现在小小的细节都讲完了,让我们看看现在能做什么!
首先,让我们看看旧窗体
现在是新窗体
新窗体具有以下升级规格:
- 按钮仅在需要时启用。
- `Bool` 值用于查看程序是否正在录制或是否已显示热键警告。
- 一个 `backworker`(称为 `Playworker`)用于回放过程(使其能够停止回放)。
- 回放时隐藏窗口选项。
- 鼠标选择窗口时停止选项。
- 集成我最喜欢使用的全局热键激活。
- 如果激活了热键,你可以启用无限循环并循环回放,直到按下全局热键。
- 添加了进度条以检索进度报告。
我知道人们会问,但是不,我没有包含序列化器来保存鼠标或键盘移动。保存鼠标事件非常麻烦(因为你需要分解事件并为每个内部对象创建不同的变量)。尽管如此,如果你保存鼠标移动,然后将其带到具有不同屏幕分辨率的另一台计算机系统上,你可能会遇到越界指针异常。要使其正常工作,需要进行大量的错误纠正。
既然我已经解释了为什么没有包含保存按钮,让我们继续。
全局热键通过设置一个系统 `IntPtr struct` 来工作,该结构基于 `Windows.Forms.Keys` 中的输入键码和修饰符。按下热键时,会激活一个 `protected override void`。从该 `void` 中,它运行另一个名为 `HandleHotkey` 的 `void` 来处理热键事件。
Backworker 和 Progress Bar 非常简单;它完成了为回放设定的编程,并增加了三项功能。
- 在 `Backworker` 被告知工作之前,会计算录制的事件并将它们设置为进度条的最大值。
- 一个内部变量随后计算 `backworker` 运行的事件,并将该计数输出到进度条。
- 在运行下一个事件之前,会检查 worker 是否有待处理的取消请求;如果有,则退出 `foreach` 命令。
隐藏窗口和选择时停止是简单的自解释选项。需要注意的是,在更改进度条状态之前,会检查是否勾选了“隐藏窗口”。这是为了避免隐藏表单但更改设计器项状态时可能出现的异常。
结论
无论你是想通过这个应用程序学习如何录制鼠标和键盘输入,还是想和你的朋友一起玩乐;它都做同样的事情。
随意下载两个源代码并进行比较。玩起来很有趣。
各位技术宅们,加油!