我有以下代码,可以在按下CTRL + B后最小化主程序时将外部窗口中的选定文本复制到剪贴板。 它适用于记事本,文字等程序。但是对于像chrome这样的其他程序,该函数无法获取所选文本。 有什么建议吗?
我的程序代码,它只有一个表单: 公共类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 GetWindowThreadProcessId Lib "User32" (ByVal hWnd As IntPtr, ByVal ProcessID As Integer) As Integer
Private Declare Function GetGUIThreadInfo Lib "User32" (ByVal ThreadID As Integer, ByRef Info As InfoStruct) As Boolean
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 Declare Function SendMessageA Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
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 Const EM_GETSEL As Integer = &HB0
Private Const WM_HOTKEY As Integer = &H312
Private Const WM_GETTEXT As Integer = &HD
Private Const WM_GETTEXTLENGTH As Integer = &HE
Private HotKeyID As Integer = 1
Private Sub PutTextInClipboard()
Dim ParentHandle As IntPtr = GetForegroundWindow
If ParentHandle <> IntPtr.Zero Then
Dim RightControl As IntPtr = SetectTheRightControl(ParentHandle)
If Not RightControl = IntPtr.Zero Then
Dim S As Selection = GetSelection(RightControl)
If S.End <> S.Start Then
Dim SelectedText As String = GetTheText(RightControl, S)
My.Computer.Clipboard.Clear()
My.Computer.Clipboard.SetText(SelectedText)
End If
End If
End If
End Sub
Private Function SetectTheRightControl(ByVal hWnd As IntPtr) As IntPtr
Dim ThreadID As Integer = GetWindowThreadProcessId(hWnd, Nothing)
Dim InfoStructure As New InfoStruct
Dim i As Integer = IntPtr.Size
InfoStructure.cbSize = 24 + 6 * i
If GetGUIThreadInfo(ThreadID, InfoStructure) Then
Return InfoStructure.Caret
End If
End Function
Private Function GetTheText(ByVal hWnd As IntPtr, ByVal Sel As Selection) As String
Dim TxtLength As Integer = SendMessageA(hWnd, WM_GETTEXTLENGTH, Nothing, Nothing)
Dim Ptr As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal(TxtLength + 1)
Dim LengthCopied As Integer = SendMessageA(hWnd, WM_GETTEXT, CType(TxtLength + 1, IntPtr), Ptr)
Dim ByteTxt(LengthCopied) As Byte
Runtime.InteropServices.Marshal.Copy(Ptr, ByteTxt, 0, LengthCopied)
Runtime.InteropServices.Marshal.FreeHGlobal(Ptr)
Dim Txt As String = New String(ByteTxt.Select(Function(b) Chr(b)).ToArray)
Return Txt.Substring(Sel.Start, Sel.End - Sel.Start)
End Function
Private Function GetSelection(ByVal hWnd As IntPtr) As Selection
Dim Result As Integer = SendMessageA(hWnd, EM_GETSEL, Nothing, Nothing)
Dim Sel As New Selection
Sel.Start = Result And &HFFFF
Sel.End = Result >> 16
Return Sel
End Function
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_HOTKEY Then
Dim Modif = (CType(m.LParam, Integer) And &HFFFF)
Dim Key = CType(m.LParam, Integer) >> 16
If Key = VK_b And Modif = MOD_CONTROL Then
PutTextInClipboard()
End If
Else
MyBase.WndProc(m)
End If
End Sub
Private Structure Selection
Public Start As Integer
Public [End] As Integer
End Structure
Private Structure InfoStruct
Public cbSize As Integer
Public flag As Integer
Public Active As IntPtr
Public Focus As IntPtr
Public Capture As IntPtr
Public Menu As IntPtr
Public Move As IntPtr
Public Caret As IntPtr
Public CaretRect As Rectangle
End Structure End Class