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