internal static void ConstructCustomMenu(IntPtr menu, CustomMenuStructure[] customItems, out List <IntPtr> menuPtrConstructed) { menuPtrConstructed = new List <IntPtr>(); for (int i = 0; i < customItems.Length; i++) { CustomMenuStructure item = customItems[i]; if (item.IsFolder) { IntPtr newPopup = ShellAPI.CreatePopupMenu(); menuPtrConstructed.Add(newPopup); ShellAPI.InsertMenu(menu, (uint)i, ShellAPI.MFT.BYPOSITION | ShellAPI.MFT.POPUP, newPopup, item.Text); List <IntPtr> submenuPtrConstructed; ConstructCustomMenu(newPopup, item.Items.ToArray(), out submenuPtrConstructed); menuPtrConstructed.AddRange(submenuPtrConstructed); } else if (item.Text == "---") { ShellAPI.InsertMenu(menu, (uint)i, ShellAPI.MFT.BYPOSITION | ShellAPI.MFT.SEPARATOR, IntPtr.Zero, ""); } else { ShellAPI.MFT extraFlag = 0; if (item.Checked) { extraFlag |= ShellAPI.MFT.CHECKED; } ShellAPI.InsertMenu(menu, (uint)i, ShellAPI.MFT.BYPOSITION | extraFlag, new UIntPtr(ShellAPI.CMD_LAST + item.ID + 1), item.Text); } } }
public static void ConstructCustomMenu(IntPtr menu, CustomMenuStructure[] customItems, uint idCmdFirst, out List <IntPtr> menuPtrConstructed, out List <IntPtr> imgPtrConstructed) { menuPtrConstructed = new List <IntPtr>(); imgPtrConstructed = new List <IntPtr>(); for (int i = 0; i < customItems.Length; i++) { CustomMenuStructure item = customItems[i]; if (item.IsFolder) { IntPtr newPopup = ShellAPI.CreatePopupMenu(); List <IntPtr> submenuPtrConstructed, subimgPtrConstructed; ConstructCustomMenu(newPopup, item.Items.ToArray(), idCmdFirst, out submenuPtrConstructed, out subimgPtrConstructed); insertMenu(menu, idCmdFirst, i, newPopup, item, ref imgPtrConstructed); menuPtrConstructed.Add(newPopup); menuPtrConstructed.AddRange(submenuPtrConstructed); imgPtrConstructed.AddRange(subimgPtrConstructed); } else if (item.Text == "---") { ShellAPI.InsertMenu(menu, (uint)i, ShellAPI.MFT.BYPOSITION | ShellAPI.MFT.SEPARATOR, 0, ""); } else { insertMenu(menu, idCmdFirst, i, IntPtr.Zero, item, ref imgPtrConstructed); } } }
/// <summary> /// When the mouse goes up on an node and suspendContextMenu is true, this method will show the /// ContextMenu for that node and after the user selects an item, it will execute that command. /// </summary> void FolderView_MouseUp(object sender, MouseEventArgs e) { if (suspendContextMenu || contextMenuVisible) { suspendContextMenu = false; return; } TreeViewHitTestInfo hitTest = br.FolderView.HitTest(e.Location); contextMenuVisible = true; if (e.Button == MouseButtons.Right && (hitTest.Location == TreeViewHitTestLocations.Image || hitTest.Location == TreeViewHitTestLocations.Label || hitTest.Location == TreeViewHitTestLocations.StateImage)) { #region Fields ShellItem item = (ShellItem)hitTest.Node.Tag; IntPtr contextMenu = IntPtr.Zero, iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero; IShellFolder parentShellFolder = (item.ParentItem != null) ? item.ParentItem.ShellFolder : item.ShellFolder; #endregion #region Show / Invoke try { if (ContextMenuHelper.GetIContextMenu(parentShellFolder, new IntPtr[] { item.PIDLRel.Ptr }, out iContextMenuPtr, out iContextMenu)) { contextMenu = ShellAPI.CreatePopupMenu(); iContextMenu.QueryContextMenu( contextMenu, 0, ShellAPI.CMD_FIRST, ShellAPI.CMD_LAST, ShellAPI.CMF.EXPLORE | ShellAPI.CMF.CANRENAME | ((Control.ModifierKeys & Keys.Shift) != 0 ? ShellAPI.CMF.EXTENDEDVERBS : 0)); string topInvoke = hitTest.Node.IsExpanded ? "Collapse" : "Expand"; ShellAPI.MFT extraFlag = (hitTest.Node.Nodes.Count > 0) ? 0 : ShellAPI.MFT.GRAYED; ShellAPI.InsertMenu(contextMenu, 0, ShellAPI.MFT.BYPOSITION | extraFlag, (int)CMD_CUSTOM.ExpandCollapse, topInvoke); ShellAPI.InsertMenu(contextMenu, 1, ShellAPI.MFT.BYPOSITION | ShellAPI.MFT.SEPARATOR, 0, "-"); ShellAPI.SetMenuDefaultItem( contextMenu, 0, true); Marshal.QueryInterface(iContextMenuPtr, ref ShellAPI.IID_IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref ShellAPI.IID_IContextMenu3, out iContextMenuPtr3); try { iContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); iContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); } catch (Exception) { } Point ptInvoke = br.FolderView.PointToScreen(e.Location); uint selected = ShellAPI.TrackPopupMenuEx( contextMenu, ShellAPI.TPM.RETURNCMD, ptInvoke.X, ptInvoke.Y, this.Handle, IntPtr.Zero); br.OnContextMenuMouseHover(new ContextMenuMouseHoverEventArgs(string.Empty)); if (selected == (int)CMD_CUSTOM.ExpandCollapse) { if (hitTest.Node.IsExpanded) { hitTest.Node.Collapse(true); } else { hitTest.Node.Expand(); } } else if (selected >= ShellAPI.CMD_FIRST) { string command = ContextMenuHelper.GetCommandString( iContextMenu, selected - ShellAPI.CMD_FIRST, true); if (command == "rename") { br.FolderView.LabelEdit = true; hitTest.Node.BeginEdit(); } else { ContextMenuHelper.InvokeCommand( iContextMenu, selected - ShellAPI.CMD_FIRST, (item.ParentItem != null) ? ShellItem.GetRealPath(item.ParentItem) : ShellItem.GetRealPath(item), ptInvoke); } } } } #endregion catch (Exception) { } #region Finally finally { if (iContextMenu != null) { Marshal.ReleaseComObject(iContextMenu); iContextMenu = null; } if (iContextMenu2 != null) { Marshal.ReleaseComObject(iContextMenu2); iContextMenu2 = null; } if (iContextMenu3 != null) { Marshal.ReleaseComObject(iContextMenu3); iContextMenu3 = null; } if (contextMenu != null) { ShellAPI.DestroyMenu(contextMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } } #endregion } contextMenuVisible = false; }
public int ShowContextMenu(Point pointScreen, string[] AddedItems) { IntPtr intPtr = IntPtr.Zero; IntPtr zero = IntPtr.Zero; IntPtr zero2 = IntPtr.Zero; IntPtr zero3 = IntPtr.Zero; int num = -1; int result; try { if (null == this._arrPIDLs) { this.ReleaseAll(); result = -2; } else if (!this.GetContextMenuInterfaces(this._oParentFolder, this._arrPIDLs, out zero)) { this.ReleaseAll(); result = -2; } else { intPtr = ShellContextMenu.CreatePopupMenu(); int num2 = this._oContextMenu.QueryContextMenu(intPtr, 0u, 1u, 30000u, ShellContextMenu.CMF.EXPLORE | (((Control.ModifierKeys & Keys.Shift) != Keys.None) ? ShellContextMenu.CMF.EXTENDEDVERBS : ShellContextMenu.CMF.NORMAL)); Marshal.QueryInterface(zero, ref ShellContextMenu.IID_IContextMenu2, out zero2); Marshal.QueryInterface(zero, ref ShellContextMenu.IID_IContextMenu3, out zero3); this._oContextMenu2 = (ShellContextMenu.IContextMenu2)Marshal.GetTypedObjectForIUnknown(zero2, typeof(ShellContextMenu.IContextMenu2)); this._oContextMenu3 = (ShellContextMenu.IContextMenu3)Marshal.GetTypedObjectForIUnknown(zero3, typeof(ShellContextMenu.IContextMenu3)); for (int i = 0; i < AddedItems.Length; i++) { ShellAPI.InsertMenu(intPtr, (uint)i, ShellAPI.MFT.BYPOSITION, (uint)(30001 + i), AddedItems[i]); } ShellAPI.InsertMenu(intPtr, (uint)AddedItems.Length, ShellAPI.MFT.SEPARATOR | ShellAPI.MFT.BYPOSITION, (uint)(30001 + AddedItems.Length), "-"); uint num3 = ShellContextMenu.TrackPopupMenuEx(intPtr, ShellContextMenu.TPM.RETURNCMD, pointScreen.X, pointScreen.Y, base.Handle, IntPtr.Zero); ShellContextMenu.DestroyMenu(intPtr); intPtr = IntPtr.Zero; if (AddedItems.Length > 0 && num3 >= 30001u && (ulong)num3 <= (ulong)((long)(AddedItems.Length - 1 + 30001))) { num = (int)(num3 - 30001u); } else if (num3 != 0u) { this.InvokeCommand(this._oContextMenu, num3, this._strParentFolder, pointScreen); } result = num; } } catch { Console.WriteLine("Error in Context Menu generation"); result = -1; } finally { if (intPtr != IntPtr.Zero) { ShellContextMenu.DestroyMenu(intPtr); } if (zero != IntPtr.Zero) { Marshal.Release(zero); } if (zero2 != IntPtr.Zero) { Marshal.Release(zero2); } if (zero3 != IntPtr.Zero) { Marshal.Release(zero3); } this.ReleaseAll(); } return(result); }