简体   繁体   English

如何使用 VB.NET 注册全局鼠标事件(移动、点击)?

[英]How to register to global mouse events (move, click) with VB.NET?

For my own implementation of a lightweight remote service application (like RDP, TeamViewer), I need to listen to the system's (or global) mouse events, like mouse move or left/right/middle/etc click.对于我自己的轻量级远程服务应用程序(如 RDP、TeamViewer)的实现,我需要监听系统(或全局)鼠标事件,如鼠标移动或左/右/中/等点击。

I found out, that there is a managed interface/API for querying the system's mouse position:我发现,有一个用于查询系统鼠标位置的托管接口/API:

Dim pos As System.Drawing.Point = Windows.Forms.Cursor.Position
Label1.Text = String.Format("Current Position: {0} - {1}", pos.X, pos.Y)

However, the class Windows.Forms.Cursor seems to have no events, I can register/listen to.但是,类Windows.Forms.Cursor似乎没有事件,我可以注册/收听。 Private WithEvents MyCurser As Windows.Forms.Cursor does not have any listing with Handles . Private WithEvents MyCurser As Windows.Forms.Cursor没有任何包含Handles列表。

To make it more clear: I do want to track mouse events outside my application (so click event listeners to my own forms are not applicable), as my application is a remote service application like RDP or TeamViewer which only forwards mouse events (and the display) to an remote computer.更清楚地说:我确实想我的应用程序之外跟踪鼠标事件(因此我自己的表单的单击事件侦听器不适用),因为我的应用程序是一个远程服务应用程序,如 RDP 或 TeamViewer,它只转发鼠标事件(以及显示)到远程计算机。

Is there a managed (.NET) way of getting the mouse position changes as an event (and not requiring to have a timer to query the position), and also whether the user have clicked (is clicking) a button on the mouse (and what button it is)?是否有一种托管(.NET) 方法可以将鼠标位置更改为事件(并且不需要计时器来查询位置),以及用户是否已单击(正在单击)鼠标上的按钮(以及它是什么按钮)?

Bonus question: Does your solution work when the mouse move/click "event" has been triggered by another software and not by the human who is actually operating the mouse.额外问题:当鼠标移动/点击“事件”是由另一个软件而不是由实际操作鼠标的人触发时,您的解决方案是否有效。

You can use my library called InputHelper . 您可以使用我的名为InputHelper的库。 It was built to help .NET developers both capture and simulate mouse and keyboard input in a simple, and correct, manner. 它旨在帮助.NET开发人员以简单且正确的方式捕获和模拟鼠标和键盘输入。

After seeing and answering way too many Stack Overflow questions where the user either used a deprecated API or where their P/Invoke signatures where way off, I decided to create this as a more .NET-friendly way of managing input as well as an attempt to fight the only partially correct code that users gathered from many different places on the internet. 在看到并回答了太多的堆栈溢出问题后,用户要么使用了已弃用的API,要么在哪里使用了P / Invoke签名,然后我决定将其创建为一种更加.NET友好的方式来管理输入和尝试与用户从互联网上许多不同地方收集的唯一部分正确的代码作斗争。

InputHelper is built around the native Windows API (WinAPI) and utilizes functions such as SendInput() , SendMessage() / PostMessage() and SetWindowsHookEx() in order to get its job done. InputHelper围绕本机Windows API(WinAPI)构建,并利用诸如SendInput()SendMessage() / PostMessage()SetWindowsHookEx()的功能来完成其工作。

Its Wiki is sadly still far from complete as I've only documented the mouse and keyboard hooks, however the library includes XML documentation files containing comments explaining every function in it, which are automatically displayed by IntelliSense as you type your code. 可悲的是,它的Wiki还远远不够完善,因为我只记录了鼠标和键盘挂钩,但是该库包含XML文档文件,其中包含解释其中每个功能的注释,IntelliSense会在您键入代码时自动显示这些注释。 So for a mini-documentation and overview of the library you can always open Visual Studio's Object Browser (press F12 on any type or namespace, or go to View > Object Browser ) and locate it there. 因此,对于库的小型文档和概述,您始终可以打开Visual Studio的对象浏览器(在任何类型或名称空间上按F12 ,或转到“ View > Object Browser )并将其定位在该位置。

InputHelper currently consists of four caregories: InputHelper当前包含四个类别:

  • InputHelper.Hooks : Classes for capturing system-wide mouse and keyboard input. InputHelper.Hooks :用于捕获系统范围的鼠标和键盘输入的类。 This can be used to make hot keys, for instance. 例如,这可用于制作热键。

  • InputHelper.Keyboard : Methods for simulating physical ("real") keyboard input/key strokes. InputHelper.Keyboard :模拟物理(“实际”)键盘输入/按键的方法。

  • InputHelper.Mouse : Methods for simulating physical mouse input. InputHelper.Mouse :用于模拟物理鼠标输入的方法。

  • InputHelper.WindowMessages : Methods for simulating mouse and keyboard input at a more virtual level. InputHelper.WindowMessages :用于在更虚拟的级别上模拟鼠标和键盘输入的方法。 This utilizes window messages ( Send-/PostMessage ) and can be used to target specific windows. 这利用了窗口消息( Send-/PostMessage ),并且可以用于定位特定的窗口。

