using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace WinShell {
    /// <summary>
    /// 
    /// </summary>
    public class API {
        #region API 앉짫
        /// <summary>
        /// 
        /// </summary>
        public const int MAX_PATH = 260;
        /// <summary>
        /// 
        /// </summary>
        public const int S_OK = 0;
        /// <summary>
        /// 
        /// </summary>
        public const int S_FALSE = 1;
        /// <summary>
        /// 
        /// </summary>
        public const uint CMD_FIRST = 1;
        /// <summary>
        /// 
        /// </summary>
        public const uint CMD_LAST = 30000;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ppshf"></param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern Int32 SHGetDesktopFolder(out IntPtr ppshf);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pstr"></param>
        /// <param name="pidl"></param>
        /// <param name="pszBuf"></param>
        /// <param name="cchBuf"></param>
        /// <returns></returns>
        [DllImport("Shlwapi.Dll", CharSet = CharSet.Auto)]
        public static extern Int32 StrRetToBuf(IntPtr pstr, IntPtr pidl, StringBuilder pszBuf, int cchBuf);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="nFolder"></param>
        /// <param name="ppidl"></param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern int SHGetSpecialFolderLocation(IntPtr handle, CSIDL nFolder, out IntPtr ppidl);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ppidl"></param>
        /// <param name="dwFileAttributes"></param>
        /// <param name="sfi"></param>
        /// <param name="cbFileInfo"></param>
        /// <param name="uFlags"></param>
        /// <returns></returns>
        [DllImport("shell32",
            EntryPoint = "SHGetFileInfo",
            ExactSpelling = false,
            CharSet = CharSet.Auto,
            SetLastError = true)]
        public static extern IntPtr SHGetFileInfo(
            IntPtr ppidl,
            FILE_ATTRIBUTE dwFileAttributes,
            ref SHFILEINFO sfi,
            int cbFileInfo,
            SHGFI uFlags);
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [DllImport("user32",
            SetLastError = true,
            CharSet = CharSet.Auto)]
        public static extern IntPtr CreatePopupMenu();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hmenu"></param>
        /// <param name="flags"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="hwnd"></param>
        /// <param name="lptpm"></param>
        /// <returns></returns>
        [DllImport("user32.dll",
            ExactSpelling = true,
            CharSet = CharSet.Auto)]
        public static extern uint TrackPopupMenuEx(
            IntPtr hmenu,
            TPM flags,
            int x,
            int y,
            IntPtr hwnd,
            IntPtr lptpm);

        #endregion

        /// <summary>
        ///Shell
        /// </summary>
        public static IShellFolder GetDesktopFolder(/*out IntPtr ppshf*/) {
            IntPtr ppshf;
            SHGetDesktopFolder(out ppshf);
            Object obj = Marshal.GetObjectForIUnknown(ppshf);
            return (IShellFolder)obj;
        }
        /// <summary>
        /// 몽앴쨌쓺삿혤 IShellFolder 뵨 PIDL
        /// </summary>
        public static IShellFolder GetShellFolder(IShellFolder desktop, string path, out IntPtr Pidl)
        {
            IShellFolder IFolder;
            uint i, j = 0;
            desktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, path, out i, out Pidl, ref j);
            desktop.BindToObject(Pidl, IntPtr.Zero, ref Guids.IID_IShellFolder, out IFolder);
            return IFolder;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Root"></param>
        /// <param name="pidlSub"></param>
        /// <returns></returns>
        public static string GetNameByIShell(IShellFolder Root, IntPtr pidlSub) {
            IntPtr strr = Marshal.AllocCoTaskMem(MAX_PATH * 2 + 4);
            Marshal.WriteInt32(strr, 0, 0);
            StringBuilder buf = new StringBuilder(MAX_PATH);
            Root.GetDisplayNameOf(pidlSub, SHGNO.INFOLDER, strr);
            API.StrRetToBuf(strr, pidlSub, buf, MAX_PATH);
            return buf.ToString();
        }

        /// <summary>
        ///
        /// </summary>
        public static string GetNameByPIDL(IntPtr pidl) {
            SHFILEINFO info = new SHFILEINFO();
            API.SHGetFileInfo(pidl, 0, ref info, Marshal.SizeOf(typeof(SHFILEINFO)),
                SHGFI.PIDL | SHGFI.DISPLAYNAME | SHGFI.TYPENAME);
            return info.szDisplayName;
        }

    }
}
