2017-11-17 85 views
1

首先,我不是一个真正的编码器,但我很满意迄今为止所做的。允许全局热键

我已经写下了这个代码,这是与机器人技术。下面的代码允许我在单击表单时使用键盘快捷键。但是,无论应用程序是否处于焦点或甚至最小化状态,我都需要使用热键。

我已经看了网上,但它不是很清楚。

Public Class MainForm 

    Private Sub MainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown 

     If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then 
      DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R) 
     End If 

     'If e.KeyCode = Keys.R Then 
     'DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R) 
     'End If 

    End Sub 

    Private Sub MainForm_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp 

     If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then 
      DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R) 
     End If 

     'If e.KeyCode = Keys.R Then 
     'DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R) 
     'End If 

    End Sub 

Public Class MainForm 


    Private Sub MainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown 

     If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then 
      DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R) 
     End If 

     'If e.KeyCode = Keys.R Then 
     'DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R) 
     'End If 

    End Sub 

    Private Sub MainForm_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp 

     If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then 
      DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R) 
     End If 

     'If e.KeyCode = Keys.R Then 
     'DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R) 
     'End If 

    End Sub 

End Class 

更新:

权。我已经添加了一个允许注册GlobalKey的类。

在我的主要形式,我现在有这个键:

Public Class MainForm 
    Dim hkr As New HotKeyRegistryClass(Me.Handle) 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.A).ToString() 
     hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.S).ToString() 
     hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.D).ToString() 
     hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.F).ToString() 
     hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.G).ToString() 
     hkr.Register(HotKeyRegistryClass.Modifiers.MOD_SHIFT Or HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.H).ToString() 
    End Sub 

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 
     If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE 
      Dim ID As String = m.WParam.ToString() 
      Select Case ID 
       Case 0 : If DF1Com1.Write("O:1/0", "1") Then DF1Com1.Write("O:1/0", "0") 
       Case 1 : MessageBox.Show("S") 
       Case 2 : MessageBox.Show("D") 
       Case 3 : MessageBox.Show("F") 
       Case 4 : MessageBox.Show("G") 
       Case 5 : MessageBox.Show("H") 
      End Select 
     End If 
     MyBase.WndProc(m) 
    End Sub 

如果你看看案例0。它可以工作,但它不会使钥匙备份。它一直压下来。我需要它的时候,关键是郁闷它DF1Com1.Write( “O:1/0”, “0”)'

类代码

Public NotInheritable Class HotKeyRegistryClass 
    Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Int32, ByVal fsModifier As Int32, ByVal vk As Int32) As Int32 
    Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Int32) As Int32 
    Private Handle As IntPtr = IntPtr.Zero 
    Private Registry As New System.Collections.Generic.List(Of Int32) 
    Public Enum Messages 
     [WM_HOTKEY] = &H312 
    End Enum 
    Public Enum Modifiers 
     [MOD_ALT] = &H1 
     [MOD_CTRL] = &H2 
     [MOD_SHIFT] = &H4 
    End Enum 
    Sub New(ByVal Handle As IntPtr) 
     Me.Handle = Handle 
    End Sub 
    Public Function Register(ByVal Modifier As Int32, ByVal Key As System.Windows.Forms.Keys) As Int32 
     Dim ret As Int32 
     ret = NextAvailableIndex() 
     Call RegisterHotKey(Me.Handle, ret, Modifier, Key) 
     Registry.Insert(ret, ret) 
     Return ret 
    End Function 
    Public Sub Unregister(ByVal ID As Int32) 
     Call UnregisterHotKey(Me.Handle, ID) 
     Registry.Remove(ID) 
    End Sub 
    Private Function NextAvailableIndex() As Int32 
     Dim ret As Int32 = 0 
     Dim n As Int32 = 0 
     For i As Int32 = 0 To Registry.Count - 1 
      If Registry(i) = n Then 
       n = n + 1 
      ElseIf n < Registry(i) Then 
       Return n 
      End If 
     Next 
     If n = Registry.Count Then 
      Return Registry.Count 
     End If 
     Return ret 
    End Function 
End Class 
+1

查看'Windows.Input.Keyboard.GetKeyStates',而不是捕获窗体上的关键事件,轮询计时器或后台线程中的键状态。 –

+1

问这个问题。有点不公正。正如我所说的。我不是一个硬核编码器。 – Arthor

+1

我已经更新了代码,我几乎是他们的。仍在继续,但我坚持最后一部分。 – Arthor

回答

1

遗憾的是,只有RegisterHotkey告诉你当一个组合键被激活时。另外,正如您已经意识到的那样,只有当您的应用具有焦点时,您才能使用KeyDownKeyUp事件。

真正全球化的KeyDownKeyUp的唯一方法是使用低级别的键盘钩子。由于我不想复制我的整个答案,我只会链接到它。该链接将为您设置键盘挂钩提供一些指导。

How to disable/override Windows 10 Hotkeys with C#

另一种可能性是在热键激活这样执行这两个命令...

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 
     If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE 
      Dim ID As String = m.WParam.ToString() 
      Select Case ID 
       Case 0 : 
        DF1Com1.Write("O:1/0", "1") 
        System.Threading.Thread.Sleep(2000) 
        DF1Com1.Write("O:1/0", "0") 
       Case 1 : MessageBox.Show("S") 
       Case 2 : MessageBox.Show("D") 
       Case 3 : MessageBox.Show("F") 
       Case 4 : MessageBox.Show("G") 
       Case 5 : MessageBox.Show("H") 
      End Select 
     End If 
     MyBase.WndProc(m) 
    End Sub 
+0

只是一个简单的问题。我知道你在C#中有你的解决方案。是否有一个VB.NET解决方案,因为我的机器人系统使用VB.NET。和以前一样,我不介意如果我不能进入最低级别,我只需要一种方法,一旦释放了密钥,就可以停用'DF1Com1.Write(“O:1/0”,“0”)。谢谢 – Arthor

+0

你应该可以从CodeProject中获取项目并将C#编译成DLL库。然后,您可以引用该库并在VB.net中编写处理程序。 –

+0

也许....通过RegisterHotkey激活每个热键应执行第一个代码DF1Com1.Write(“O:1/0”,“1”),然后休眠一秒钟然后执行最后一位, 'DF1Com1.Write(“O:1/0”,“0”)'。基本上这意味着即使您按住按键,每次按键也只能使机器人移动一定的量。如果这不起作用,那么我只能想到一个键盘钩子。 –

0

达到这个目的可能是使用布尔追踪的另一种选择。这意味着,按热键启动,然后再按一次停止。

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 
Static toggle As Boolean 
     If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE 
      Dim ID As String = m.WParam.ToString() 
      Select Case ID 
       Case 0 : 
      If toggle Then 
      DF1Com1.Write("O:1/0", "0") 
      Else 
         DF1Com1.Write("O:1/0", "1") 
      End If 
      toggle = Not toggle 
       Case 1 : MessageBox.Show("S") 
       Case 2 : MessageBox.Show("D") 
       Case 3 : MessageBox.Show("F") 
       Case 4 : MessageBox.Show("G") 
       Case 5 : MessageBox.Show("H") 
      End Select 
     End If 
     MyBase.WndProc(m) 
    End Sub 
+0

你好,好主意。但不幸的是,这样做不可行。我只能想象会出错的用户数量。由于这个系统不只是由我自己使用, – Arthor

+0

你好,有人提议的解决方案的任何更新有一天提出。谢谢 – Arthor

+0

我已经取得了一些进展,但假期让我感到耽搁。我会尽力在今天完成。 –