我想获取treeview所有节点的文本
现在有两个问题: 
1   GetItemText  获得的文本全是乱码
2   遍历不能获得所有的节点  应该是有逻辑错误        public  void  Bianli(IntPtr Root,IntPtr TreeViewHwnd)
        {
            IntPtr XD = GetNextItem(TreeViewHwnd, Root);
            if (!XD.Equals(IntPtr.Zero))  //当前节点是否有兄弟节点
                Bianli(XD, TreeViewHwnd);
            IntPtr CHILD = GetCHILDItem(TreeViewHwnd, Root);
            if (!CHILD.Equals(IntPtr.Zero))  //当前节点是否有子节点
                Bianli(TreeViewHwnd, CHILD);            s += GetItemText(TreeViewHwnd, Root);
        }
        //获取下一个同级节点
        public static IntPtr GetNextItem(IntPtr TreeViewHwnd, IntPtr PrevHwnd)
        {
            int mbHwnd = 0;
            mbHwnd = SendMessage(TreeViewHwnd.ToInt32(), TVM_GETNEXTITEM, new IntPtr(TVGN_NEXT), PrevHwnd);
            return new IntPtr(mbHwnd);
        }
        //获取第一个子节点
        public static IntPtr GetCHILDItem(IntPtr TreeViewHwnd, IntPtr PrevHwnd)
        {
            int mbHwnd = 0;
            mbHwnd = SendMessage(TreeViewHwnd.ToInt32(), TVM_GETNEXTITEM, new IntPtr(TVGN_CHILD), PrevHwnd);
            return new IntPtr(mbHwnd);
        }
        //获取指定项文本
        public static string GetItemText(IntPtr TreeViewHwnd, IntPtr ItemHwnd)
        {
            IntPtr hStr = Marshal.AllocHGlobal(1024);
            TVITEM tv = new TVITEM();
            tv.hItem = ItemHwnd;
            tv.mask = TVIF_TEXT;
            tv.pszText = hStr;
            tv.cchTextMax = 1024;
            StringBuilder sb = new StringBuilder(1024);
            int result = SendMessage(TreeViewHwnd.ToInt32(), TVM_GETITEM, new IntPtr(0), tv);
            int iCopy = CopyMemory(sb, hStr, 1024);
            Marshal.FreeHGlobal(hStr);
            return sb.ToString();
        }

