SendKeys.SendWait不支持某些修饰符吗?

时间:2019-07-28 14:31:16

标签: windows vb.net text copy sendkeys

我有一个完美的代码,可以从任何Windows应用程序中按CTRL + B复制所选文本。 但是,当我将触发SendKeys.SendWait(“ ^ c”)的修改器从MOD_CONTROL更改为MOD_ALT + MOD_SHIFT时,命令SendKeys不会从活动窗口复制文本。 因此,按ALT + SHIFT + B仍会启动命令SendKeys,但该命令不会将所选文本复制到剪贴板。 sendkeys命令和除MOD_CONTROL之外的其他修饰符之间是否存在某些不兼容?

我尝试注册不同的热键,以及为每个热键使用不同的修饰符:sendkeys可以与具有MOD_CONTROL修饰符的每个热键一起使用,但不适用于具有其他修饰符组合的每个热键。

Public Class Form1  
 Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing  
    UnregisterHotKey(Nothing, HotKeyID)  
End Sub  

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
    RegisterHotKey(Me.Handle, HotKeyID, MOD_CONTROL, VK_b)  
End Sub  

Private Declare Function GetForegroundWindow Lib "User32" () As IntPtr  
Private Declare Function RegisterHotKey Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal ID As Integer, ByVal Modifiers As UInteger, ByVal VK As UInteger) As Boolean  
Private Declare Function UnregisterHotKey Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal ID As Integer) As Boolean  

Private HotKeyID As Integer = 1  
Private Const WM_HOTKEY As Integer = &H312  
Private Const MOD_ALT As UInteger = 1
Private Const MOD_CONTROL As UInteger = 2  
Private Const MOD_SHIFT As UInteger = 4    
Private Const VK_b As UInteger = &H42  

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)  
    If m.Msg = WM_HOTKEY Then  
        Dim Modif As UInteger = (CType(m.LParam, Integer) And &HFFFF)  
        Dim Key As UInteger = CType(m.LParam, Integer) >> 16  
        If Key = VK_b And Modif = MOD_CONTROL Then  

            'Check foregroundwindow has a valid handle  
            If GetForegroundWindow <> IntPtr.Zero Then  
                'Send the Ctrl+C command to the active window  
                SendKeys.SendWait("^c")  
            End If  

        End If  
    Else  
        MyBase.WndProc(m)  
    End If  
End Sub  
End Class

如果我改变

        If Key = VK_b And Modif = MOD_CONTROL Then  

            'Check foregroundwindow has a valid handle  
            If GetForegroundWindow <> IntPtr.Zero Then  
                'Send the Ctrl+C command to the active window  
                SendKeys.SendWait("^c")  
            End If  
          End If  

使用:

        If Key = VK_b And Modif = MOD_ALT + MOD_SHIFT Then  

            'Check foregroundwindow has a valid handle  
            If GetForegroundWindow <> IntPtr.Zero Then  
                'Send the Ctrl+C command to the active window  
                SendKeys.SendWait("^c")  
            End If  
          End If  

SendKeys.SendWait命令不会复制所选文本:有人可以给我一个提示吗? 谢谢

1 个答案:

答案 0 :(得分:0)

最后,我设法使其能够添加以下行:

System.Threading.Thread.Sleep(300)

在命令SendKeys.SendWait(“ ^ c”)之前

似乎SendKeys的时间安排有问题,插入的暂停可以解决问题。 因此,现在这段代码可以工作了:

Public Class Form1  
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    UnregisterHotKey(Nothing, HotKeyID)
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    RegisterHotKey(Me.Handle, HotKeyID, MOD_ALT + MOD_SHIFT, VK_b)
End Sub

Private Declare Function GetForegroundWindow Lib "User32" () As IntPtr
Private Declare Function RegisterHotKey Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal ID As Integer, ByVal Modifiers As UInteger, ByVal VK As UInteger) As Boolean
Private Declare Function UnregisterHotKey Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal ID As Integer) As Boolean

Private Const WM_HOTKEY As Integer = &H312
Private Const MOD_ALT As UInteger = 1
Private Const MOD_CONTROL As UInteger = 2
Private Const MOD_SHIFT As UInteger = 4
Private Const VK_b As UInteger = 66
Private HotKeyID As Integer = 1

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If m.Msg = WM_HOTKEY Then
        Dim Modif As UInteger = (CType(m.LParam, Integer) And &HFFFF)
        Dim Key As UInteger = CType(m.LParam, Integer) >> 16
        If Key = VK_b And Modif = MOD_ALT + MOD_SHIFT Then
            'Check foregroundwindow has a valid handle  
            If GetForegroundWindow <> IntPtr.Zero Then
                'Send the Ctrl+C command to the active window
                System.Threading.Thread.Sleep(300)
                SendKeys.SendWait("^c")
            End If
        End If
    Else
        MyBase.WndProc(m)
    End If
End Sub
End Class