The one you're looking for is InputHelper.Hooks , specifically, InputHelper.Hooks.MouseHook . 您要查找的是InputHelper.Hooks ,特别是InputHelper.Hooks.MouseHook

To start with, download the compiled version of the library on the Releases page and add it as a reference to your project. 首先,请在“ 发行”页面上下载库的编译版本,并将其添加为对项目的引用。 For convenience import the InputHelperLib namespace in the file(s) that you'll be using it: 为了方便起见,将InputHelperLib命名空间导入将要使用的文件中:

Imports InputHelperLib

Now, the easiest way to create a mouse hook is to just instantiate an instance of the MouseHook class at class-level: 现在,创建鼠标挂钩的最简单方法是在类级别实例化MouseHook类的实例:

Dim MouseHook As New InputHelper.Hooks.MouseHook

This will listen for mouse events until the variable goes out of scope or until you call Dispose() on it. 这将监听鼠标事件,直到变量超出范围或直到您对它调用Dispose()为止。

If you don't want to start the hook right away, just declare the variable and initialize it whenever you want. 如果您不想立即启动挂钩,则只需声明变量并在需要时对其进行初始化。

Dim MouseHook As InputHelper.Hooks.MouseHook

'Start the hook at the click of a button.
Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click
    If MouseHook Is Nothing Then
        MouseHook = New InputHelper.Hooks.MouseHook
    End If
End Sub

The hook includes four events: 该挂钩包括四个事件:

  • MouseDown - Occurs when a mouse button is pressed or held down. MouseDown在按下或按住鼠标按钮时发生。

  • MouseMove - Occurs when the mouse moves. MouseMove在鼠标移动时发生。

  • MouseUp - Occurs when a mouse button is released. MouseUp在释放鼠标按钮时发生。

  • MouseWheel - Occurs when the mouse wheel is scrolled. MouseWheel滚动鼠标滚轮时发生。

You can subscribe to the events using the AddHandler statement . 您可以使用AddHandler语句订阅事件。

Dim MouseHook As InputHelper.Hooks.MouseHook

'Start the hook at the click of a button.
Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click
    If MouseHook Is Nothing Then
        MouseHook = New InputHelper.Hooks.MouseHook

        AddHandler MouseHook.MouseDown, AddressOf MouseHook_MouseDown
        AddHandler MouseHook.MouseMove, AddressOf MouseHook_MouseMove
        AddHandler MouseHook.MouseWheel, AddressOf MouseHook_MouseWheel
    End If
End Sub

Example MouseDown event handler: 示例MouseDown事件处理程序:

Private Sub MouseHook_MouseDown(sender As Object, e As InputHelperLib.InputHelper.Hooks.MouseHookEventArgs)
    If e.Button = System.Windows.Forms.MouseButtons.Left AndAlso e.DoubleClick = True Then
        MessageBox.Show("Left mouse button was double-clicked.")
    End If
End Sub

Example MouseMove event handler: 示例MouseMove事件处理程序:

Private Sub MouseHook_MouseMove(sender As Object, e As InputHelperLib.InputHelper.Hooks.MouseHookEventArgs)
    LogTextBox.AppendText("Mouse moved to (X: " & e.Location.X & ", Y: " & e.Location.Y & ")")
End Sub

Example MouseWheel event handler : 示例MouseWheel事件处理程序

Private Sub MouseHook_MouseWheel(sender As Object, e As InputHelperLib.InputHelper.Hooks.MouseHookEventArgs)
    If e.Delta > 0 AndAlso e.ScrollDirection = InputHelper.Hooks.ScrollDirection.Vertical Then
        MessageBox.Show("Mouse scrolled up")
    End If
End Sub

And now you have a functioning, global mouse hook! 现在,您有了一个有效的全局鼠标钩!

For more details about the hook and its event args, please have a look at the project's wiki . 有关钩子及其事件args的更多详细信息,请查看项目的wiki

Bonus question: Does your solution work when the mouse move/click "event" has been triggered by another software and not by the human who is actually operating the mouse. 额外的问题:当鼠标移动/单击“事件”是由另一个软件而不是由实际操作鼠标的人员触发时,您的解决方案是否有效?

Yes and no. 是的,没有。 It depends on how the other software triggered the event. 这取决于其他软件如何触发事件。 If it uses SendInput or alike to simulate actual, physical input then yes. 如果它使用SendInput或类似方法模拟实际的物理输入, SendInput是。 If it uses window messages to target specific windows then no. 如果它使用窗口消息来定位特定窗口,则否。

Thank you so much.非常感谢。

I could find no Hooking Lib for Visual Basic on anywhere on internet.我在互联网上的任何地方都找不到适用于 Visual Basic 的 Hooking Lib。 And also I unfortunately could not convert the C# codes to VB codes.而且不幸的是,我无法将 C# 代码转换为 VB 代码。 But this Lib and examples are perfect :)但是这个 Lib 和示例是完美的 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM