Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.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# 双击treeview win32 api中的选定项_C#_Winapi_Treeview_Selecteditem_Selected - Fatal编程技术网

C# 双击treeview win32 api中的选定项

C# 双击treeview win32 api中的选定项,c#,winapi,treeview,selecteditem,selected,C#,Winapi,Treeview,Selecteditem,Selected,我想用winapi向其他应用程序中的treeview中的选定项发送有关鼠标双击的消息 如何在其他应用程序中获取treeview中所选项目的句柄? p、 在spy++中,我只获得treeview的句柄 谢谢大家! 这最好使用,它公开了对UI元素的访问,如和,使用COM接口: 通过CoCreateInstance()创建CUIAutomationCOM对象的实例,并获取其IUIAutomation接口 调用其ElementFromHandle()方法来检索TreeView窗口的IUIAutom

我想用winapi向其他应用程序中的treeview中的选定项发送有关鼠标双击的消息

  • 如何在其他应用程序中获取treeview中所选项目的句柄?
p、 在spy++中,我只获得treeview的句柄


谢谢大家!

这最好使用,它公开了对UI元素的访问,如和,使用COM接口:

  • 通过
    CoCreateInstance()
    创建
    CUIAutomation
    COM对象的实例,并获取其
    IUIAutomation
    接口

  • 调用其
    ElementFromHandle()
    方法来检索TreeView窗口的
    IUIAutomationeElement
    接口

  • 调用其
    FindFirst()
    方法以查找第一个选定项并获取其
    IUIAutomationeElement
    接口

  • 调用其
    GetCurrentPattern()
    方法以获取
    Invoke
    控制模式的
    IUnknown
    接口

  • 查询它的
    IUIAutomationInvokePattern
    接口,然后调用它的
    Invoke()
    方法

但是,如果您只想使用窗口消息,可以执行以下操作:

  • 使用消息获取所选项目,为
    wParam
    指定
    TVGN\u插入符号

  • 使用消息获取TreeView客户端区域内项目文本的矩形,为其
    wParam
    指定TRUE

    但是,这需要跨流程边界手动封送
    RECT
    ,因为
    RECT
    必须存在于拥有TreeView的同一流程中

    • 使用
      GetWindowThreadProcessId()
      获取拥有TreeView的进程的ID

    • 使用
      OpenProcess()
      获取进程ID的
      句柄
      ,请求
      process\u VM\u操作
      process\u VM\u读取
      访问

    • 使用
      VirtualAllocEx()
      在过程中分配
      RECT

    • TVM\u GETITEMRECT

    • 使用
      ReadProcessMemory()
      读取
      RECT
      数据

    • 使用
      VirtualFreeEx()释放内存

    • 使用
      CloseHandle()
      关闭进程句柄

  • 向TreeView窗口发送消息,指定项目文本矩形内的X、Y坐标


我知道这很旧,但我尝试了很多方法让它在VB.net中工作。我需要为RECT创建两个不同的结构,因为它使用长参数为RECT位置返回错误的值。 下面是一个例子,您可以轻松地转换为C#

Private子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击
Dim SelNodeRectangle As RECT=GetTreeViewSelectedNode直立(TreeViewWPTR)
端接头
Private Const TV_FIRST作为整数=&H1100
Private Const TVGN_插入符号为整数=&H9
Private Const TVM_GETNEXTITEM作为整数=(TV_FIRST+10)
Private Const TVM_GETITEMRECT作为整数=(TV_FIRST+4)
私有常量进程\u VM\u操作为整数=&H8
私有常量进程\u VM\u读取为整数=&H10
私有常量进程\u VM\u WRITE=(&H20)
Private Const PAGE_READWRITE As Long=&H4
Private Const MEM_COMMIT As Long=&H1000&
私有Const MEM_释放长度=&H8000&
私有结构指针
公共左As IntPtr
端部结构
私有结构
公共左整数
作为整数的公共Top
作为整数的公权
公共底部为整数
端部结构
公共枚举分配类型
提交=&H1000
储备金=&H2000
解除承诺=&H4000
释放=&H8000
重置=&H80000
物理=&H400000
自上而下=&H100000
WriteWatch=&H200000
LargePages=&H20000000
结束枚举
将私有函数sendmagesa Lib“user32”(ByVal hWnd作为IntPtr,ByVal Msg作为Integer,ByVal wParam作为Integer,ByVal lParam作为Long)声明为IntPtr
私有声明函数WriteProcessMemory Lib“kernel32”(ByVal hProcess作为IntPtr,ByVal lpBaseAddress作为IntPtr,ByRef buffer作为RECTPointer,ByVal dwSize作为整数,ByVal lpnumberofbytes作为IntPtr)作为布尔值
私有将函数GetWindowThreadProcessId Lib“user32”(ByVal hwnd作为IntPtr,ByRef lpdwProcessID作为Integer)声明为Integer
私有函数OpenProcess Lib“kernel32”(ByVal dwDesiredAccess为整数,ByVal bInheritHandle为布尔值,ByVal dwProcessId为UInteger)声明为IntPtr
私有声明函数VirtualAllocEx Lib“kernel32”(ByVal hProcess作为IntPtr,ByVal lpAddress作为IntPtr,ByVal dwSize作为UInteger,ByVal flAllocationType作为UInteger,ByVal flProtect作为UInteger)作为IntPtr
将私有函数ReadProcessMemory Lib“kernel32”(ByVal hProcess作为整数,ByVal lpBaseAddress作为Long,ByVal lpBuffer作为Long,ByVal nSize作为整数,ByRef lpnumberofbytes作为整数)声明为整数
私有声明函数VirtualFreeEx Lib“kernel32”(ByVal hProcess As IntPtr,
ByVal lpAddress作为IntPtr,
ByVal dwSize为整数,
ByVal dwFreeType作为分配类型)作为布尔值
私有函数CloseHandle Lib“kernel32”(ByVal hObject作为IntPtr)声明为布尔值
私有函数GetTreeViewSelectedNodeBu立(TreeViewPTR作为IntPtr)作为RECT
常量dwBufferSize为整数=1024
Dim dwProcessID为整数
Dim processHandle作为IntPtr=IntPtr.Zero
Dim remotePointerBuffer As IntPtr=IntPtr.Zero
Dim localPointerBuffer为IntPtr=IntPtr.Zero
Dim threadId为IntPtr=IntPtr.Zero
localPointerBuffer=Runtime.InteropServices.Marshal.AllocHGlobal(dwBufferSize)
threadId=GetWindowThreadProcessId(TreeViewPTR,dwProcessID)
processHandle=OpenProcess(进程\虚拟机\操作+进程\虚拟机\写入+进程\虚拟机\读取,False,dwProcessID)
remotePo
 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim SelNodeRectangle As RECT = GetTreeViewSelectedNodeRECT(TreeViewPtr)
End Sub

Private Const TV_FIRST As Integer = &H1100
Private Const TVGN_CARET As Integer = &H9
Private Const TVM_GETNEXTITEM As Integer = (TV_FIRST + 10)
Private Const TVM_GETITEMRECT As Integer = (TV_FIRST + 4)

Private Const PROCESS_VM_OPERATION As Integer = &H8
Private Const PROCESS_VM_READ As Integer = &H10
Private Const PROCESS_VM_WRITE = (&H20)

Private Const PAGE_READWRITE As Long = &H4
Private Const MEM_COMMIT As Long = &H1000&
Private Const MEM_RELEASE As Long = &H8000&

Private Structure RECTPointer
    Public Left As IntPtr
End Structure

Private Structure RECT
    Public Left As Integer
    Public Top As Integer
    Public Right As Integer
    Public Bottom As Integer
End Structure

<Flags>
Public Enum AllocationType
    Commit = &H1000
    Reserve = &H2000
    Decommit = &H4000
    Release = &H8000
    Reset = &H80000
    Physical = &H400000
    TopDown = &H100000
    WriteWatch = &H200000
    LargePages = &H20000000
End Enum


Private Declare Function SendMessageA Lib "user32" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Long) As IntPtr

Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef buffer As RECTPointer, ByVal dwSize As Integer, ByVal lpNumberOfBytesWritten As IntPtr) As Boolean

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As IntPtr, ByRef lpdwProcessID As Integer) As Integer

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr

Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr

Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Long, ByVal lpBuffer As Long, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer


Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As IntPtr,
                  ByVal lpAddress As IntPtr,
                  ByVal dwSize As Integer,
                  ByVal dwFreeType As AllocationType) As Boolean


Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.Bool)> Boolean

Private Function GetTreeViewSelectedNodeRECT(TreeViewPTR As IntPtr) As RECT


    Const dwBufferSize As Integer = 1024
    Dim dwProcessID As Integer
    Dim processHandle As IntPtr = IntPtr.Zero
    Dim remotePointerBuffer As IntPtr = IntPtr.Zero
    Dim localPointerBuffer As IntPtr = IntPtr.Zero
    Dim threadId As IntPtr = IntPtr.Zero


    localPointerBuffer = Runtime.InteropServices.Marshal.AllocHGlobal(dwBufferSize)

    threadId = GetWindowThreadProcessId(TreeViewPTR, dwProcessID)

    processHandle = OpenProcess(PROCESS_VM_OPERATION + PROCESS_VM_WRITE + PROCESS_VM_READ, False, dwProcessID)


    remotePointerBuffer = VirtualAllocEx(processHandle, IntPtr.Zero, dwBufferSize, MEM_COMMIT, PAGE_READWRITE)

    Dim bSuccess As Boolean
    Dim tvItem As New RECTPointer()

    Dim SelectedNodePTR As IntPtr = SendMessageA(TreeViewPTR, TVM_GETNEXTITEM, TVGN_CARET, 0)
    tvItem.Left = SelectedNodePTR

    bSuccess = WriteProcessMemory(processHandle, remotePointerBuffer, tvItem, Runtime.InteropServices.Marshal.SizeOf(GetType(RECTPointer)), IntPtr.Zero)
    If Not bSuccess Then
        Throw New SystemException("Fail writing to process memory!")
    End If

    SendMessageA(TreeViewPTR, TVM_GETITEMRECT, 0, remotePointerBuffer)

    bSuccess = ReadProcessMemory(processHandle, remotePointerBuffer, localPointerBuffer, dwBufferSize, IntPtr.Zero)

    If Not bSuccess Then
        Throw New SystemException("Fail reading from process memory!")
    End If



    Dim returnRECT As RECT = Runtime.InteropServices.Marshal.PtrToStructure(localPointerBuffer, GetType(RECT))

    If localPointerBuffer <> IntPtr.Zero Then
        Runtime.InteropServices.Marshal.FreeHGlobal(localPointerBuffer)
    End If
    If remotePointerBuffer <> IntPtr.Zero Then
        VirtualFreeEx(processHandle, remotePointerBuffer, 0, MEM_RELEASE)
    End If
    If processHandle <> IntPtr.Zero Then
        CloseHandle(processHandle)
    End If

    Return returnRECT
End Function