【问题标题】:How to catch Ctrl + Alt + RShftKey如何捕捉 Ctrl + Alt + RShftKey
【发布时间】:2013-08-16 21:21:22
【问题描述】:

一段时间以来,我试图在常见的 VBNET 密钥处理程序下捕捉 Ctrl + Alt + Right Shift Key。 这是我的测试:

    If e.Control And e.Alt And e.KeyCode = Keys.Space Then
        MsgBox("CTRL + ALT + SPACE") ' This work
    End If

    If e.Control And e.Shift And e.KeyCode = Keys.F10 Then
        MsgBox("CTRL + SHIFT + F10") ' This work
    End If

    If e.Control And e.Alt And e.KeyCode = Keys.ShiftKey Then
        MsgBox("CTRL + ALT + SHIFT") ' This work
    End If

    If e.Alt And e.Shift And e.KeyCode = Keys.LWin Then
        MsgBox("ALT + SHIFT + LEFT WINDOWS") ' This work
    End If

    If e.Control And e.Alt And e.KeyCode = Keys.RShiftKey Then
        MsgBox("CTRL + ALT + RIGHT SHIFT") ' This don't work
    End If

Windows 7、WinForms、VB2008、NET 框架 2.0

为什么我在描述的情况下无法捕捉到 Ctrl + Alt + Right Shift Key
或者,我如何捕捉 Ctrl + Alt + Right Shift Key 组合?

【问题讨论】:

    标签: vb.net


    【解决方案1】:

    使用标准 VB.NET 方法无法检测 Shift 之间的差异。 为此,您必须使用 Windows API:

     <System.Runtime.InteropServices.DllImport("user32.dll")> _
        Private Shared Function GetAsyncKeyState(vKey As Keys) As Short
        End Function
    
        Private Sub Form2_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    
            If e.Control And e.Alt And e.Shift Then
    
                If Convert.ToBoolean(GetAsyncKeyState(Keys.LShiftKey)) Then
                    MsgBox("CTRL + ALT + LEFT SHIFT")
                ElseIf Convert.ToBoolean(GetAsyncKeyState(Keys.RShiftKey)) Then
                    MsgBox("CTRL + ALT + RIGHT SHIFT")
                End If
    
            End If
    
        End Sub
    

    【讨论】:

    • 非常有趣。为什么在 Keys 常量下枚举 RShiftKey 和 LShiftKey 呢? LControlKey 和 RControlKey 是否同样适用?还有什么不能按预期工作?
    • 更新了我对可行解决方案的回答 - 这是您使用这些枚举代码的地方
    • 有问题。按住三个键后按任意其他键,看看它触发了消息框。
    • 你的意思是按住ctrl+alt+shift后显示信息?
    【解决方案2】:

    嗯,这很棘手,因为这些都是修饰键,用户可以按任意顺序按下它们。您需要进行一些过滤以确保第 4 次按键不会再次产生匹配,这是接受答案的问题。而且右移键比较难,按下时报Keys.Shift。这需要 pinvoke 来检查密钥是否已关闭。

    效果很好:

    Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
        If Control.ModifierKeys = (Keys.Control Or Keys.Alt Or Keys.Shift) Then
            If e.KeyCode = Keys.ControlKey Or e.KeyCode = Keys.Menu Or e.KeyCode = Keys.ShiftKey Then
                If GetKeyState(Keys.RShiftKey) < 0 And GetKeyState(Keys.LShiftKey) >= 0 Then
                    MessageBox.Show("yada")
                End If
            End If
        End If
    End Sub
    
    Private Declare Function GetKeyState Lib "user32.dll" (ByVal key As Keys) As Short
    

    这通过首先验证所有三个修饰键都已按下来起作用。然后它会检查最后按下的键是否是三个键中的 一个,该过滤可确保您不会获得太多匹配项。最后,它会检查右移键是否按下,并且按下左移键是否也没有到达那里。

    【讨论】:

    • 感谢 Hans,您的示例也按预期工作,但 Yuri 首先回复。
    • 答案不一样。
    • 当然不是,但都基于 user32.dll 和众所周知的 GetKeyState。你觉得 Yuri 的解决方案不够好?通过测试,它表现良好。
    • 我不知道我是否理解得很好,但是如果我按 RShift 然后按 Control 然后按 Alt,您的示例也可以工作,但我认为没关系...
    • 最好是,你不能指望用户选择正确的订单。
    【解决方案3】:

    看看这个:

        If e.Control And e.Alt And e.KeyCode = Keys.ShiftKey Then
            MsgBox("CTRL + ALT + SHIFT") ' This work
            Debug.Print("CTRL + ALT + SHIFT" & GetAsyncKeyState(Keys.ShiftKey) & GetAsyncKeyState(Keys.RShiftKey)) 
        End If
    
        If e.Control And e.Alt And e.KeyCode = Keys.RShiftKey Then
            MsgBox("CTRL + ALT + RIGHT SHIFT") ' This don't work
            Debug.Print("CTRL + ALT + RIGHT SHIFT " & GetAsyncKeyState(Keys.ShiftKey) & GetAsyncKeyState(Keys.RShiftKey))
        End If
    

    您将看到 Keys.ShiftKey 的值对于左右是相同的。 Keys.RShiftKey 的测试发生了变化。 API 调用需要上面的 DECLARE。

    【讨论】:

    • 有趣的实验给出了“可行的这个”:如果 e.Control And e.Alt And GetAsyncKeyState(Keys.RShiftKey) Then...
    猜你喜欢
    • 1970-01-01
    • 2018-10-13
    • 2014-01-11
    • 1970-01-01
    • 2014-01-09
    • 2010-11-23
    • 1970-01-01
    • 2011-02-17
    相关资源
    最近更新 更多