/// <summary>
        /// デスクトップアイコンのテキストを取得します。
        /// </summary>
        /// <param name="index">デスクトップアイコンのインデックス。</param>
        /// <returns>デスクトップアイコンのテキスト。</returns>
        static string GetDesktopIconText(int index)
        {
            using (var lviMem = DesktopListViewMemory.Allocate(IntPtr.Zero, Marshal.SizeOf(new Win32Api.LVITEM()), Win32Api.MEM_COMMIT, Win32Api.PAGE_READWRITE))
            {
                using (var txtMem = DesktopListViewMemory.Allocate(IntPtr.Zero, sizeof(char) * (Win32Api.MAX_LVMSTRING + 1), Win32Api.MEM_COMMIT, Win32Api.PAGE_READWRITE))
                {
                    // テキストを受け取るためのLVITEM構造体を生成しリストビューのプロセスのメモリにコピー。
                    Win32Api.LVITEM listviewItem = new Win32Api.LVITEM()
                    {
                        cchTextMax = Win32Api.MAX_LVMSTRING, iSubItem = 0, pszText = txtMem.Ptr
                    };
                    Win32Api.WriteProcessMemory(lviMem.ProcessPtr, lviMem.Ptr, ref listviewItem, Marshal.SizeOf(listviewItem), IntPtr.Zero);

                    // テキスト取得
                    Win32Api.SendMessage(Win32Util.GetDesktopListView(), Win32Api.LVM_GETITEMTEXTW, index, lviMem.Ptr);

                    // string型に変換
                    var strBuf = new StringBuilder(Win32Api.MAX_LVMSTRING);
                    if (!Win32Api.ReadProcessMemory(txtMem.ProcessPtr, txtMem.Ptr, strBuf, strBuf.Capacity, IntPtr.Zero))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    return(strBuf.ToString());
                }
            }
        }
        /// <summary>
        /// VirtualAllocExのラッパー。メモリ割り当てに失敗するとWin32Exceptionをスローします。
        /// </summary>
        public static DesktopListViewMemory Allocate(IntPtr lpAddress, int dwSize, int flAllocationType, int flProtect)
        {
            int pid;

            Win32Api.GetWindowThreadProcessId(Win32Util.GetDesktopListView(), out pid);
            var hProc = Win32Api.OpenProcess(Win32Api.PROCESS_VM_OPERATION |
                                             Win32Api.PROCESS_VM_READ |
                                             Win32Api.PROCESS_VM_WRITE |
                                             Win32Api.PROCESS_QUERY_INFORMATION, false, pid);

            if (hProc == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            var result = new DesktopListViewMemory();

            result.ProcessPtr = hProc;
            result.Ptr        = Win32Api.VirtualAllocEx(hProc, lpAddress, dwSize, flAllocationType, flProtect);
            if (result.Ptr == IntPtr.Zero)
            {
                result.Dispose();
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return(result);
        }
        /// <summary>
        /// デスクトップアイコンの座標を取得します。
        /// </summary>
        /// <param name="index">デスクトップアイコンのインデックス。</param>
        /// <returns>デスクトップアイコンの座標。</returns>
        static Point GetDesktopIconLocation(int index)
        {
            using (var mem = DesktopListViewMemory.Allocate(IntPtr.Zero, Marshal.SizeOf(Point.Empty), Win32Api.MEM_COMMIT, Win32Api.PAGE_READWRITE))
            {
                Point result = Point.Empty;
                Win32Api.SendMessage(Win32Util.GetDesktopListView(), Win32Api.LVM_GETITEMPOSITION, index, mem.Ptr);

                if (!Win32Api.ReadProcessMemory(mem.ProcessPtr, mem.Ptr, out result, Marshal.SizeOf(result), IntPtr.Zero))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                return(result);
            }
        }