public static int ShowContextMenu(IntPtr hwnd, string[] strFiles, int intX, int intY, bool blnErrorBeep)
        {
            CMINVOKECOMMANDINFO CI = new CMINVOKECOMMANDINFO();

            DirectoryInfo dInfo;

            FileInfo fInfo;

            IContextMenu CM;              // LPCONTEXTMENU

            int cmdID;                    // LongBool
            int pchEaten     = 0;         // DWORD pchEaten;
            int dwAttributes = new int(); // ULONG
            int intZero      = 0;
            int intCount;

            IntPtr ipParent = new IntPtr(); // LPITEMIDLIST
            IntPtr ipChild  = new IntPtr(); // LPITEMIDLIST
            IntPtr hMenu    = new IntPtr(); // HMENU
            //IntPtr ipPath = new IntPtr();
            //IntPtr ipFileName = new IntPtr();

            IShellFolder DesktopFolder = null; // IShellFolder
            IShellFolder ParentFolder  = null; // IShellfolder ParentFolder

            Rect mRect;

            REFIID IID_IShellFolder = new REFIID("000214E6-0000-0000-c000-000000000046");
            REFIID IID_IContextMenu = new REFIID("000214E4-0000-0000-c000-000000000046");

            string strFullName = "";
            string strFilePath = "";
            string strFileName = "";
            string strFQName   = "";

            m_pidlCount = 0;

            for (intCount = 0; intCount <= strFiles.GetUpperBound(0); intCount++)
            {
                strFullName = strFiles[intCount];

                fInfo = new FileInfo(strFullName);

                if (fInfo.Exists)
                {
                    strFilePath = fInfo.DirectoryName;
                    strFileName = fInfo.Name;
                    strFQName   = fInfo.FullName;
                }
                else
                {
                    dInfo = new DirectoryInfo(strFullName);
                    if (dInfo.Exists)
                    {
                        try
                        {
                            strFileName = dInfo.Name;
                            strFilePath = dInfo.Parent.FullName;
                        }
                        catch
                        {
                            strFilePath = "";
                        }
                    }
                }

                SHGetDesktopFolder(ref DesktopFolder);

                // ParseDisplayName - parent
                // Translates a file object's or folder's display name into an item identifier list
                pchEaten     = 1;
                dwAttributes = 0;
                ipParent     = new IntPtr();
                DesktopFolder.ParseDisplayName(hwnd, IntPtr.Zero, strFilePath, ref pchEaten, ref ipParent, ref dwAttributes);

                // BindToObject
                // Retrieves an IShellFolder object for a subfolder
                ParentFolder = null;
                DesktopFolder.BindToObject(ipParent, IntPtr.Zero, ref IID_IShellFolder, ref ParentFolder);

                // ParseDisplayName - child
                // Translates a file object's or folder's display name into an item identifier list
                pchEaten     = 1;
                dwAttributes = 0;
                ipChild      = new IntPtr();
                ParentFolder.ParseDisplayName(hwnd, IntPtr.Zero, strFileName, ref pchEaten, ref ipChild, ref dwAttributes);

                JAddItemToIDList(ipChild);
            }

            CM = null;

            int intReturn = ParentFolder.GetUIObjectOf(hwnd, m_pidlCount, ref m_ipList[0], ref IID_IContextMenu, out intZero, ref CM);

            if (CM != null)
            {
                hMenu = CreatePopupMenu();

                CM.QueryContextMenu(hMenu, 0, MIN_SHELL_ID, MAX_SHELL_ID, QueryContextMenuFlags.CMF_EXPLORE);

                cmdID = TrackPopupMenu(hMenu, (TPM_RETURNCMD | TPM_LEFTALIGN), intX, intY, 0, hwnd, out mRect);

                if (cmdID != 0)
                {
                    CI.cbSize       = Marshal.SizeOf(CI);
                    CI.hwnd         = hwnd;
                    CI.lpVerb       = (IntPtr)MAKEINTRESOURCE(cmdID - 1);
                    CI.lpParameters = IntPtr.Zero;
                    CI.lpDirectory  = IntPtr.Zero;
                    CI.nShow        = SW_SHOWNORMAL;
                    CM.InvokeCommand(ref CI);
                }
            }
            else
            {
                if (blnErrorBeep)
                {
                    MessageBeep(-1);
                }
            }
            return(0);
        }