从任何窗口VB.net获取所选文本

时间:2014-08-11 20:09:25

标签: c# vb.net windows text copy

我有以下代码,可以在按下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

0 个答案:

没有答案