void RemoveShellMenuItems(Menu menu)
        {
            const int    tag      = 0xAB;
            List <int>   remove   = new List <int>();
            int          count    = ShellNativeMethods.GetMenuItemCount(menu.Handle);
            MENUINFO     menuInfo = new MENUINFO();
            MENUITEMINFO itemInfo = new MENUITEMINFO();

            menuInfo.cbSize = Marshal.SizeOf(menuInfo);
            menuInfo.fMask  = MIM.MIM_MENUDATA;
            itemInfo.cbSize = (uint)Marshal.SizeOf(itemInfo);
            itemInfo.fMask  = (uint)MIIM.MIIM_ID | (uint)MIIM.MIIM_SUBMENU;

            // First, tag the managed menu items with an arbitary
            // value (0xAB).
            TagManagedMenuItems(menu, tag);

            for (int n = 0; n < count; ++n)
            {
                ShellNativeMethods.GetMenuItemInfo(menu.Handle, n, true, ref itemInfo);

                if (itemInfo.hSubMenu == IntPtr.Zero)
                {
                    // If the item has no submenu we can't get the tag, so
                    // check its ID to determine if it was added by the shell.
                    if (itemInfo.wID >= m_CmdFirst)
                    {
                        remove.Add(n);
                    }
                }
                else
                {
                    ShellNativeMethods.GetMenuInfo(itemInfo.hSubMenu, ref menuInfo);
                    if (menuInfo.dwMenuData != tag)
                    {
                        remove.Add(n);
                    }
                }
            }

            // Remove the unmanaged menu items.
            remove.Reverse();
            foreach (int position in remove)
            {
                ShellNativeMethods.DeleteMenu(menu.Handle, position, MF.MF_BYPOSITION);
            }
        }
        /// <summary>
        /// Shows a context menu for a shell item.
        /// </summary>
        ///
        /// <param name="control">
        /// The parent control.
        /// </param>
        ///
        /// <param name="pos">
        /// The position on <paramref name="control"/> that the menu
        /// should be displayed at.
        /// </param>
        public void ShowContextMenu(Point pos, Boolean isNew = false)
        {
            using (ContextMenu menu = new ContextMenu())
            {
                Populate(menu);
                int          count    = ShellNativeMethods.GetMenuItemCount(menu.Handle);
                MENUITEMINFO itemInfo = new MENUITEMINFO();

                itemInfo.cbSize = (uint)Marshal.SizeOf(itemInfo);
                itemInfo.fMask  = (uint)MIIM.MIIM_FTYPE;
                for (int i = 0; i < count; i++)
                {
                    if (ShellNativeMethods.GetMenuItemInfo(menu.Handle, i, true, ref itemInfo))
                    {
                        var isSep = (itemInfo.fType & 2048) != 0;
                        if (i == count - 1)
                        {
                            ShellNativeMethods.GetMenuItemInfo(menu.Handle, i, true, ref itemInfo);
                            if ((itemInfo.fType & 2048) != 0)
                            {
                                ShellNativeMethods.DeleteMenu(menu.Handle, i, MF.MF_BYPOSITION);
                            }
                        }
                        else if (i < count - 1)
                        {
                            ShellNativeMethods.GetMenuItemInfo(menu.Handle, i + 1, true, ref itemInfo);
                        }
                        if (isSep && (itemInfo.fType & 2048) != 0)
                        {
                            ShellNativeMethods.DeleteMenu(menu.Handle, i, MF.MF_BYPOSITION);
                        }
                    }
                }

                int command = ShellNativeMethods.TrackPopupMenuEx(menu.Handle,
                                                                  TPM.TPM_RETURNCMD, pos.X, pos.Y, m_MessageWindow.Handle,
                                                                  IntPtr.Zero);
                if (command > 0)
                {
                    string info  = string.Empty;
                    byte[] bytes = new byte[256];
                    int    index;

                    m_ComInterface.GetCommandString(command - m_CmdFirst, 4, 0, bytes, 260);

                    index = 0;
                    while (index < bytes.Length - 1 && (bytes[index] != 0 || bytes[index + 1] != 0))
                    {
                        index += 2;
                    }

                    if (index < bytes.Length - 1)
                    {
                        info = Encoding.Unicode.GetString(bytes, 0, index); //+ 1);
                    }
                    if (!isNew)
                    {
                        if (info == "rename")
                        {
                            Explorer.DoRename();
                        }
                        else if (info == "cut")
                        {
                            Explorer.DoCut();
                        }
                        else
                        {
                            InvokeCommand(command - m_CmdFirst);
                        }
                    }
                    else
                    {
                        if (String.IsNullOrEmpty(info))
                        {
                            var newItems = GetNewContextMenuItems();
                            InvokeCommand(m_ComInterface3, newItems[command - m_CmdFirst - 3], this.Explorer.NavigationLog.CurrentLocation.ParsingName, pos);
                        }
                        else
                        {
                            InvokeCommand(m_ComInterface3, info, this.Explorer.NavigationLog.CurrentLocation.ParsingName, pos);
                        }
                    }
                }
            }
        }
 public static extern bool GetMenuItemInfo(IntPtr hMenu, int uItem,
                                           bool fByPosition, ref MENUITEMINFO lpmii);