Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从VB.net的任何窗口获取选定文本_C#_Vb.net_Windows_Text_Copy - Fatal编程技术网

C# 从VB.net的任何窗口获取选定文本

C# 从VB.net的任何窗口获取选定文本,c#,vb.net,windows,text,copy,C#,Vb.net,Windows,Text,Copy,我有以下代码,可以将外部窗口中选定的文本复制到剪贴板,同时在按下CTRL+B后最小化主程序。 它适用于记事本、word等程序。但是,对于其他程序(如chrome),该函数无法获取所选文本。 有什么建议吗 我的程序代码,它只有一种形式: 公开课表格1 Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormCl

我有以下代码,可以将外部窗口中选定的文本复制到剪贴板,同时在按下CTRL+B后最小化主程序。 它适用于记事本、word等程序。但是,对于其他程序(如chrome),该函数无法获取所选文本。 有什么建议吗

我的程序代码,它只有一种形式: 公开课表格1

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
Private Sub Form1\u FormClosing(ByVal sender作为对象,ByVal e作为System.Windows.Forms.FormClosingEventArgs)处理Me.FormClosing
取消注册热键(无,热键ID)
端接头
私有子表单1_Load(ByVal发送方作为System.Object,ByVal e作为System.EventArgs)处理MyBase.Load
注册表快捷键(Me.Handle、HotKeyID、MOD_控件、VK_b)
端接头
将私有函数GetWindowThreadProcessId Lib“User32”(ByVal hWnd作为IntPtr,ByVal ProcessID作为Integer)声明为Integer
将私有函数GetGuitThreadInfo Lib“User32”(ByVal ThreadID作为整数,ByRef Info作为InfoStruct)声明为布尔值
将私有函数GetForegroundWindow Lib“User32”()声明为IntPtr
将私有函数注册表项库“User32.dll”(ByVal hWnd作为IntPtr,ByVal ID作为Integer,ByVal修饰符作为UInteger,ByVal VK作为UInteger)声明为布尔值
私有声明函数unregister热键库“User32.dll”(ByVal hWnd作为IntPtr,ByVal ID作为Integer)作为布尔值
将私有函数sendmagesa Lib“User32.dll”(ByVal hWnd作为IntPtr,ByVal Msg作为Integer,ByVal wParam作为IntPtr,ByVal lParam作为IntPtr)声明为Integer
私有常量MOD_ALT As UInteger=1
专用常量MOD_控件作为UInteger=2
专用常量MOD_移位为UInteger=4
作为UInteger的专用常量VK_b=66
私有常量EM_GETSEL为整数=&HB0
Private Const WM_热键为整数=&H312
私有常量WM_GETTEXT为整数=&HD
Private Const WM_GETTEXTLENGTH作为整数=&HE
私有热键ID为整数=1
专用子剪贴板()
Dim ParentHandle作为IntPtr=GetForegroundWindow
如果ParentHandle IntPtr.Zero,则
Dim RIGHT CONTROL As IntPtr=SETECTTHERIGHT控制(父句柄)
如果不是RightControl=IntPtr.Zero,则
Dim S As Selection=GetSelection(右控制)
如果S.结束S.开始
Dim SelectedText As String=GetTheText(右控件,S)
My.Computer.Clipboard.Clear()
My.Computer.Clipboard.SetText(已选文本)
如果结束
如果结束
如果结束
端接头
专用函数将ECTTHERIGHTCONTROL(ByVal hWnd作为IntPtr)设置为IntPtr
Dim ThreadID As Integer=GetWindowThreadProcessId(hWnd,无)
Dim InfoStructure作为新的InfoStruct
尺寸i为整数=整数尺寸
InfoStructure.cbSize=24+6*i
如果GetGuitThreadInfo(线程ID、信息结构),则
Return InfoStructure.Caret
如果结束
端函数
私有函数GetTheText(ByVal hWnd作为IntPtr,ByVal Sel作为Selection)作为字符串
Dim TxtLength As Integer=SendMessageA(hWnd,WM_GETTEXTLENGTH,Nothing,Nothing)
Dim Ptr As IntPtr=Runtime.InteropServices.Marshal.AllocHGlobal(TxtLength+1)
Dim LENGTHCOPYED As Integer=SendMessageA(hWnd,WM_GETTEXT,CType(TxtLength+1,IntPtr),Ptr)
Dim ByteTxt(长度复制)作为字节
Runtime.InteropServices.Marshal.Copy(Ptr,byteText,0,lengthCopy)
Runtime.InteropServices.Marshal.FreeHGlobal(Ptr)
Dim Txt As String=新字符串(byteText.Select(Function(b)Chr(b)).ToArray)
返回Txt.Substring(Sel.Start,Sel.End-Sel.Start)
端函数
私有函数GetSelection(ByVal hWnd作为IntPtr)作为选择
Dim结果为整数=SendMessageA(hWnd,EM_GETSEL,Nothing,Nothing)
将Sel变暗作为新选择
选择开始=结果和&HFFFF
选择结束=结果>>16
返回Sel
端函数
受保护的覆盖子WndProc(ByRef m As System.Windows.Forms.Message)
如果m.Msg=WM\U热键,则
Dim Modif=(CType(m.LParam,Integer)和&HFFFF)
Dim Key=CType(m.LParam,整数)>>16
如果Key=VK_b,Modif=MOD_CONTROL,则
剪贴板()
如果结束
其他的
MyBase.WndProc(m)
如果结束
端接头
私有结构选择
公共起始为整数
公共[结束]为整数
端部结构
私有结构信息结构
公共cbSize为整数
作为整数的公共标志
作为IntPtr的公共活动
作为IntPtr的公共焦点
作为IntPtr的公共捕获
作为IntPtr的公共菜单
作为IntPtr的公共移动
公共插入符号
公共事业呈矩形
端结构端类

您是否考虑过这些应用程序可能已经使用了CTRL+B?你尝试过更奇特的组合吗?@RowlandShaw是的,我考虑过这个,我尝试过几种组合,但它仍然只适用于记事本/word之类的程序。但不是chrome或其他程序。您的
GetSelection
函数假定窗口是一个编辑控件。您应该使用UI自动化类。这似乎是你想要的。