private void ShowMenu(ShellFolder folder, IntPtr contextMenu) { CreateHandle(new CreateParams()); if (EnvironmentHelper.IsWindows10DarkModeSupported) { NativeMethods.AllowDarkModeForWindow(Handle, true); } uint selected = Interop.TrackPopupMenuEx( contextMenu, TPM.RETURNCMD, x, y, Handle, IntPtr.Zero); if (selected >= Interop.CMD_FIRST) { if (selected <= Interop.CMD_LAST) { // custom commands are greater than CMD_LAST, so this must be a sub menu item foreach (var subMenu in ShellNewMenus) { if (subMenu.iContextMenu != null) { InvokeCommand( subMenu.iContextMenu, folder.IsFolder && folder.IsFileSystem ? folder.Path : null, selected - Interop.CMD_FIRST, new Point(x, y)); } } } folderItemSelected?.Invoke(selected, folder.Path); } DestroyHandle(); }
private void ShowFolderMenu() { IntPtr contextMenu = IntPtr.Zero, viewSubMenu = IntPtr.Zero; IntPtr newContextMenuPtr = IntPtr.Zero, newContextMenuPtr2 = IntPtr.Zero, newContextMenuPtr3 = IntPtr.Zero; newSubmenuPtr = IntPtr.Zero; try { contextMenu = ShellFolders.CreatePopupMenu(); ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.BYCOMMAND, (int)CairoContextMenuItem.OpenInNewWindow, Localization.DisplayString.sStacks_OpenInNewWindow); if (!StacksManager.Instance.StackLocations.Contains(directory)) { ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.BYCOMMAND, (int)CairoContextMenuItem.AddToStacks, Localization.DisplayString.sInterface_AddToStacks); } else { ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.BYCOMMAND, (int)CairoContextMenuItem.RemoveFromStacks, Localization.DisplayString.sInterface_RemoveFromStacks); } ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.SEPARATOR, 1, string.Empty); ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.BYCOMMAND, (int)CairoContextMenuItem.Paste, Localization.DisplayString.sInterface_Paste); if (GetNewContextMenu(out newContextMenuPtr, out newContextMenu)) { ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.SEPARATOR, 1, string.Empty); newContextMenu.QueryContextMenu( contextMenu, 5, ShellFolders.CMD_FIRST, ShellFolders.CMD_LAST, ShellFolders.CMF.NORMAL); newSubmenuPtr = ShellFolders.GetSubMenu(contextMenu, 5); Marshal.QueryInterface(newContextMenuPtr, ref ShellFolders.IID_IContextMenu2, out newContextMenuPtr2); Marshal.QueryInterface(newContextMenuPtr, ref ShellFolders.IID_IContextMenu3, out newContextMenuPtr3); try { newContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(newContextMenuPtr2, typeof(IContextMenu2)); newContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(newContextMenuPtr3, typeof(IContextMenu3)); } catch (Exception) { } } ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.SEPARATOR, 0, string.Empty); ShellFolders.AppendMenu(contextMenu, 0, (int)CairoContextMenuItem.Properties, Localization.DisplayString.sInterface_Properties); ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.SEPARATOR, 0, string.Empty); if (!Shell.IsCairoRunningAsShell) { ShellFolders.AppendMenu(contextMenu, 0, (int)CairoContextMenuItem.DisplaySettings, Localization.DisplayString.sDesktop_DisplaySettings); } ShellFolders.AppendMenu(contextMenu, 0, (int)CairoContextMenuItem.Personalize, Localization.DisplayString.sDesktop_Personalize); CairoContextMenuItem selected = (CairoContextMenuItem)ShellFolders.TrackPopupMenuEx( contextMenu, ShellFolders.TPM.RETURNCMD, x, y, Handle, IntPtr.Zero); if ((int)selected >= ShellFolders.CMD_FIRST) { string command = ""; switch (selected) { case CairoContextMenuItem.OpenInNewWindow: command = "openWithShell"; break; case CairoContextMenuItem.AddToStacks: command = "addStack"; break; case CairoContextMenuItem.RemoveFromStacks: command = "removeStack"; break; case CairoContextMenuItem.Personalize: command = "personalize"; break; case CairoContextMenuItem.DisplaySettings: command = "displaySettings"; break; case CairoContextMenuItem.Properties: command = "properties"; ShellFolders.InvokeCommand( folder, parentShellFolder, new IntPtr[] { folderPidl }, command, new System.Drawing.Point(x, y)); break; case CairoContextMenuItem.Paste: command = "paste"; ShellFolders.InvokeCommand( folder, parentShellFolder, new IntPtr[] { folderPidl }, command, new System.Drawing.Point(x, y)); break; default: if ((uint)selected <= ShellFolders.CMD_LAST) { command = "new"; ShellFolders.InvokeCommand( newContextMenu, (uint)selected - ShellFolders.CMD_FIRST, folder, new System.Drawing.Point(x, y)); } break; } folderItemSelected?.Invoke(command, folder); } } catch (Exception) { } finally { if (newContextMenu != null) { Marshal.FinalReleaseComObject(newContextMenu); newContextMenu = null; } if (newContextMenu2 != null) { Marshal.FinalReleaseComObject(newContextMenu2); newContextMenu2 = null; } if (newContextMenu3 != null) { Marshal.FinalReleaseComObject(newContextMenu3); newContextMenu3 = null; } if (contextMenu != null) { ShellFolders.DestroyMenu(contextMenu); } if (viewSubMenu != null) { ShellFolders.DestroyMenu(viewSubMenu); } if (newContextMenuPtr != IntPtr.Zero) { Marshal.Release(newContextMenuPtr); } if (newContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(newContextMenuPtr2); } if (newContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(newContextMenuPtr3); } newSubmenuPtr = IntPtr.Zero; Marshal.FreeCoTaskMem(folderPidl); Marshal.FreeCoTaskMem(folderRelPidl); folderPidl = IntPtr.Zero; folderRelPidl = IntPtr.Zero; } }