【问题标题】:Hook ALT key in VSTO Excel Add-in在 VSTO Excel 加载项中挂钩 ALT 键
【发布时间】:2019-02-04 05:41:34
【问题描述】:

我需要的解决方案 99% 封装在下面链接的公认解决方案中:

How to perform .Onkey Event in an Excel Add-In created with Visual Studio 2010?

但是,它似乎不适用于挂接 ALT 键。我环顾四周,遇到了几个 C# 示例,但我是编程新手,而且我正在学习 VB .NET,因此以我的知识水平,我无法成功地将代码移植到其他 C# 示例中以使其在我的VB .NET 项目。

由于上面链接的代码已经完成了我需要的一切,我想继续使用它,但如果有人能告诉我如何让它也钩住 ALT 键,我将不胜感激。我想有一个常量需要以特定的方式传递和检查,但是自从找到这个解决方案后的最后 4 天里我一直无法弄清楚。任何帮助将不胜感激。

非常感谢!

编辑:@Vincent,这是我正在测试的代码,它因溢出错误而中断:

Imports InputHelperLib

Public Class ThisAddIn

Dim KeyboardHook As InputHelper.Hooks.LocalKeyboardHook

Private Sub ThisAddIn_Startup() Handles Me.Startup
    KeyboardHook = New InputHelper.Hooks.LocalKeyboardHook
    AddHandler KeyboardHook.KeyDown, AddressOf KeyboardHook_KeyDown
    AddHandler KeyboardHook.KeyUp, AddressOf KeyboardHook_KeyUp
End Sub

Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
    If KeyboardHook IsNot Nothing Then KeyboardHook.Dispose()
End Sub

Private Sub KeyboardHook_KeyDown(sender As Object, e As InputHelper.Hooks.KeyboardHookEventArgs)
    If e.Modifiers = InputHelper.ModifierKeys.Alt AndAlso e.KeyCode = System.Windows.Forms.Keys.M Then
        System.Windows.Forms.MessageBox.Show("ALT + M was pressed!")
    End If
End Sub

Private Sub KeyboardHook_KeyUp(sender As Object, e As InputHelper.Hooks.KeyboardHookEventArgs)
    If e.Modifiers = InputHelper.ModifierKeys.Alt AndAlso e.KeyCode = System.Windows.Forms.Keys.M Then
        System.Windows.Forms.MessageBox.Show("ALT + M was released!")
    End If
End Sub
End Class

【问题讨论】:

  • 该代码并不完全有效,并且没有使用确定修饰符的最佳方法...我建议您查看我的名为 InputHelper 的库。它包含一个键盘钩子,它是通过大量研究创建的,以便尽可能正确(编码方面),我已经对其进行了彻底的测试,以确保它可以正常工作。在项目的 wiki 上有关于如何使用它的说明:Low-level keyboard hook
  • 嗨文森特,这是一个令人印象深刻的项目。但是,它似乎不能在 Excel 中运行的 VSTO 加载项中可靠地工作。我发现如果我按照 wiki 文档实现它,它在 Winforms 应用程序中运行良好,但是当我的加载项加载时挂钩时,它不会触发 Excel 内部的事件,但只要我点击外部Excel,它的工作原理。我相信这可能是为相关应用程序域获取正确线程的问题?
  • 这很奇怪...因为它安装了一个低级挂钩并使用 WinAPI 来执行此操作,所以它应该始终工作,因为 Windows 正在为您管理挂钩。该钩子在创建它的同一线程中运行。您可以编辑您的问题并包含您使用的代码吗?我得自己试试这个。您使用的是哪个版本的 Excel?
  • 虽然我现在看到,在您之前链接的帖子中,它只挂钩了当前 AppDomain 的线程。如果我的库挂钩了当前桌面中的 all 线程,那么如果这个微小的细节产生了重大影响,那就太奇怪了。
  • 我似乎无法重现该问题。我尝试了所有我能想到的实例化钩子和订阅事件处理程序的组合,并且每次都没有问题。我使用 Excel 2010 和 Visual Studio 2010,针对 .NET Framework 4.0。

标签: .net vb.net vsto


【解决方案1】:

该答案中的代码并不完全有效,并且没有使用确定修饰符的最佳方法。

由于标准的低级键盘钩子不起作用,我在我的InputHelper 库中添加了一个LocalKeyboardHook,它使用WH_KEYBOARD 钩子而不是WH_KEYBOARD_LL。不同之处在于WH_KEYBOARD 要求您注入一个 DLL 并在您要挂钩的每个进程中指定一个线程。幸运的是,由于您使用的是 VSTO 外接程序,因此 InputHelper 已与您的外接程序一起加载到 Excel 进程中。

编译后的DLL可以在我项目的Release部分下载:
https://github.com/Visual-Vincent/InputHelper/releases

(也可以直接从仓库下载InputHelper.vb源文件)

使用示例:

Imports InputHelperLib

Public Class ThisAddIn

    Dim KeyboardHook As InputHelper.Hooks.LocalKeyboardHook

    Private Sub ThisAddIn_Startup() Handles Me.Startup
        KeyboardHook = New InputHelper.Hooks.LocalKeyboardHook
        AddHandler KeyboardHook.KeyDown, AddressOf KeyboardHook_KeyDown
        AddHandler KeyboardHook.KeyUp, AddressOf KeyboardHook_KeyUp
    End Sub

    Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
        If KeyboardHook IsNot Nothing Then KeyboardHook.Dispose()
    End Sub

    Private Sub KeyboardHook_KeyDown(sender As Object, e As InputHelper.Hooks.KeyboardHookEventArgs)
        If e.Modifiers = InputHelper.ModifierKeys.Alt AndAlso e.KeyCode = System.Windows.Forms.Keys.M Then
            System.Windows.Forms.MessageBox.Show("ALT + M was pressed!")
        End If
    End Sub

    Private Sub KeyboardHook_KeyUp(sender As Object, e As InputHelper.Hooks.KeyboardHookEventArgs)
        If e.Modifiers = InputHelper.ModifierKeys.Alt AndAlso e.KeyCode = System.Windows.Forms.Keys.M Then
            System.Windows.Forms.MessageBox.Show("ALT + M was released!")
        End If
    End Sub
End Class

【讨论】:

  • 您好文森特,感谢您发布更新,非常感谢。我今天正在旅行,但明天我一回到我的电脑就会测试它。
  • @RandomOrangeCat :不用担心!慢慢来!
  • 嗨文森特,我今天早上进行了测试,虽然它现在似乎肯定挂钩了键,但无论我挂钩哪个键,一旦事件触发,我就会收到此错误:类型未处理的异常' System.OverflowException' 发生在未知模块中。算术运算导致溢出。为确保我的加载项没有问题,我新建了一个完全空白的加载项,仅将您在上面发布的代码放入其中并对其进行测试,并且错误不断出现。
  • @RandomOrangeCat :您可以编辑您在问题中使用的代码吗?还有你用的是InputHelper编译好的DLL还是源码?
  • 您好文森特,我都尝试了 - 我将源代码作为项目导入到我的加载项中,当失败时,尝试仅引用 InputHelper 的 DLL(我也尝试了 .NET3 的一个)。你想让我粘贴我正在使用但目前失败的代码吗?如果是这样,我将在我回到装有 Visual Studio 的 PC 后立即执行此操作。感谢您的耐心等待
猜你喜欢
  • 2022-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多