解决方案 »

  1.   

    是 C# 的 TreeView 吗,如果是递归遍历就行了
      

  2.   

    是另外一个程序里的SysTreeView32控件,需要跨进称操作 所以需要引用win32api  
      

  3.   

    1、获取TreeView文本涉及到跨进程读取内存的问题,得这么做(有一些WINAPI的方法和常数你自己找找):public static string GetItemText(IntPtr TreeViewHwnd, int ItemHwnd)
    {
    string output = string.Empty; uint vProcessId;
    /* WINAPI */ GetWindowThreadProcessId(TreeViewHwnd, out vProcessId);
    IntPtr vProcess = /* WINAPI */ OpenProcess(
    PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
    false,
    vProcessId
    );
    IntPtr vPointer = /* WINAPI */ VirtualAllocEx(
    vProcess,
    IntPtr.Zero,
    4096,
    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE
    ); try
    {
    byte[] vBuffer = new byte[1024];
    LVITEM[] vItem = new LVITEM[1];
    vItem[0] = new LVITEM();
    vItem[0].mask = LVIF_TEXT;
    vItem[0].ItemHwnd = ItemHwnd;
    vItem[0].iSubItem = 0;
    vItem[0].pszText = (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(LVITEM)));
    vItem[0].cchTextMax = vBuffer.Length;
    uint vNumberOfBytesRead = 0;
    /* WINAPI */ WriteProcessMemory(
    vProcess,
    vPointer,
    Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0),
    (uint)Marshal.SizeOf(typeof(LVITEM)),
    out vNumberOfBytesRead
    );
    SendMessage(TreeViewHwnd, LVM_GETITEMW, IntPtr.Zero, vPointer);
    /* WINAPI */ ReadProcessMemory(
    vProcess,
    new IntPtr(vPointer.ToInt32() + Marshal.SizeOf(typeof(LVITEM))),
     Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0),
    (uint)vBuffer.Length,
    out vNumberOfBytesRead
    ); output = Marshal.PtrToStringAuto(Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0));
    }
    finally
    {
    /* WINAPI */ VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
    /* WINAPI */ CloseHandle(vProcess);
    } return output;
    }
    2、递归应该是先遍历当前节点的所有子节点,再遍历其兄弟节点,大概是这样public  void  Bianli(IntPtr Root,IntPtr TreeViewHwnd)
    {
    IntPtr CHILD = IntPtr.Zero;
    do
    {
    CHILD = GetCHILDItem(TreeViewHwnd, Root);
    if (!CHILD.Equals(IntPtr.Zero))  //当前节点是否有子节点
    Bianli(TreeViewHwnd, CHILD);
    }
    while (!CHILD.Equals(IntPtr.Zero));
    IntPtr XD = IntPtr.Zero;
    do
    {
    XD = GetNextItem(TreeViewHwnd, Root);
    if (!XD.Equals(IntPtr.Zero))  //当前节点是否有兄弟节点
    Bianli(XD, TreeViewHwnd);
    }
    while (!XD.Equals(IntPtr.Zero));
    s += GetItemText(TreeViewHwnd, Root);
    }
      

  4.   

    楼上用的应该是listview吧 ,不知道treeview结果怎么样  先试试再说
      

  5.   

    Sorry,贴错鸟。TV和LV我都搞过,差不多的public static string GetItemText(IntPtr TreeViewHwnd, IntPtr ItemHwnd)
    {
    string output = string.Empty; uint vProcessId;
    /* WINAPI */ GetWindowThreadProcessId(TreeViewHwnd, out vProcessId);
    IntPtr vProcess = /* WINAPI */ OpenProcess(
    PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
    false,
    vProcessId
    );
    IntPtr vPointer = /* WINAPI */ VirtualAllocEx(
    vProcess,
    IntPtr.Zero,
    4096,
    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE
    ); try
    {
    byte[] vBuffer = new byte[1024];
    TVITEM[] vItem = new TVITEM[1];
    vItem[0] = new TVITEM();
    vItem[0].mask = TVIF_TEXT;
    vItem[0].hItem = ItemHwnd;
    vItem[0].pszText = (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(TVITEM)));
    vItem[0].cchTextMax = vBuffer.Length;
    uint vNumberOfBytesRead = 0;
    /* WINAPI */ WriteProcessMemory(
    vProcess,
    vPointer,
    Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0),
    (uint)Marshal.SizeOf(typeof(TVITEM)),
    out vNumberOfBytesRead
    );
    SendMessage(TreeViewHwnd, TVM_GETITEMW, IntPtr.Zero, vPointer);
    /* WINAPI */ ReadProcessMemory(
    vProcess,
    new IntPtr(vPointer.ToInt32() + Marshal.SizeOf(typeof(TVITEM))),
     Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0),
    (uint)vBuffer.Length,
    out vNumberOfBytesRead
    ); output = Marshal.PtrToStringAuto(Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0));
    }
    finally
    {
    /* WINAPI */ VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
    /* WINAPI */ CloseHandle(vProcess);
    } return output;
    }
      

  6.   

    WriteProcessMemory这个方法的第三个参数是byte[]数组类型
    而Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0)返回值为IntPtr类型
    这个怎么转换啊
    WriteProcessMemory和ReadProcessMemory的最后一个参数都是out vNumberOfBytesRead
    但是一个要求int  一个要求UIntPtr类型,肿么弄?
      

  7.   

    我是这样定义的[DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool ReadProcessMemory(
        IntPtr hProcess,
        IntPtr lpBaseAddress,
        IntPtr lpBuffer,
        uint nSize,
        out uint lpNumberOfBytesRead
        );[DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool WriteProcessMemory(
        IntPtr hProcess,
        IntPtr lpBaseAddress,
        IntPtr lpBuffer,
        uint nSize,
        out uint lpNumberOfBytesWritten
        );
      

  8.   

    悲剧了,我这里还是获取不到,文本为空,不知道方便把你的样例发给我研究不?
    [email protected]
      

  9.   

    现在已经可以获取到文本了,但是双击事件怎么响应呢?SendInput又得有坐标
    不知道这个treeview的每一个文本是不是对应一个value  怎么获取呢?