c# 用 win32 api treeview 遍历解决思路

c# 用 win32 api treeview 遍历
我想获取treeview所有节点的文本
现在有两个问题: 
1 GetItemText 获得的文本全是乱码
2 遍历不能获得所有的节点 应该是有逻辑错误
C# code

        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();
        }



------解决方案--------------------
Sorry,贴错鸟。TV和LV我都搞过,差不多的
C# code

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;
}