/// <summary> /// Invokes the specified verb on the shell item(s). /// </summary> public string InvokeVerb(string verb) { string ret = string.Empty; //CMINVOKECOMMANDINFO invoke = new CMINVOKECOMMANDINFO(); //invoke.cbSize = Marshal.SizeOf(invoke); //invoke.lpVerb = verb; CMInvokeCommandInfoEx invoke = new CMInvokeCommandInfoEx(); invoke.cbSize = Marshal.SizeOf(invoke); invoke.lpVerb = Marshal.StringToHGlobalAnsi(verb); try { m_ComInterface.InvokeCommand(ref invoke); return(string.Empty); } catch (COMException e) { // Ignore the exception raised when the user cancels // a delete operation. if (e.ErrorCode != unchecked ((int)0x800704C7) && e.ErrorCode != unchecked ((int)0x80270000)) { throw; } } return(verb); }
/// <summary> /// Invokes a specific command from an IContextMenu /// </summary> /// <param name="iContextMenu">the IContextMenu containing the item</param> /// <param name="cmd">the index of the command to invoke</param> /// <param name="parentDir">the parent directory from where to invoke</param> /// <param name="ptInvoke">the point (in screen coördinates) from which to invoke</param> public void InvokeCommand(IContextMenu iContextMenu, IntPtr cmd, string parentDir, System.Drawing.Point ptInvoke) { CMInvokeCommandInfoEx invoke = new CMInvokeCommandInfoEx(); invoke.cbSize = Shell32.cbInvokeCommand; invoke.lpVerb = cmd; invoke.lpDirectory = parentDir; invoke.lpVerbW = cmd; invoke.lpDirectoryW = parentDir; invoke.fMask = (int)(CMIC.UNICODE | CMIC.PTINVOKE); if ((Control.ModifierKeys & Keys.Control) != 0) { invoke.fMask = invoke.fMask | (int)CMIC.CONTROL_DOWN; } if ((Control.ModifierKeys & Keys.Shift) != 0) { invoke.fMask = invoke.fMask | (int)CMIC.SHIFT_DOWN; } invoke.ptInvoke = new System.Drawing.Point(ptInvoke.X, ptInvoke.Y); invoke.nShow = (int)SW.SHOWNORMAL; iContextMenu.InvokeCommand(ref invoke); }
/// <summary> /// If this method returns true then the caller must call ReleaseMenu /// </summary> /// <param name="hwnd">The handle to the control to host the ContextMenu</param> /// <param name="items">The items for which to show the ContextMenu. These items must be in the same folder.</param> /// <param name="pt">The point where the ContextMenu should appear</param> /// <param name="allowrename">Set if (the ContextMenu should contain the Rename command where appropriate</param> /// <param name="cmi">The command information for the users selection</param> /// <returns></returns> /// <remarks></remarks> public bool ShowMenu(IntPtr hwnd, ShellItem[] items, System.Drawing.Point pt, bool allowRename, ref CMInvokeCommandInfoEx cmi) { bool bShowMenu = false; Debug.Assert(items.Length > 0); IntPtr comContextMenu = User32.CreatePopupMenu(); IntPtr[] pidls = new System.IntPtr[items.Length]; int i; IShellFolder folder = null; if (items[0] == ShellItem.Desktop) { folder = items[0].GetIShellFolder(); } else { folder = items[0].Parent.GetIShellFolder(); } for (i = 0; i <= items.Length - 1; i++) { if (!items[i].CanRename) { allowRename = false; } pidls[i] = Shell32.ILFindLastID(items[i].Pidl); } int prgf = 0; IntPtr pIcontext = IntPtr.Zero; int HR = folder.GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length, pidls, Shell32.IID_IContextMenu, (uint)prgf, out pIcontext); if (HR != (int)HResult.S_OK) { #if DEBUG Marshal.ThrowExceptionForHR(HR); #endif //GoTo FAIL; } winMenu = (IContextMenu)Marshal.GetObjectForIUnknown(pIcontext); IntPtr p = IntPtr.Zero; Marshal.QueryInterface(pIcontext, ref Shell32.IID_IContextMenu2, out p); if (p != IntPtr.Zero) { winMenu2 = (IContextMenu2)Marshal.GetObjectForIUnknown(p); } Marshal.QueryInterface(pIcontext, ref Shell32.IID_IContextMenu3, out p); if (p != IntPtr.Zero) { winMenu3 = (IContextMenu3)Marshal.GetObjectForIUnknown(p); } if (!pIcontext.Equals(IntPtr.Zero)) { pIcontext = IntPtr.Zero; } //Check item count - should always be 0 but check just in case uint startIndex = User32.GetMenuItemCount(comContextMenu); //Fill the context menu CMF flags = (CMF.NORMAL | CMF.EXPLORE); if (allowRename) { flags = flags | CMF.CANRENAME; } if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { flags = flags | CMF.EXTENDEDVERBS; } int idCount = (int)winMenu.QueryContextMenu(comContextMenu, startIndex, min, max, flags); int cmd = User32.TrackPopupMenuEx(comContextMenu, TPM.TPM_RETURNCMD, pt.X, pt.Y, hwnd, IntPtr.Zero); if (cmd >= min && cmd <= idCount) { cmi = new CMInvokeCommandInfoEx(); cmi.cbSize = Marshal.SizeOf(cmi); cmi.lpVerb = (IntPtr)(cmd - min); cmi.lpVerbW = (IntPtr)(cmd - min); cmi.nShow = (int)SW.SHOWNORMAL; cmi.fMask = (int)(CMIC.UNICODE | CMIC.PTINVOKE); cmi.ptInvoke = new System.Drawing.Point(pt.X, pt.Y); bShowMenu = true; } else { //FAIL: if (winMenu != null) { Marshal.ReleaseComObject(winMenu); winMenu = null; } bShowMenu = false; } if (winMenu2 != null) { Marshal.ReleaseComObject(winMenu2); winMenu2 = null; } if (winMenu3 != null) { Marshal.ReleaseComObject(winMenu3); winMenu3 = null; } if (!comContextMenu.Equals(IntPtr.Zero)) { Marshal.Release(comContextMenu); comContextMenu = IntPtr.Zero; } return(bShowMenu); }