【问题标题】:Are some modifiers not supported by SendKeys.SendWait?SendKeys.SendWait 不支持某些修饰符吗?
【发布时间】:2019-07-28 14:31:16
【问题描述】:

我有一个完美运行的代码,从任何 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 不会复制选定的文本:有人可以给我一个线索吗? 谢谢

【问题讨论】:

  • SendKeys.SendWait("") SendKeys.SendWait("^c")。如果你用MOD_ALT Or MOD_CONTROL注册了热键,那就是。这里没有显示。您在代码中仅将 MOD_CONTROL 显示为键修饰符。我还建议使用 .Net 声明而不是使用 VB6 样式。 UInteger 不是 Integer
  • 嗯,我的意思是MOD_ALT Or MOD_SHIFT,当然。这里是一样的,但你应该有Dim Modif As Integer = (CType(m.LParam, Integer) And &amp;HFF)
  • 使用MOD_CONTROL Or MOD_SHIFT 作为修饰符会得到更好的结果。另外,请阅读SendKeys.SendWait() 的备注部分。
  • 谢谢 Jimi,当然,当我尝试不同的修饰符时,我确实使用该修饰符注册了热键。实际上,问题不在于键捕获:如果我使用 ALT+SHIFT+键注册一个键,则该组合将起作用,并且程序流程进入命令 SendKeys.SenWait("^c"): 是发送键不起作用。它似乎只有在我用 CTRL 捕获热键时才有效
  • 它确实有效。我说CTRL + SHIFT 的组合效果更好,因为使用ALT + SHIFT,在第一次执行后,前景窗口不再是 ForegroundWindow(即使它看起来是)。用记事本试试。使用热键发送CTRL-C,然后单击桌面,再次在记事本中,然后再次按下ALT+SHIFT+B。你会看到它再次起作用。有这个小问题。在再次激活热键之前,您必须存储 ForegroundWindow 的句柄并再次激活它。除非新的 ForegroundWindow 句柄是当前句柄。

标签: windows vb.net text copy sendkeys


【解决方案1】:

最后我设法让它工作添加行:

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

【讨论】:

    猜你喜欢
    • 2018-05-09
    • 2021-12-07
    • 2020-08-04
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多