/// <summary>Initialises a new instance of the <see cref="ShellContextMenu"/> class.</summary> /// <param name="items">The items to which the context menu should refer.</param> public ShellContextMenu(ShellItem[] items) { var pidls = new IntPtr[items.Length]; ShellFolder parent = null; for (var n = 0; n < items.Length; ++n) { pidls[n] = ILFindLastID((IntPtr)items[n].PIDL); if (parent is null) { if (items[n] == ShellFolder.Desktop) { parent = ShellFolder.Desktop; } else { parent = items[n].Parent; } } else { if (items[n].Parent != parent) { throw new Exception("All shell items must have the same parent"); } } } ComInterface = parent.IShellFolder.GetUIObjectOf <IContextMenu>(HWND.NULL, pidls); m_ComInterface2 = ComInterface as IContextMenu2; m_ComInterface3 = ComInterface as IContextMenu3; m_MessageWindow = new MessageWindow(this); }
private static void ReleaseAll() { if (null != _oContextMenu) { Marshal.ReleaseComObject(_oContextMenu); _oContextMenu = null; } if (null != _oContextMenu2) { Marshal.ReleaseComObject(_oContextMenu2); _oContextMenu2 = null; } if (null != _oContextMenu3) { Marshal.ReleaseComObject(_oContextMenu3); _oContextMenu3 = null; } if (null != _oDesktopFolder) { Marshal.ReleaseComObject(_oDesktopFolder); _oDesktopFolder = null; } if (null == _oParentFolder) { return; } Marshal.ReleaseComObject(_oParentFolder); _oParentFolder = null; }
//.///////////////////////////////////////////////////////////////////// /// <summary>Gets the interfaces to the context menu</summary> /// <param name="oParentFolder">Parent folder</param> /// <param name="arrPIDLs">PIDLs</param> /// <returns>true if it got the interfaces, otherwise false</returns> private bool GetContextMenuInterfaces(IShellFolder oParentFolder, IntPtr[] arrPIDLs) { IntPtr pUnknownContextMenu = IntPtr.Zero; int nResult = oParentFolder.GetUIObjectOf( IntPtr.Zero, (uint)arrPIDLs.Length, arrPIDLs, ref IID_IContextMenu, IntPtr.Zero, out pUnknownContextMenu ); if (S_OK == nResult) { _oContextMenu = (IContextMenu)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu, typeof(IContextMenu)); IntPtr pUnknownContextMenu2 = IntPtr.Zero; if (S_OK == Marshal.QueryInterface(pUnknownContextMenu, ref IID_IContextMenu2, out pUnknownContextMenu2)) { _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu2, typeof(IContextMenu2)); } IntPtr pUnknownContextMenu3 = IntPtr.Zero; if (S_OK == Marshal.QueryInterface(pUnknownContextMenu, ref IID_IContextMenu3, out pUnknownContextMenu3)) { _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu3, typeof(IContextMenu3)); } return(true); } else { return(false); } }
/// <summary> /// Release all allocated interfaces, PIDLs /// </summary> private void ReleaseAll() { if (null != _oContextMenu) { Marshal.ReleaseComObject(_oContextMenu); _oContextMenu = null; } if (null != _oContextMenu2) { Marshal.ReleaseComObject(_oContextMenu2); _oContextMenu2 = null; } if (null != _oContextMenu3) { Marshal.ReleaseComObject(_oContextMenu3); _oContextMenu3 = null; } if (null != _oDesktopFolder) { Marshal.ReleaseComObject(_oDesktopFolder); _oDesktopFolder = null; } if (null != _oParentFolder) { Marshal.ReleaseComObject(_oParentFolder); _oParentFolder = null; } if (null != _arrPIDLs) { FreePIDLs(_arrPIDLs); _arrPIDLs = null; } }
public ShellContextMenuMessageHandler(IContextMenu contextMenu) { _contextMenu = contextMenu; _contextMenu2 = contextMenu as IContextMenu2; _contextMenu3 = contextMenu as IContextMenu3; _hwndSource = new HwndSource(0, 0, 0, 0, 0, 0, 0, null, IntPtr.Zero); _hwndSource.AddHook(WndProc); }
public void Dispose() { _hwndSource.RemoveHook(WndProc); _hwndSource?.Dispose(); _hwndSource = null; _contextMenu = null; _contextMenu2 = null; _contextMenu3 = null; }
internal ShellContextMenu(IContextMenu3 contextMenu) { Contract.Requires <ArgumentNullException>(contextMenu != null); this.ContextMenuNative = contextMenu; // PopupMenu作成 this.popupMenu = MenuNativeMethods.CreatePopupMenu(); this.ContextMenuNative.QueryContextMenu(popupMenu, 0, this.CommandFirst, this.CommandLast, 0x0114); }
private static void ShowContextMenuInternal(DirectoryInfo directory, Point pointScreen, IntPtr hwnd) { var pMenu = IntPtr.Zero; var iContextMenuPtr = IntPtr.Zero; var iContextMenuPtr2 = IntPtr.Zero; var iContextMenuPtr3 = IntPtr.Zero; try { var pidl = GetPidl(directory); if (directory.Parent != null && false == GetContextMenuInterfaces(GetParentFolder(directory.FullName), pidl, out iContextMenuPtr)) { ReleaseAll(); return; } pMenu = DllImports.CreatePopupMenu(); _oContextMenu.QueryContextMenu(pMenu, 0, CmdFirst, CmdLast, Enums.Cmf.EXPLORE | Enums.Cmf.NORMAL | ((Control.ModifierKeys & Keys.Shift) != 0 ? Enums.Cmf.EXTENDEDVERBS : 0)); Marshal.QueryInterface(iContextMenuPtr, ref _iidIContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref _iidIContextMenu3, out iContextMenuPtr3); _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); var nSelected = DllImports.TrackPopupMenuEx(pMenu, Enums.Tpm.RETURNCMD, pointScreen.X, pointScreen.Y, hwnd, IntPtr.Zero); DllImports.DestroyMenu(pMenu); pMenu = IntPtr.Zero; if (nSelected != 0) { InvokeCommand(_oContextMenu, nSelected, _strParentFolder, pointScreen); } } catch { } finally { if (pMenu != IntPtr.Zero) { DllImports.DestroyMenu(pMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } ReleaseAll(); } }
public void AddSubMenu(ShellFolder folder, int position, ref IntPtr parentNativeMenuPtr) { if (GetNewContextMenu(folder)) { iContextMenu.QueryContextMenu( parentNativeMenuPtr, (uint)position, Interop.CMD_FIRST, Interop.CMD_LAST, CMF.NORMAL); nativeMenuPtr = Interop.GetSubMenu(parentNativeMenuPtr, position); if (Marshal.QueryInterface(iContextMenuPtr, ref Interop.IID_IContextMenu2, out iContextMenu2Ptr) == NativeMethods.S_OK) { if (iContextMenu2Ptr != IntPtr.Zero) { try { iContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenu2Ptr, typeof(IContextMenu2)); } catch (Exception e) { ShellLogger.Error($"ShellContextMenu: Error retrieving IContextMenu2 interface: {e.Message}"); } } } if (Marshal.QueryInterface(iContextMenuPtr, ref Interop.IID_IContextMenu3, out iContextMenu3Ptr) == NativeMethods.S_OK) { if (iContextMenu3Ptr != IntPtr.Zero) { try { iContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenu3Ptr, typeof(IContextMenu3)); } catch (Exception e) { ShellLogger.Error($"ShellContextMenu: Error retrieving IContextMenu3 interface: {e.Message}"); } } } } }
private void ContextMenuStrip_Disposed(object sender, EventArgs e) { if (this.Menu != IntPtr.Zero) { Windows.DestroyMenu(this.Menu); } this.Menu = IntPtr.Zero; if (this.ContextMenu != null) { Marshal.ReleaseComObject(this.ContextMenu); } this.ContextMenu = null; this.ContextMenu2 = null; this.ContextMenu3 = null; this.Owner = null; ((Control) sender).Tag = null; }
void Initialize(IListItemEx[] items) { this._Items = items; IntPtr[] pidls = new IntPtr[items.Length]; IListItemEx parent = null; for (int n = 0; n < items.Length; ++n) { pidls[n] = items[n].ILPidl; if (parent == null) { if (items[n].ParsingName.Equals(ShellItem.Desktop.ParsingName)) { parent = FileSystemListItem.ToFileSystemItem(IntPtr.Zero, ShellItem.Desktop.Pidl); } else { parent = items[n].Parent; } } else if (!items[n].Parent.Equals(parent)) { throw new Exception("All shell items must have the same parent"); } } if (items.Length == 0) { var desktop = KnownFolders.Desktop as ShellItem; var ishellViewPtr = desktop.GetIShellFolder().CreateViewObject(IntPtr.Zero, typeof(IShellView).GUID); var view = Marshal.GetObjectForIUnknown(ishellViewPtr) as IShellView; view.GetItemObject(SVGIO.SVGIO_BACKGROUND, typeof(IContextMenu).GUID, out _Result); Marshal.ReleaseComObject(view); } else { parent.GetIShellFolder().GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length, pidls, typeof(IContextMenu).GUID, 0, out _Result); } m_ComInterface = (IContextMenu)Marshal.GetTypedObjectForIUnknown(_Result, typeof(IContextMenu)); m_ComInterface2 = m_ComInterface as IContextMenu2; m_ComInterface3 = m_ComInterface as IContextMenu3; m_MessageWindow = new MessageWindow(this); }
internal void FreeResources() { if (iContextMenu != null) { Marshal.FinalReleaseComObject(iContextMenu); iContextMenu = null; } if (iContextMenu2 != null) { Marshal.FinalReleaseComObject(iContextMenu2); iContextMenu2 = null; } if (iContextMenu3 != null) { Marshal.FinalReleaseComObject(iContextMenu3); iContextMenu3 = null; } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); iContextMenuPtr = IntPtr.Zero; } if (iContextMenu2Ptr != IntPtr.Zero) { Marshal.Release(iContextMenu2Ptr); iContextMenu2Ptr = IntPtr.Zero; } if (iContextMenu3Ptr != IntPtr.Zero) { Marshal.Release(iContextMenu3Ptr); iContextMenu3Ptr = IntPtr.Zero; } if (nativeMenuPtr != IntPtr.Zero) { Interop.DestroyMenu(nativeMenuPtr); nativeMenuPtr = IntPtr.Zero; } }
/// <summary> /// Initializes a new instance of the <see cref="ShellContextMenu"/> class. /// </summary> /// <param name="shellView">The ShellView the ContextMenu is associated with</param> /// <param name="Use_GetNewContextMenu"></param> public ShellContextMenu(ShellView shellView, bool Use_GetNewContextMenu) { this._ShellView = shellView; IntPtr iContextMenu = IntPtr.Zero; if (Use_GetNewContextMenu) { this.GetNewContextMenu(_ShellView.CurrentFolder, out iContextMenu, out m_ComInterface); } else { this.GetOpenWithContextMenu(_ShellView.SelectedItems.ToArray(), out iContextMenu, out m_ComInterface); } m_ComInterface2 = m_ComInterface as IContextMenu2; m_ComInterface3 = m_ComInterface as IContextMenu3; m_MessageWindow = new MessageWindow(this); }
public void InvokeCommand(IContextMenu3 iContextMenu, string cmd, string parentDir, Point ptInvoke) { CMINVOKECOMMANDINFOEX invoke = new CMINVOKECOMMANDINFOEX(); invoke.Size = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)); invoke.Verb = Marshal.StringToHGlobalAnsi(cmd); invoke.Directory = parentDir; invoke.VerbW = Marshal.StringToHGlobalUni(cmd); invoke.DirectoryW = parentDir; invoke.Mask = CMIC.Unicode | CMIC.PtInvoke | ((Control.ModifierKeys & Keys.Control) != 0 ? CMIC.ControlDown : 0) | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMIC.ShiftDown : 0); POINT pt = new POINT(); pt.x = ptInvoke.X; pt.y = ptInvoke.Y; invoke.InvokePoint = pt; invoke.ShowType = SW.ShowNormal; var res = iContextMenu.InvokeCommand(ref invoke); }
private void Initialize(ShellItem[] items) { var pidls = new IntPtr[items.Length]; ShellItem parent = null; for (var n = 0; n < items.Length; ++n) { pidls[n] = Shell32.ILFindLastID(items[n].Pidl); if (parent == null) { parent = items[n] == ShellItem.Desktop ? ShellItem.Desktop : items[n].Parent; } else { if (items[n].Parent != parent) { throw new Exception("All shell items must have the same parent"); } } } if (parent != null) { IntPtr result; parent.GetIShellFolder().GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length, pidls, typeof(IContextMenu).GUID, 0, out result); ComInterface = (IContextMenu) Marshal.GetTypedObjectForIUnknown(result, typeof(IContextMenu)); _mComInterface2 = ComInterface as IContextMenu2; _mComInterface3 = ComInterface as IContextMenu3; _mMessageWindow = new MessageWindow(this); } }
/// <summary> /// Release all allocated interfaces, PIDLs. /// </summary> private void ReleaseAll() { if (oContextMenu != null) { Marshal.ReleaseComObject(oContextMenu); oContextMenu = null; } if (oContextMenu2 != null) { Marshal.ReleaseComObject(oContextMenu2); oContextMenu2 = null; } if (oContextMenu3 != null) { Marshal.ReleaseComObject(oContextMenu3); oContextMenu3 = null; } if (oDesktopFolder != null) { Marshal.ReleaseComObject(oDesktopFolder); oDesktopFolder = null; } if (oParentFolder != null) { Marshal.ReleaseComObject(oParentFolder); oParentFolder = null; } if (arrPIDLs != null) { FreePIDLs(arrPIDLs); arrPIDLs = null; } }
public void ReleaseNewMenu() { if (newMenu != null) { Marshal.ReleaseComObject(newMenu); newMenu = null; } if (newMenu2 != null) { Marshal.ReleaseComObject(newMenu2); newMenu2 = null; } if (newMenu3 != null) { Marshal.ReleaseComObject(newMenu3); newMenu3 = null; } if (!newMenuPtr.Equals(IntPtr.Zero)) { Marshal.Release(newMenuPtr); newMenuPtr = IntPtr.Zero; } }
private static void ReleaseAll() { if (null != _oContextMenu) { Marshal.ReleaseComObject(_oContextMenu); _oContextMenu = null; } if (null != _oContextMenu2) { Marshal.ReleaseComObject(_oContextMenu2); _oContextMenu2 = null; } if (null != _oContextMenu3) { Marshal.ReleaseComObject(_oContextMenu3); _oContextMenu3 = null; } if (null != _oDesktopFolder) { Marshal.ReleaseComObject(_oDesktopFolder); _oDesktopFolder = null; } if (null == _oParentFolder) return; Marshal.ReleaseComObject(_oParentFolder); _oParentFolder = null; }
private void CreateNormalMenu(Point ptInvoke, ListViewHitTestInfo hitTest, MouseEventArgs e) { hitTest.Item.Selected = true; #region Fields ShellItem item = (ShellItem)hitTest.Item.Tag; int offset = br.FileView.SelectedOrder.Contains(hitTest.Item) ? 0 : 1; IntPtr[] pidls = new IntPtr[br.FileView.SelectedOrder.Count + offset]; if (offset == 1) pidls[0] = item.PIDLRel.Ptr; for (int i = offset; i < pidls.Length; i++) { pidls[i] = ((ShellItem)((ListViewItem)br.FileView.SelectedOrder[i - offset]).Tag).PIDLRel.Ptr; } 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, pidls, 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)); 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) { } uint selected = ShellAPI.TrackPopupMenuEx( contextMenu, ShellAPI.TPM.RETURNCMD, ptInvoke.X, ptInvoke.Y, this.Handle, IntPtr.Zero); br.OnContextMenuMouseHover(new ContextMenuMouseHoverEventArgs(string.Empty)); if (selected >= ShellAPI.CMD_FIRST) { string command = ContextMenuHelper.GetCommandString(iContextMenu, selected - ShellAPI.CMD_FIRST, true); if (command == "Explore" && br.FolderView.SelectedNode != null) { if (!br.FolderView.SelectedNode.IsExpanded) br.FolderView.SelectedNode.Expand(); br.FolderView.SelectedNode = br.FolderView.SelectedNode.Nodes[hitTest.Item.Text]; } else if (command == "rename") { hitTest.Item.BeginEdit(); } else { ContextMenuHelper.InvokeCommand( iContextMenu, selected - ShellAPI.CMD_FIRST, ShellItem.GetRealPath(br.SelectedItem), 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 }
void Initialize(IListItemEx item) { Guid iise = typeof(IShellExtInit).GUID; var ishellViewPtr = (item.IsDrive || !item.IsFileSystem || item.IsNetworkPath) ? item.GetIShellFolder().CreateViewObject(IntPtr.Zero, typeof(IShellView).GUID) : item.Parent.GetIShellFolder().CreateViewObject(IntPtr.Zero, typeof(IShellView).GUID); var view = Marshal.GetObjectForIUnknown(ishellViewPtr) as IShellView; view?.GetItemObject(SVGIO.SVGIO_BACKGROUND, typeof(IContextMenu).GUID, out _Result); if (view != null) Marshal.ReleaseComObject(view); m_ComInterface = (IContextMenu)Marshal.GetTypedObjectForIUnknown(_Result, typeof(IContextMenu)); m_ComInterface2 = m_ComInterface as IContextMenu2; m_ComInterface3 = m_ComInterface as IContextMenu3; IntPtr iShellExtInitPtr; if (Marshal.QueryInterface(_Result, ref iise, out iShellExtInitPtr) == (int)HResult.S_OK) { var iShellExtInit = Marshal.GetTypedObjectForIUnknown(iShellExtInitPtr, typeof(IShellExtInit)) as IShellExtInit; try { var hhh = IntPtr.Zero; iShellExtInit?.Initialize(_ShellView.CurrentFolder.PIDL, null, 0); if (iShellExtInit != null) Marshal.ReleaseComObject(iShellExtInit); Marshal.Release(iShellExtInitPtr); } catch { } } m_MessageWindow = new MessageWindow(this); }
/// <summary> /// Initializes a new instance of the <see cref="ShellContextMenu"/> class. /// </summary> /// <param name="shellView">The ShellView the ContextMenu is associated with</param> /// <param name="Use_GetNewContextMenu"></param> public ShellContextMenu(ShellView shellView, bool Use_GetNewContextMenu) { this._ShellView = shellView; IntPtr iContextMenu = IntPtr.Zero; if (Use_GetNewContextMenu) this.GetNewContextMenu(_ShellView.CurrentFolder, out iContextMenu, out m_ComInterface); else this.GetOpenWithContextMenu(_ShellView.SelectedItems.ToArray(), out iContextMenu, out m_ComInterface); m_ComInterface2 = m_ComInterface as IContextMenu2; m_ComInterface3 = m_ComInterface as IContextMenu3; m_MessageWindow = new MessageWindow(this); }
/// <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); }
public string Popup(FileSystemInfoEx[] items, Point pt) { if (items.Length > 0 && !_contextMenuVisible) { //0.15: Fixed ShellFolder not freed correctly. try { using (ShellFolder2 parentShellFolder = items[0].Parent != null ? items[0].Parent.ShellFolder : DirectoryInfoEx.DesktopDirectory.ShellFolder) try { _contextMenuVisible = true; ///Debug.WriteLine(items[0].Parent.FullName); IntPtr ptrContextMenu = IntPtr.Zero; IntPtr ptrContextMenu2 = IntPtr.Zero; IntPtr PtrContextMenu3 = IntPtr.Zero; IntPtr contextMenu = IntPtr.Zero; List <IntPtr> menuPtrConstructed = new List <IntPtr>(); List <IntPtr> imgPtrConstructed = new List <IntPtr>(); PIDL[] pidls = IOTools.GetPIDL(items, true); if (ContextMenuHelper.GetIContextMenu(parentShellFolder, IOTools.GetPIDLPtr(pidls), out ptrContextMenu, out _iContextMenu)) { try { queryMenuItemsEventArgs = new QueryMenuItemsEventArgs(items); if (OnQueryMenuItems != null) { OnQueryMenuItems(this, queryMenuItemsEventArgs); } contextMenu = ShellAPI.CreatePopupMenu(); if (queryMenuItemsEventArgs.QueryContextMenu) { _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)); } #region obsolute //for (uint i = 0; i < queryMenuItemsEventArgs.ExtraMenuItems.Length; i++) //{ // string caption = queryMenuItemsEventArgs.ExtraMenuItems[i]; // if (caption != "---") // { // ShellAPI.InsertMenu(contextMenu, i, ShellAPI.MFT.BYPOSITION, // ShellAPI.CMD_LAST + i + 1, caption); // if (queryMenuItemsEventArgs.DefaultItem == i) // ShellAPI.SetMenuDefaultItem(contextMenu, i, true); // } // else ShellAPI.InsertMenu(contextMenu, i, ShellAPI.MFT.BYPOSITION | // ShellAPI.MFT.SEPARATOR, 0, "-"); //} #endregion //0.11: Added ContextMenuWrapper OnQueryMenuItems event now support multilevel directory. (e.g. @"Tools\Add") ContextMenuHelperEx.ConstructCustomMenu(contextMenu, queryMenuItemsEventArgs.ExtraMenuItems, out menuPtrConstructed, out imgPtrConstructed); if (queryMenuItemsEventArgs.QueryContextMenu2) { try { Marshal.QueryInterface(ptrContextMenu, ref ShellAPI.IID_IContextMenu2, out ptrContextMenu2); _iContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown( ptrContextMenu2, typeof(IContextMenu2)); } catch (Exception) { } } if (queryMenuItemsEventArgs.QueryContextMenu3) { try { Marshal.QueryInterface(ptrContextMenu, ref ShellAPI.IID_IContextMenu3, out PtrContextMenu3); _iContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown( PtrContextMenu3, typeof(IContextMenu3)); } catch (Exception) { } } uint GMDI_USEDISABLED = 0x0001; //uint GMDI_GOINTOPOPUPS = 0x0002; uint intDefaultItem = (uint)ShellAPI.GetMenuDefaultItem(contextMenu, false, GMDI_USEDISABLED); string strDefaultCommand = intDefaultItem >= ShellAPI.CMD_FIRST ? ContextMenuHelper.GetCommandString(_iContextMenu, intDefaultItem - ShellAPI.CMD_FIRST, true) : null; if (queryMenuItemsEventArgs.QueryContextMenu) //No need to Disable if query is not carried out in first place. { //0.11: Added queryMenuItemsEventArgs.GrayedItems / HiddenItems ContextMenuHelperEx.DisableMenuItems(contextMenu, _iContextMenu, queryMenuItemsEventArgs.GrayedItems, ContextMenuHelperEx.DisabledMethods.Gray); ContextMenuHelperEx.DisableMenuItems(contextMenu, _iContextMenu, queryMenuItemsEventArgs.HiddenItems, ContextMenuHelperEx.DisabledMethods.Remove); } //0.17: Added DefaultItem and DefaultCommand in BeforePopup bool cont = true; if (OnBeforePopup != null) { BeforePopupEventArgs args = new BeforePopupEventArgs (contextMenu, _iContextMenu, intDefaultItem - ShellAPI.CMD_FIRST, strDefaultCommand); OnBeforePopup(this, args); cont = args.ContinuePopup; } if (cont) { //0.18 Fixed Context menu disappear in some case. (By cwharmon) //http://www.codeproject.com/KB/files/DirectoryInfoEx.aspx#xx3475961xx ShellAPI.SetForegroundWindow(this.Handle); uint selected = ShellAPI.TrackPopupMenuEx(contextMenu, ShellAPI.TPM.RETURNCMD, pt.X, pt.Y, this.Handle, IntPtr.Zero); uint msg = 0; ShellAPI.PostMessage(this.Handle, msg, IntPtr.Zero, IntPtr.Zero); if (OnMouseHover != null) { OnMouseHover(this, new MouseHoverEventArgs("", "", 0)); } if (selected >= ShellAPI.CMD_LAST) { return(removeCheckedSymbol(queryMenuItemsEventArgs.ExtraMenuItems[selected - ShellAPI.CMD_LAST])); } if (selected >= ShellAPI.CMD_FIRST) { string command = ContextMenuHelper.GetCommandString(_iContextMenu, selected - ShellAPI.CMD_FIRST, true); if (command == null) { return(null); } if (OnBeforeInvokeCommand != null) { InvokeCommandEventArgs args = new InvokeCommandEventArgs(command, "", selected, items); OnBeforeInvokeCommand(this, args); if (!args.ContinueInvoke) { return(command); } } if (command == "rename") { return("rename"); } else { //if (items.Length == 1 && items[0] is DirectoryInfoEx) ContextMenuHelper.InvokeCommand(_iContextMenu, selected - ShellAPI.CMD_FIRST, (items[0].Parent != null) ? items[0].Parent.FullName : items[0].FullName, pt); //else //ContextMenuHelper.InvokeCommand(items[0].Parent, // IOTools.GetPIDLPtr(items, true), selected - ShellAPI.CMD_FIRST, // pt); } } } } finally { IOTools.FreePIDL(pidls); if (_iContextMenu != null) { Marshal.ReleaseComObject(_iContextMenu); _iContextMenu = null; } if (_iContextMenu2 != null) { Marshal.ReleaseComObject(_iContextMenu2); _iContextMenu2 = null; } if (_iContextMenu3 != null) { Marshal.ReleaseComObject(_iContextMenu3); _iContextMenu3 = null; } foreach (IntPtr menuPtr in menuPtrConstructed) { ShellAPI.DestroyMenu(menuPtr); } menuPtrConstructed.Clear(); if (contextMenu != null) { ShellAPI.DestroyMenu(contextMenu); } if (ptrContextMenu != IntPtr.Zero) { Marshal.Release(ptrContextMenu); } if (ptrContextMenu2 != IntPtr.Zero) { Marshal.Release(ptrContextMenu2); } if (PtrContextMenu3 != IntPtr.Zero) { Marshal.Release(PtrContextMenu3); } } } } finally { _contextMenuVisible = false; } } catch { } } return(null); }
public string Popup(FileSystemInfoEx[] items, Point pt) { if (items.Length > 0 && !_contextMenuVisible) { //0.15: Fixed ShellFolder not freed correctly. try { using (ShellFolder2 parentShellFolder = items[0].Parent != null ? items[0].Parent.ShellFolder : DirectoryInfoEx.DesktopDirectory.ShellFolder) try { _contextMenuVisible = true; ///Debug.WriteLine(items[0].Parent.FullName); IntPtr ptrContextMenu = IntPtr.Zero; IntPtr ptrContextMenu2 = IntPtr.Zero; IntPtr PtrContextMenu3 = IntPtr.Zero; IntPtr contextMenu = IntPtr.Zero; List<IntPtr> menuPtrConstructed = new List<IntPtr>(); List<IntPtr> imgPtrConstructed = new List<IntPtr>(); PIDL[] pidls = IOTools.GetPIDL(items, true); if (ContextMenuHelper.GetIContextMenu(parentShellFolder, IOTools.GetPIDLPtr(pidls), out ptrContextMenu, out _iContextMenu)) try { queryMenuItemsEventArgs = new QueryMenuItemsEventArgs(items); if (OnQueryMenuItems != null) OnQueryMenuItems(this, queryMenuItemsEventArgs); contextMenu = ShellAPI.CreatePopupMenu(); if (queryMenuItemsEventArgs.QueryContextMenu) _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)); #region obsolute //for (uint i = 0; i < queryMenuItemsEventArgs.ExtraMenuItems.Length; i++) //{ // string caption = queryMenuItemsEventArgs.ExtraMenuItems[i]; // if (caption != "---") // { // ShellAPI.InsertMenu(contextMenu, i, ShellAPI.MFT.BYPOSITION, // ShellAPI.CMD_LAST + i + 1, caption); // if (queryMenuItemsEventArgs.DefaultItem == i) // ShellAPI.SetMenuDefaultItem(contextMenu, i, true); // } // else ShellAPI.InsertMenu(contextMenu, i, ShellAPI.MFT.BYPOSITION | // ShellAPI.MFT.SEPARATOR, 0, "-"); //} #endregion //0.11: Added ContextMenuWrapper OnQueryMenuItems event now support multilevel directory. (e.g. @"Tools\Add") ContextMenuHelperEx.ConstructCustomMenu(contextMenu, queryMenuItemsEventArgs.ExtraMenuItems, out menuPtrConstructed, out imgPtrConstructed); if (queryMenuItemsEventArgs.QueryContextMenu2) try { Marshal.QueryInterface(ptrContextMenu, ref ShellAPI.IID_IContextMenu2, out ptrContextMenu2); _iContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown( ptrContextMenu2, typeof(IContextMenu2)); } catch (Exception) { } if (queryMenuItemsEventArgs.QueryContextMenu3) try { Marshal.QueryInterface(ptrContextMenu, ref ShellAPI.IID_IContextMenu3, out PtrContextMenu3); _iContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown( PtrContextMenu3, typeof(IContextMenu3)); } catch (Exception) { } uint GMDI_USEDISABLED = 0x0001; //uint GMDI_GOINTOPOPUPS = 0x0002; uint intDefaultItem = (uint)ShellAPI.GetMenuDefaultItem(contextMenu, false, GMDI_USEDISABLED); string strDefaultCommand = intDefaultItem >= ShellAPI.CMD_FIRST ? ContextMenuHelper.GetCommandString(_iContextMenu, intDefaultItem - ShellAPI.CMD_FIRST, true) : null; if (queryMenuItemsEventArgs.QueryContextMenu) //No need to Disable if query is not carried out in first place. { //0.11: Added queryMenuItemsEventArgs.GrayedItems / HiddenItems ContextMenuHelperEx.DisableMenuItems(contextMenu, _iContextMenu, queryMenuItemsEventArgs.GrayedItems, ContextMenuHelperEx.DisabledMethods.Gray); ContextMenuHelperEx.DisableMenuItems(contextMenu, _iContextMenu, queryMenuItemsEventArgs.HiddenItems, ContextMenuHelperEx.DisabledMethods.Remove); } //0.17: Added DefaultItem and DefaultCommand in BeforePopup bool cont = true; if (OnBeforePopup != null) { BeforePopupEventArgs args = new BeforePopupEventArgs (contextMenu, _iContextMenu, intDefaultItem - ShellAPI.CMD_FIRST, strDefaultCommand); OnBeforePopup(this, args); cont = args.ContinuePopup; } if (cont) { //0.18 Fixed Context menu disappear in some case. (By cwharmon) //http://www.codeproject.com/KB/files/DirectoryInfoEx.aspx#xx3475961xx ShellAPI.SetForegroundWindow(this.Handle); uint selected = ShellAPI.TrackPopupMenuEx(contextMenu, ShellAPI.TPM.RETURNCMD, pt.X, pt.Y, this.Handle, IntPtr.Zero); uint msg = 0; ShellAPI.PostMessage(this.Handle, msg, IntPtr.Zero, IntPtr.Zero); if (OnMouseHover != null) OnMouseHover(this, new MouseHoverEventArgs("", "", 0)); if (selected >= ShellAPI.CMD_LAST) { return removeCheckedSymbol(queryMenuItemsEventArgs.ExtraMenuItems[selected - ShellAPI.CMD_LAST]); } if (selected >= ShellAPI.CMD_FIRST) { string command = ContextMenuHelper.GetCommandString(_iContextMenu, selected - ShellAPI.CMD_FIRST, true); if (command == null) return null; if (OnBeforeInvokeCommand != null) { InvokeCommandEventArgs args = new InvokeCommandEventArgs(command, "", selected, items); OnBeforeInvokeCommand(this, args); if (!args.ContinueInvoke) return command; } if (command == "rename") return "rename"; else { //if (items.Length == 1 && items[0] is DirectoryInfoEx) ContextMenuHelper.InvokeCommand(_iContextMenu, selected - ShellAPI.CMD_FIRST, (items[0].Parent != null) ? items[0].Parent.FullName : items[0].FullName, pt); //else //ContextMenuHelper.InvokeCommand(items[0].Parent, // IOTools.GetPIDLPtr(items, true), selected - ShellAPI.CMD_FIRST, // pt); } } } } finally { IOTools.FreePIDL(pidls); if (_iContextMenu != null) { Marshal.ReleaseComObject(_iContextMenu); _iContextMenu = null; } if (_iContextMenu2 != null) { Marshal.ReleaseComObject(_iContextMenu2); _iContextMenu2 = null; } if (_iContextMenu3 != null) { Marshal.ReleaseComObject(_iContextMenu3); _iContextMenu3 = null; } foreach (IntPtr menuPtr in menuPtrConstructed) ShellAPI.DestroyMenu(menuPtr); menuPtrConstructed.Clear(); if (contextMenu != null) ShellAPI.DestroyMenu(contextMenu); if (ptrContextMenu != IntPtr.Zero) Marshal.Release(ptrContextMenu); if (ptrContextMenu2 != IntPtr.Zero) Marshal.Release(ptrContextMenu2); if (PtrContextMenu3 != IntPtr.Zero) Marshal.Release(PtrContextMenu3); } } finally { _contextMenuVisible = false; } } catch { } } return null; }
/// <summary> /// If this method returns true then the caller must call ReleaseNewMenu /// </summary> /// <param name="itm"></param> /// <param name="contextMenu"></param> /// <param name="index"></param> /// <returns></returns> /// <remarks></remarks> public bool SetUpNewMenu(ShellItem itm, IntPtr contextMenu, int index) { int HR; HResult idCount; newMenuPtr = IntPtr.Zero; HR = Ole32.CoCreateInstance(Shell32.CLSID_NewMenu, IntPtr.Zero, (uint)CLSCTX.INPROC_SERVER, Shell32.IID_IContextMenu, out newMenuPtr); if (HR == (int)HResult.S_OK) { newMenu = (IContextMenu)Marshal.GetObjectForIUnknown(newMenuPtr); IntPtr p = IntPtr.Zero; Marshal.QueryInterface(newMenuPtr, ref Shell32.IID_IContextMenu2, out p); if (p != IntPtr.Zero) { newMenu2 = (IContextMenu2)Marshal.GetObjectForIUnknown(p); } Marshal.QueryInterface(newMenuPtr, ref Shell32.IID_IContextMenu3, out p); if (p != IntPtr.Zero) { newMenu3 = (IContextMenu3)Marshal.GetObjectForIUnknown(p); } if (!p.Equals(IntPtr.Zero)) { Marshal.Release(p); p = IntPtr.Zero; } IntPtr iShellExtInitPtr = IntPtr.Zero; HR = (Marshal.QueryInterface(newMenuPtr, ref Shell32.IID_IShellExtInit, out iShellExtInitPtr)); if (HR == (int)HResult.S_OK) { IShellExtInit shellExtInit = (IShellExtInit)Marshal.GetObjectForIUnknown(iShellExtInitPtr); shellExtInit.Initialize(itm.Pidl, IntPtr.Zero, 0); Marshal.ReleaseComObject(shellExtInit); Marshal.Release(iShellExtInitPtr); } if (!newMenuPtr.Equals(IntPtr.Zero)) { Marshal.Release(newMenuPtr); newMenuPtr = IntPtr.Zero; } } if (HR != (int)HResult.S_OK) { ReleaseNewMenu(); #if DEBUG Marshal.ThrowExceptionForHR(HR); #endif return(false); } idCount = newMenu.QueryContextMenu(contextMenu, (uint)index, min, max, (int)CMF.NORMAL); newMenuPtr = User32.GetSubMenu(contextMenu, index); return(true); }
private void release() { if (null != _oContextMenu) { Marshal.ReleaseComObject(_oContextMenu); _oContextMenu = null; } if (null != _oContextMenu2) { Marshal.ReleaseComObject(_oContextMenu2); _oContextMenu2 = null; } if (null != _oContextMenu3) { Marshal.ReleaseComObject(_oContextMenu3); _oContextMenu3 = null; } }
void Initialize(IListItemEx[] items) { this._Items = items; IntPtr[] pidls = new IntPtr[items.Length]; IListItemEx parent = null; for (int n = 0; n < items.Length; ++n) { pidls[n] = Shell32.ILFindLastID(items[n].PIDL); if (parent == null) { if (items[n].ParsingName.Equals(ShellItem.Desktop.ParsingName)) { parent = FileSystemListItem.ToFileSystemItem(IntPtr.Zero, ShellItem.Desktop.Pidl); } else { parent = items[n].Parent; } } else if (!items[n].Parent.Equals(parent)) { throw new Exception("All shell items must have the same parent"); } } if (items.Length == 0) { var desktop = KnownFolders.Desktop as ShellItem; var ishellViewPtr = desktop.GetIShellFolder().CreateViewObject(IntPtr.Zero, typeof(IShellView).GUID); var view = Marshal.GetObjectForIUnknown(ishellViewPtr) as IShellView; view.GetItemObject(SVGIO.SVGIO_BACKGROUND, typeof(IContextMenu).GUID, out _Result); Marshal.ReleaseComObject(view); } else { parent.GetIShellFolder().GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length, pidls, typeof(IContextMenu).GUID, 0, out _Result); } m_ComInterface = (IContextMenu)Marshal.GetTypedObjectForIUnknown(_Result, typeof(IContextMenu)); m_ComInterface2 = m_ComInterface as IContextMenu2; m_ComInterface3 = m_ComInterface as IContextMenu3; m_MessageWindow = new MessageWindow(this); }
/// <summary> /// Shows the context menu. /// </summary> /// <param name="pointScreen">Where to show the menu.</param> public void ShowContextMenu(Point pointScreen) { IntPtr pMenu = IntPtr.Zero, iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero; try { if (arrPIDLs == null) { ReleaseAll(); return; } if (!GetContextMenuInterfaces(oParentFolder, arrPIDLs, out iContextMenuPtr)) { ReleaseAll(); return; } pMenu = DllImports.NativeMethods.User32CreatePopupMenu(); int nResult = oContextMenu.QueryContextMenu( pMenu, 0, CmdFirst, CmdLast, CMF.EXPLORE | CMF.NORMAL | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0)); Marshal.QueryInterface(iContextMenuPtr, ref iidIContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref iidIContextMenu3, out iContextMenuPtr3); oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); uint nSelected = DllImports.NativeMethods.User32TrackPopupMenuEx( pMenu, DllImports.NativeMethods.TPM.RETURNCMD, pointScreen.X, pointScreen.Y, Handle, IntPtr.Zero); DllImports.NativeMethods.User32DestroyMenu(pMenu); pMenu = IntPtr.Zero; if (nSelected != 0) { InvokeCommand(oContextMenu, nSelected, strParentFolder, pointScreen); } } catch { throw; } finally { if (pMenu != IntPtr.Zero) { DllImports.NativeMethods.User32DestroyMenu(pMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } ReleaseAll(); } }
/// <summary> /// Shows the context menu /// </summary> /// <param name="arrFI">FileInfos (should all be in same directory)</param> /// <param name="pointScreen">Where to show the menu</param> private void ShowContextMenu(Point pointScreen) { IntPtr pMenu = IntPtr.Zero, iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero; try { if (null == _arrPIDLs) { ReleaseAll(); return; } if (false == GetContextMenuInterfaces(_oParentFolder, _arrPIDLs, out iContextMenuPtr)) { ReleaseAll(); return; } pMenu = CreatePopupMenu(); var nResult = _oContextMenu.QueryContextMenu( pMenu, 0, CMD_FIRST, CMD_LAST, CMF.EXPLORE | CMF.NORMAL | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0)); Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu3, out iContextMenuPtr3); _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); var nSelected = TrackPopupMenuEx( pMenu, TPM.RETURNCMD, pointScreen.X, pointScreen.Y, Handle, IntPtr.Zero); DestroyMenu(pMenu); pMenu = IntPtr.Zero; if (nSelected != 0) { InvokeCommand(_oContextMenu, nSelected, _strParentFolder, pointScreen); } } catch { throw; } finally { //hook.Uninstall(); if (pMenu != IntPtr.Zero) { DestroyMenu(pMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } ReleaseAll(); } }
private static void ShowContextMenuInternal(DirectoryInfo directory, Point pointScreen, IntPtr hwnd) { var pMenu = IntPtr.Zero; var iContextMenuPtr = IntPtr.Zero; var iContextMenuPtr2 = IntPtr.Zero; var iContextMenuPtr3 = IntPtr.Zero; try { var pidl = GetPidl(directory); if (directory.Parent != null && false == GetContextMenuInterfaces(GetParentFolder(directory.FullName), pidl, out iContextMenuPtr)) { ReleaseAll(); return; } pMenu = DllImports.CreatePopupMenu(); _oContextMenu.QueryContextMenu(pMenu, 0, CmdFirst, CmdLast, Enums.Cmf.EXPLORE | Enums.Cmf.NORMAL | ((Control.ModifierKeys & Keys.Shift) != 0 ? Enums.Cmf.EXTENDEDVERBS : 0)); Marshal.QueryInterface(iContextMenuPtr, ref _iidIContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref _iidIContextMenu3, out iContextMenuPtr3); _oContextMenu2 = (IContextMenu2) Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof (IContextMenu2)); _oContextMenu3 = (IContextMenu3) Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof (IContextMenu3)); var nSelected = DllImports.TrackPopupMenuEx(pMenu, Enums.Tpm.RETURNCMD, pointScreen.X, pointScreen.Y, hwnd, IntPtr.Zero); DllImports.DestroyMenu(pMenu); pMenu = IntPtr.Zero; if (nSelected != 0) { InvokeCommand(_oContextMenu, nSelected, _strParentFolder, pointScreen); } } catch { } finally { if (pMenu != IntPtr.Zero) { DllImports.DestroyMenu(pMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } ReleaseAll(); } }
private void ContextMenuStrip_Opening(object sender, CancelEventArgs e) { ContextMenuStrip strip = (ContextMenuStrip) sender; if ((strip.Items.Count <= 1) && (strip.Items[0].Text == string.Empty)) { if ((this.ContextMenu == null) && (this.FileNames != null)) { this.ContextMenu = GetContextMenu(this.Owner, this.ParentName, this.FileNames); } if (this.ContextMenu == null) { e.Cancel = true; } else { this.ContextMenu3 = this.ContextMenu as IContextMenu3; if (this.ContextMenu3 == null) { this.ContextMenu2 = this.ContextMenu as IContextMenu2; } this.Menu = Windows.CreatePopupMenu(); this.ContextMenu.QueryContextMenu(this.Menu, 0, 1, 0x7fff, this.Options | (((Control.ModifierKeys & Keys.Shift) > Keys.None) ? CMF.CMF_EXTENDEDVERBS : CMF.CMF_NORMAL)); if (this.ContextMenu3 != null) { this.ContextMenu3.HandleMenuMsg2(0x117, this.Menu, IntPtr.Zero, IntPtr.Zero); } else if (this.ContextMenu2 != null) { this.ContextMenu2.HandleMenuMsg(0x117, this.Menu, IntPtr.Zero); } this.InitializeToolStrip(strip, this.Menu); } } }
/// <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 void ShowContextMenu() { IntPtr contextMenu = IntPtr.Zero, iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero; try { if (ShellFolders.GetIContextMenu(parentShellFolder, pidls, out iContextMenuPtr, out iContextMenu)) { contextMenu = ShellFolders.CreatePopupMenu(); iContextMenu.QueryContextMenu( contextMenu, 0, ShellFolders.CMD_FIRST, ShellFolders.CMD_LAST, ShellFolders.CMF.EXPLORE | ShellFolders.CMF.CANRENAME | ((Control.ModifierKeys & Keys.Shift) != 0 ? ShellFolders.CMF.EXTENDEDVERBS : 0)); // add to stacks option for folders if (Interop.Shell.Exists(paths[0]) && (File.GetAttributes(this.paths[0]) & FileAttributes.Directory) == FileAttributes.Directory) { ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.SEPARATOR, 1, string.Empty); ShellFolders.AppendMenu(contextMenu, ShellFolders.MFT.BYCOMMAND, (int)CairoContextMenuItem.AddToStacks, Localization.DisplayString.sInterface_AddToStacks); } Marshal.QueryInterface(iContextMenuPtr, ref ShellFolders.IID_IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref ShellFolders.IID_IContextMenu3, out iContextMenuPtr3); try { iContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); iContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); } catch (Exception) { } uint selected = ShellFolders.TrackPopupMenuEx( contextMenu, ShellFolders.TPM.RETURNCMD, this.x, this.y, this.Handle, IntPtr.Zero); if (selected >= ShellFolders.CMD_FIRST) { string command = ShellFolders.GetCommandString(iContextMenu, selected - ShellFolders.CMD_FIRST, true); if ((CairoContextMenuItem)selected == CairoContextMenuItem.AddToStacks) { command = "addStack"; } else { ShellFolders.InvokeCommand( iContextMenu, selected - ShellFolders.CMD_FIRST, parent, new Point(this.x, this.y)); } if (this.itemSelected != null) { itemSelected(command, paths[0], sender); } } } else { CairoLogger.Instance.Debug("Error retrieving IContextMenu"); } } catch (Exception) { } finally { if (iContextMenu != null) { Marshal.FinalReleaseComObject(iContextMenu); iContextMenu = null; } if (iContextMenu2 != null) { Marshal.FinalReleaseComObject(iContextMenu2); iContextMenu2 = null; } if (iContextMenu3 != null) { Marshal.FinalReleaseComObject(iContextMenu3); iContextMenu3 = null; } if (parentShellFolder != null) { Marshal.FinalReleaseComObject(parentShellFolder); parentShellFolder = null; } if (contextMenu != null) { ShellFolders.DestroyMenu(contextMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } for (int i = 0; i < pidls.Length; i++) { Marshal.FreeCoTaskMem(pidls[i]); pidls[i] = IntPtr.Zero; } } }
public static void ShowContextMenu(IntPtr handle, IShellFolder desktop, string parent, List <FileSystemInfo> lst, double x, double y, ref IContextMenu2 newContextMenu2, ref IntPtr newSubmenuPtr) { if (lst == null) { ShowContextMenuFolder(handle, desktop, parent, lst, x, y, ref newContextMenu2, ref newSubmenuPtr); return; } IntPtr PPopup = IntPtr.Zero, PIDLParent = IntPtr.Zero, PSHParent = IntPtr.Zero; IntPtr PContext = IntPtr.Zero, PContext2 = IntPtr.Zero, PContext3 = IntPtr.Zero; List <IntPtr> ChildrenList = null; IContextMenu CContext = null; IContextMenu2 CContext2 = null; IContextMenu3 CContext3 = null; IShellFolder SHParent = null; try { //親フォルダの PIDL を取得する uint fcharcnt = 0; SFGAO fattr = SFGAO.BROWSABLE; if (desktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, parent, ref fcharcnt, out PIDLParent, ref fattr) == Shell32Wrapper.S_OK) { //親フォルダのシェルフォルダのポインタを取得する if (desktop.BindToObject(PIDLParent, IntPtr.Zero, GUIDs.IID_IShellFolder, out PSHParent) == Shell32Wrapper.S_OK) { //親フォルダのIShellFolder を取得する SHParent = (IShellFolder)Marshal.GetTypedObjectForIUnknown(PSHParent, typeof(IShellFolder)); ChildrenList = new List <IntPtr>(); //対象ファイルの PIDL (親のシェルフォルダからの相対 PIDL)を取得する foreach (var files in lst) { IntPtr PFile; if (SHParent.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, files.Name, ref fcharcnt, out PFile, ref fattr) == Shell32Wrapper.S_OK) { ChildrenList.Add(PFile); } } //対象ファイルの IContextMenu へのポインタを取得する IntPtr[] children = ChildrenList.ToArray(); if (SHParent.GetUIObjectOf(IntPtr.Zero, (uint)children.Length, children, GUIDs.IID_IContextMenu, IntPtr.Zero, out PContext) == Shell32Wrapper.S_OK) { //対象ファイルの IContextMenu を取得する CContext = (IContextMenu)Marshal.GetTypedObjectForIUnknown(PContext, typeof(IContextMenu)); //対象ファイルの IContextMenu2, IContextMenu3 のポインタを取得する Marshal.QueryInterface(PContext, ref GUIDs.IID_IContextMenu2, out PContext2); Marshal.QueryInterface(PContext, ref GUIDs.IID_IContextMenu3, out PContext3); CContext2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(PContext2, typeof(IContextMenu2)); CContext3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(PContext3, typeof(IContextMenu3)); //ポップアップメニューを作成する PPopup = User32Wrapper.CreatePopupMenu(); //ポップアップメニューに、コンテキストメニュー IContextMenu を追加する CMF ContextMenuFlag = CMF.EXPLORE | CMF.CANRENAME; CContext.QueryContextMenu(PPopup, 0, Shell32Wrapper.CMD_FIRST, Shell32Wrapper.CMD_LAST, ContextMenuFlag); //ポップアップメニューを表示する //呼び出しをブロックします uint selected = User32Wrapper.TrackPopupMenuEx(PPopup, TPM.RETURNCMD, (int)x, (int)y, handle, IntPtr.Zero); if (selected >= Shell32Wrapper.CMD_FIRST) { uint cmdidx = selected - Shell32Wrapper.CMD_FIRST; Helper.InvokeCommand(CContext, cmdidx, parent, new Point(x, y)); } } } } } #region finally finally { if (PPopup != null) { User32Wrapper.DestroyMenu(PPopup); } if (CContext3 != null) { Marshal.FinalReleaseComObject(CContext3); CContext3 = null; } if (CContext2 != null) { Marshal.FinalReleaseComObject(CContext2); CContext2 = null; } if (CContext != null) { Marshal.FinalReleaseComObject(CContext); CContext = null; } if (ChildrenList != null) { foreach (var child in ChildrenList) { Marshal.FreeCoTaskMem(child); } ChildrenList = null; } if (SHParent != null) { Marshal.FinalReleaseComObject(SHParent); SHParent = null; } if (PIDLParent != IntPtr.Zero) { Marshal.FreeCoTaskMem(PIDLParent); } if (PSHParent != IntPtr.Zero) { Marshal.Release(PSHParent); } if (PContext != IntPtr.Zero) { Marshal.Release(PContext); } if (PContext2 != IntPtr.Zero) { Marshal.Release(PContext2); } if (PContext3 != IntPtr.Zero) { Marshal.Release(PContext3); } } #endregion }
//色々サンプルを書きたいのよ private void Button_Click(object sender, RoutedEventArgs e) { try { this.hoge.ExplorerBrowserControl.Navigate((ShellObject)KnownFolders.Desktop); return; IntPtr PDesktop; Shell32Wrapper.SHGetDesktopFolder(out PDesktop); IShellFolder SHDesktop = (IShellFolder)Marshal.GetTypedObjectForIUnknown(PDesktop, typeof(IShellFolder)); IntPtr strr = Marshal.AllocCoTaskMem(Shell32Wrapper.MAX_PATH * 2 + 4); Marshal.WriteInt32(strr, 0, 0); IntPtr ptrPid; Shell32Wrapper.SHGetSpecialFolderLocation(IntPtr.Zero, (int)SpecialFolderID.CSIDL_DRIVES, out ptrPid); //なんかDesktop自身の名前は取得方法がわからん //if (SHDesktop.GetDisplayNameOf(desktop, SHGNO.NORMAL, strr) == Shell32Wrapper.S_OK) if (SHDesktop.GetDisplayNameOf(ptrPid, SHGNO.NORMAL, strr) == Shell32Wrapper.S_OK) { StringBuilder buf = new StringBuilder(Shell32Wrapper.MAX_PATH); ShlwapiWrapper.StrRetToBuf(strr, PDesktop, buf, Shell32Wrapper.MAX_PATH); MessageBox.Show(buf.ToString()); } Marshal.FreeCoTaskMem(strr); //対象ファイルの親のシェルフォルダの PIDL を取得する IntPtr PFolder; uint fcharcnt = 0; SFGAO fattr = SFGAO.BROWSABLE; if (SHDesktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, @"C:\temp", ref fcharcnt, out PFolder, ref fattr) == Shell32Wrapper.S_OK) { //対象ファイルの親のシェルフォルダのポインタを取得する IntPtr PPV; if (SHDesktop.BindToObject(PFolder, IntPtr.Zero, GUIDs.IID_IShellFolder, out PPV) == Shell32Wrapper.S_OK) { //対象ファイルの親のシェルフォルダ IShellFolder を取得する IShellFolder SHFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(PPV, typeof(IShellFolder)); //対象ファイルの PIDL (親のシェルフォルダからの相対 PIDL)を取得する IntPtr PFile; if (SHFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, "a.vbs", ref fcharcnt, out PFile, ref fattr) == Shell32Wrapper.S_OK) { //対象ファイルの IContextMenu へのポインタを取得する IntPtr[] children = new IntPtr[] { PFile }; IntPtr PContext; if (SHFolder.GetUIObjectOf(IntPtr.Zero, (uint)children.Length, children, GUIDs.IID_IContextMenu, IntPtr.Zero, out PContext) == Shell32Wrapper.S_OK) { //対象ファイルの IContextMenu を取得する IContextMenu CContext = (IContextMenu)Marshal.GetTypedObjectForIUnknown(PContext, typeof(IContextMenu)); //対象ファイルの IContextMenu2, IContextMenu3 のポインタを取得する IntPtr PContext2, PContext3; Marshal.QueryInterface(PContext, ref GUIDs.IID_IContextMenu2, out PContext2); Marshal.QueryInterface(PContext, ref GUIDs.IID_IContextMenu3, out PContext3); IContextMenu2 CContext2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(PContext2, typeof(IContextMenu2)); IContextMenu3 CContext3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(PContext3, typeof(IContextMenu3)); //ポップアップメニューを作成する IntPtr PPopup = User32Wrapper.CreatePopupMenu(); //ポップアップメニューに、コンテキストメニュー IContextMenu を追加する CMF ContextMenuFlag = CMF.EXPLORE | CMF.CANRENAME; CContext.QueryContextMenu(PPopup, 0, Shell32Wrapper.CMD_FIRST, Shell32Wrapper.CMD_LAST, ContextMenuFlag); //ポップアップメニューを表示する //呼び出しをブロックします uint selected = User32Wrapper.TrackPopupMenuEx(PPopup, TPM.RETURNCMD, 0, 0, new System.Windows.Interop.WindowInteropHelper(this).Handle, IntPtr.Zero); if (selected >= Shell32Wrapper.CMD_FIRST) { uint cmdidx = selected - Shell32Wrapper.CMD_FIRST; Helper.InvokeCommand(CContext, cmdidx, @"C:\temp", new Point(0, 0)); } User32Wrapper.DestroyMenu(PPopup); Marshal.ReleaseComObject(CContext3); Marshal.ReleaseComObject(CContext2); Marshal.Release(PContext3); Marshal.Release(PContext2); Marshal.ReleaseComObject(CContext); } Marshal.Release(PContext); } Marshal.FreeCoTaskMem(PFile); Marshal.ReleaseComObject(SHFolder); } Marshal.Release(PPV); } //なんでかExceptionが発生するのでコメントアウト ← 解放するメソッドを間違えていた //Marshal.Release(PIDLParent); Marshal.FreeCoTaskMem(PFolder); Marshal.ReleaseComObject(SHDesktop); Marshal.Release(PDesktop); } catch (Exception ex) { MessageBox.Show(ex.Message, ex.GetType().Name, MessageBoxButton.OK, MessageBoxImage.Error); } }
private List <MenuInfo> GenerateMenuInfo(IntPtr menu, IContextMenu contextMenu, IContextMenu3 contextMenu3) { if (menu == IntPtr.Zero) { return(new List <MenuInfo>()); } var count = User32.GetMenuItemCount(menu); return(Enumerable.Range(0, count).Select(it => { var cch = GetTextLength(menu, it, true) + 1; var itemInfo = new MENUITEMINFO(); itemInfo.cbSize = (uint)Marshal.SizeOf(itemInfo); itemInfo.fMask = MIIM.MIIM_STRING | MIIM.MIIM_SUBMENU | MIIM.MIIM_ID; itemInfo.cch = cch; itemInfo.dwTypeData = Marshal.AllocCoTaskMem((int)cch * sizeof(char)); itemInfo.hSubMenu = IntPtr.Zero; User32.GetMenuItemInfo(menu, it, true, ref itemInfo); var title = Marshal.PtrToStringAuto(itemInfo.dwTypeData); Marshal.FreeCoTaskMem(itemInfo.dwTypeData); var id = Convert.ToInt64(itemInfo.wID); var command = string.Empty; if (!string.IsNullOrEmpty(title) && id > 0 && uint.TryParse(id + "", out var uid)) { command = GetCommandString(contextMenu, uid, true); } if (itemInfo.hSubMenu != IntPtr.Zero) { Marshal.AllocCoTaskMem(sizeof(int)).UseCoTask(indexPointer => { Marshal.WriteInt32(indexPointer, it); contextMenu3.HandleMenuMsg2(KAN.WM_INITMENUPOPUP, itemInfo.hSubMenu, indexPointer, out _); }); } return new MenuInfo { CommandName = command, Title = title, Id = id, SubMenu = GenerateMenuInfo(itemInfo.hSubMenu, contextMenu, contextMenu3) }; }).ToList()); }
public void Show(Point location, params string[] pathList) { IntPtr[] pidls = ShellHelper.GetPIDLs(pathList); IShellFolder parentShellFolder; string parentDirectory = null; if (pathList[0].StartsWith("::{")) { parentShellFolder = ShellHelper.GetDesktopFolder(); } else { parentDirectory = ShellHelper.GetParentDirectoryPath(pathList[0]); parentShellFolder = ShellHelper.GetShellFolder(parentDirectory); } IntPtr contextMenu = IntPtr.Zero; IntPtr iContextMenuPtr = IntPtr.Zero; IntPtr iContextMenuPtr2 = IntPtr.Zero; IntPtr iContextMenuPtr3 = IntPtr.Zero; // Show / Invoke try { if (ContextMenuHelper.GetIContextMenu(parentShellFolder, pidls, out iContextMenuPtr, out iContextMenu)) { contextMenu = User32.CreatePopupMenu(); iContextMenu.QueryContextMenu(contextMenu, 0, ShellApi.CmdFirst, ShellApi.CmdLast, CMF.Explore | CMF.CanRename | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.ExtendedVerbs : 0)); Marshal.QueryInterface(iContextMenuPtr, ref ShellGuids.IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref ShellGuids.IContextMenu3, out iContextMenuPtr3); try { iContextMenu2 = (IContextMenu2) Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof (IContextMenu2)); iContextMenu3 = (IContextMenu3) Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof (IContextMenu3)); } catch (Exception) { } uint selected = User32.TrackPopupMenuEx(contextMenu, TPM.ReturnCmd, location.X, location.Y, this.Handle, IntPtr.Zero); if (selected >= ShellApi.CmdFirst) { string command = ContextMenuHelper.GetCommandString(iContextMenu, selected - ShellApi.CmdFirst, true); if (command == "Explore") { /*if (!br.FolderView.SelectedNode.IsExpanded) br.FolderView.SelectedNode.Expand(); br.FolderView.SelectedNode = br.FolderView.SelectedNode.Nodes[hitTest.Item.Text];*/ } else if (command == "rename") { /*hitTest.Item.BeginEdit();*/ } else { ContextMenuHelper.InvokeCommand(iContextMenu, selected - ShellApi.CmdFirst, parentDirectory, location); } } } } catch (Exception e) { #if DEBUG MessageBox.Show("", e.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); #endif } 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) { User32.DestroyMenu(contextMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } } }
public void ShowContextMenu() { IntPtr contextMenu = IntPtr.Zero, iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero; try { if (ShellFolders.GetIContextMenu(parentShellFolder, pidls, out iContextMenuPtr, out iContextMenu)) { // get some properties about our file(s) bool allFolders = true; bool allInStacks = true; foreach (SystemFile file in paths) { if (!file.IsDirectory) { allFolders = false; } else { bool contains = false; foreach (SystemDirectory dir in StacksManager.StackLocations) { if (dir.Equals(file.FullName)) { contains = true; break; } } if (!contains) { allInStacks = false; } } } contextMenu = ShellFolders.CreatePopupMenu(); uint numPrepended = prependItems(contextMenu, allFolders, allInStacks); iContextMenu.QueryContextMenu( contextMenu, numPrepended, ShellFolders.CMD_FIRST, ShellFolders.CMD_LAST, ShellFolders.CMF.EXPLORE | ShellFolders.CMF.CANRENAME | ((Control.ModifierKeys & Keys.Shift) != 0 ? ShellFolders.CMF.EXTENDEDVERBS : 0)); appendItems(contextMenu, allFolders, allInStacks); Marshal.QueryInterface(iContextMenuPtr, ref ShellFolders.IID_IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref ShellFolders.IID_IContextMenu3, out iContextMenuPtr3); try { iContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); iContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); } catch (Exception) { } uint selected = ShellFolders.TrackPopupMenuEx( contextMenu, ShellFolders.TPM.RETURNCMD, this.x, this.y, this.Handle, IntPtr.Zero); if (selected >= ShellFolders.CMD_FIRST) { string command = ShellFolders.GetCommandString(iContextMenu, selected - ShellFolders.CMD_FIRST, true); // set action strings for us to use in our custom execution function switch ((CairoContextMenuItem)selected) { case CairoContextMenuItem.AddToStacks: command = "addStack"; break; case CairoContextMenuItem.RemoveFromStacks: command = "removeStack"; break; case CairoContextMenuItem.OpenInNewWindow: command = "openWithShell"; break; default: if (command == "open" && allFolders) { // suppress running system code command = "openFolder"; } else { ShellFolders.InvokeCommand( iContextMenu, selected - ShellFolders.CMD_FIRST, parent, new Point(this.x, this.y)); } break; } if (this.itemSelected != null) { itemSelected(command, paths[0].FullName, sender); } } } else { CairoLogger.Instance.Debug("Error retrieving IContextMenu"); } } catch (Exception) { } finally { if (iContextMenu != null) { Marshal.FinalReleaseComObject(iContextMenu); iContextMenu = null; } if (iContextMenu2 != null) { Marshal.FinalReleaseComObject(iContextMenu2); iContextMenu2 = null; } if (iContextMenu3 != null) { Marshal.FinalReleaseComObject(iContextMenu3); iContextMenu3 = null; } if (parentShellFolder != null) { Marshal.FinalReleaseComObject(parentShellFolder); parentShellFolder = null; } if (contextMenu != null) { ShellFolders.DestroyMenu(contextMenu); } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); } if (iContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr2); } if (iContextMenuPtr3 != IntPtr.Zero) { Marshal.Release(iContextMenuPtr3); } for (int i = 0; i < pidls.Length; i++) { Marshal.FreeCoTaskMem(pidls[i]); pidls[i] = IntPtr.Zero; } } }
// public void iContextMenu(string sParent, string sSelected, System.Drawing.Point location, object f1, bool bSpecialFolderFlag) public void iContextMenu(string sParent, string sSelected, bool bSpecialFolderFlag) { IntPtr shellFolderPtr; SHGetDesktopFolder(out shellFolderPtr); iShellFolder.IShellFolder shellFolder = (iShellFolder.IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(iShellFolder.IShellFolder)); uint pchEaten = 0; int nResult = 0; IntPtr pPIDL = IntPtr.Zero; iShellFolder.SFGAO pdwAttributes = iShellFolder.SFGAO.FILESYSTEM; if (bSpecialFolderFlag) //for root drives - get "My Computer" { nResult = ShellExtensions.SHGetSpecialFolderLocation(this.Handle, ShellExtensions.CSIDL.CSIDL_DRIVES, out pPIDL); } else { nResult = shellFolder.ParseDisplayName(this.Handle, IntPtr.Zero, sParent, ref pchEaten, out pPIDL, ref pdwAttributes); } if(nResult == 0) { // Get the IShellFolder for folder IntPtr pUnknownParentFolder = IntPtr.Zero; if (shellFolder.BindToObject(pPIDL, IntPtr.Zero, ref iShellFolder.Guid_IShellFolder.IID_IShellFolder, out pUnknownParentFolder) == S_OK) { // Free the PIDL first Marshal.FreeCoTaskMem(pPIDL); pPIDL = IntPtr.Zero; IntPtr[] aPidl = new IntPtr[1]; shellFolder = (iShellFolder.IShellFolder)Marshal.GetTypedObjectForIUnknown(pUnknownParentFolder, typeof(iShellFolder.IShellFolder)); nResult = shellFolder.ParseDisplayName(this.Handle, IntPtr.Zero, sSelected, ref pchEaten, out pPIDL, ref pdwAttributes); aPidl[0] = pPIDL; IntPtr iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero;; shellFolder.GetUIObjectOf(this.Handle, 1, aPidl, ref IID_IContextMenu, 0, out iContextMenuPtr); //********************* _oContextMenu = (IContextMenu)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr, typeof(IContextMenu)); IntPtr pUnknownContextMenu2 = IntPtr.Zero; if (S_OK == Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu2, out pUnknownContextMenu2)) { _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu2, typeof(IContextMenu2)); } IntPtr pUnknownContextMenu3 = IntPtr.Zero; if (S_OK == Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu3, out pUnknownContextMenu3)) { _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu3, typeof(IContextMenu3)); } IntPtr pMenu = IntPtr.Zero; pMenu = CreatePopupMenu(); nResult = _oContextMenu.QueryContextMenu( pMenu, 0, CMD_FIRST, CMD_LAST, CMF.EXPLORE | CMF.NORMAL | ((Control.ModifierKeys & System.Windows.Forms.Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0)); Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu3, out iContextMenuPtr3); _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); uint nSelected = TrackPopupMenuEx( pMenu, TPM.RETURNCMD, Control.MousePosition.X, Control.MousePosition.Y, this.Handle, IntPtr.Zero); if (nSelected != 0) { InvokeCommand(_oContextMenu, nSelected, sParent, Control.MousePosition, this.Handle); } DestroyMenu(pMenu); pMenu = IntPtr.Zero; if (iContextMenuPtr != IntPtr.Zero) Marshal.Release(iContextMenuPtr); if (iContextMenuPtr2 != IntPtr.Zero) Marshal.Release(iContextMenuPtr2); if (iContextMenuPtr3 != IntPtr.Zero) Marshal.Release(iContextMenuPtr3); release(); } } }
/// <summary> /// Shows the context menu /// </summary> /// <param name="arrFI">FileInfos (should all be in same directory)</param> /// <param name="pointScreen">Where to show the menu</param> private void ShowContextMenu(Point pointScreen) { IntPtr pMenu = IntPtr.Zero, iContextMenuPtr = IntPtr.Zero, iContextMenuPtr2 = IntPtr.Zero, iContextMenuPtr3 = IntPtr.Zero; try { if (null == _arrPIDLs) { ReleaseAll(); return; } if (false == GetContextMenuInterfaces(_oParentFolder, _arrPIDLs, out iContextMenuPtr)) { ReleaseAll(); return; } pMenu = CreatePopupMenu(); int nResult = _oContextMenu.QueryContextMenu( pMenu, 0, CMD_FIRST, CMD_LAST, CMF.EXPLORE | CMF.NORMAL | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0)); Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu2, out iContextMenuPtr2); Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu3, out iContextMenuPtr3); _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2)); _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3)); uint nSelected = TrackPopupMenuEx( pMenu, TPM.RETURNCMD, pointScreen.X, pointScreen.Y, this.Handle, IntPtr.Zero); DestroyMenu(pMenu); pMenu = IntPtr.Zero; if (nSelected != 0) { InvokeCommand(_oContextMenu, nSelected, _strParentFolder, pointScreen); } } catch { throw; } finally { //hook.Uninstall(); if (pMenu != IntPtr.Zero) { DestroyMenu(pMenu); } if (iContextMenuPtr != IntPtr.Zero) Marshal.Release(iContextMenuPtr); if (iContextMenuPtr2 != IntPtr.Zero) Marshal.Release(iContextMenuPtr2); if (iContextMenuPtr3 != IntPtr.Zero) Marshal.Release(iContextMenuPtr3); ReleaseAll(); } }
/// <summary>Gets the interfaces to the context menu</summary> /// <param name="oParentFolder">Parent folder</param> /// <param name="arrPIDLs">PIDLs</param> /// <returns>true if it got the interfaces, otherwise false</returns> private bool GetContextMenuInterfaces(IShellFolder oParentFolder, IntPtr[] arrPIDLs) { IntPtr pUnknownContextMenu = IntPtr.Zero; int nResult = oParentFolder.GetUIObjectOf( IntPtr.Zero, (uint)arrPIDLs.Length, arrPIDLs, ref IID_IContextMenu, IntPtr.Zero, out pUnknownContextMenu); if (S_OK == nResult) { _oContextMenu = (IContextMenu)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu, typeof(IContextMenu)); IntPtr pUnknownContextMenu2 = IntPtr.Zero; if (S_OK == Marshal.QueryInterface(pUnknownContextMenu, ref IID_IContextMenu2, out pUnknownContextMenu2)) { _oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu2, typeof(IContextMenu2)); } IntPtr pUnknownContextMenu3 = IntPtr.Zero; if (S_OK == Marshal.QueryInterface(pUnknownContextMenu, ref IID_IContextMenu3, out pUnknownContextMenu3)) { _oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(pUnknownContextMenu3, typeof(IContextMenu3)); } return true; } else { return false; } }
/// <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; }
void Initialize(IListItemEx item) { Guid iise = typeof(IShellExtInit).GUID; var ishellViewPtr = (item.IsDrive || !item.IsFileSystem || item.IsNetworkPath) ? item.GetIShellFolder().CreateViewObject(IntPtr.Zero, typeof(IShellView).GUID) : item.Parent.GetIShellFolder().CreateViewObject(IntPtr.Zero, typeof(IShellView).GUID); var view = Marshal.GetObjectForIUnknown(ishellViewPtr) as IShellView; view?.GetItemObject(SVGIO.SVGIO_BACKGROUND, typeof(IContextMenu).GUID, out _Result); if (view != null) { Marshal.ReleaseComObject(view); } m_ComInterface = (IContextMenu)Marshal.GetTypedObjectForIUnknown(_Result, typeof(IContextMenu)); m_ComInterface2 = m_ComInterface as IContextMenu2; m_ComInterface3 = m_ComInterface as IContextMenu3; IntPtr iShellExtInitPtr; if (Marshal.QueryInterface(_Result, ref iise, out iShellExtInitPtr) == (int)HResult.S_OK) { var iShellExtInit = Marshal.GetTypedObjectForIUnknown(iShellExtInitPtr, typeof(IShellExtInit)) as IShellExtInit; try { var hhh = IntPtr.Zero; iShellExtInit?.Initialize(_ShellView.CurrentFolder.PIDL, null, 0); if (iShellExtInit != null) { Marshal.ReleaseComObject(iShellExtInit); } Marshal.Release(iShellExtInitPtr); } catch { } } m_MessageWindow = new MessageWindow(this); }