private void InvokeContextMenuDefault(FileInfo[] arrFI) { // Release all resources first. ReleaseAll(); IntPtr pMenu = IntPtr.Zero; try { _arrPIDLs = GetPIDLs(arrFI); if (null == _arrPIDLs) { ReleaseAll(); return; } if (false == GetContextMenuInterfaces(_oParentFolder, _arrPIDLs)) { ReleaseAll(); return; } pMenu = User32.CreatePopupMenu(); int nResult = _oContextMenu.QueryContextMenu( pMenu, 0, CMD_FIRST, CMD_LAST, CMF.DEFAULTONLY | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0)); uint nDefaultCmd = (uint)User32.GetMenuDefaultItem(pMenu, false, 0); if (nDefaultCmd >= CMD_FIRST) { InvokeCommand(_oContextMenu, nDefaultCmd, arrFI[0].DirectoryName, Control.MousePosition); } User32.DestroyMenu(pMenu); pMenu = IntPtr.Zero; } catch { throw; } finally { if (pMenu != IntPtr.Zero) { User32.DestroyMenu(pMenu); } ReleaseAll(); } }
public void GetContextMenus(string path) { IntPtr desktopPtr; IShellFolder desktop = ShellAPI.GetDesktopFolder(out desktopPtr); IntPtr ownerHwnd = IntPtr.Zero; IShellFolder Root; string FolderPath = Directory.GetParent(path).FullName; IntPtr Pidl = IntPtr.Zero; IShellFolder parent; uint i, j = 0; desktop.ParseDisplayName(ownerHwnd, IntPtr.Zero, FolderPath, out i, out Pidl, ref j); desktop.BindToObject(Pidl, IntPtr.Zero, ref Guids.IID_IShellFolder, out Root); Marshal.ReleaseComObject(desktop); IEnumIDList fileEnum = null; IEnumIDList folderEnum = null; IntPtr fileEnumPtr = IntPtr.Zero; IntPtr folderEnumPtr = IntPtr.Zero; IntPtr pidlSub; int celtFetched; if (Root.EnumObjects(ownerHwnd, SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN, out fileEnumPtr) == ShellAPI.S_OK) { fileEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(fileEnumPtr); while (fileEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == ShellAPI.S_FALSE) { string name = ShellAPI.GetNameByPIDL(pidlSub); } } if (Root.EnumObjects(ownerHwnd, SHCONTF.NONFOLDERS | SHCONTF.INCLUDEHIDDEN, out folderEnumPtr) == ShellAPI.S_OK) { folderEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(folderEnumPtr); while (folderEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == ShellAPI.S_FALSE) { string name = ShellAPI.GetNameByPIDL(pidlSub); if (Path.GetFileName(path) == name) { IntPtr PIDL = pidlSub; IShellFolder IParent = Root; IntPtr[] pidls = new IntPtr[1]; pidls[0] = PIDL; //get IContextMenu interface IntPtr iContextMenuPtr = IntPtr.Zero; iContextMenuPtr = IParent.GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length, pidls, ref Guids.IID_IContextMenu, out iContextMenuPtr); IContextMenu iContextMenu = (IContextMenu)Marshal.GetObjectForIUnknown(iContextMenuPtr); IntPtr contextMenu = ShellAPI.CreatePopupMenu(); iContextMenu.QueryContextMenu(contextMenu, 0, ShellAPI.CMD_FIRST, ShellAPI.CMD_LAST, CMF.NORMAL | CMF.EXPLORE); ParseMenu(contextMenu); } } } Marshal.ReleaseComObject(Root); }
public void Create() { if (_menuHandle == IntPtr.Zero) { _menuHandle = RUser32.CreatePopupMenu(); _face.QueryContextMenu(_menuHandle, 0, RWinShell.CMD_FIRST, RWinShell.CMD_LAST, ECmf.NORMAL | ECmf.EXPLORE); } }
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 ShowIn(UIElement element) { var point = element.PointToScreen(Mouse.GetPosition(element)); var popupMenu = ShellContextMenuNativeMethods.CreatePopupMenu(); _contextMenu.QueryContextMenu(popupMenu, 0, CmdFirst, CmdLast, CMF.EXPLORE); int command = ShellContextMenuNativeMethods.TrackPopupMenuEx(popupMenu, TPM.TPM_RETURNCMD, (int)point.X, (int)point.Y, _messageHandler.Handle, IntPtr.Zero); if (command > 0) { _messageHandler.InvokeCommand(command - CmdFirst); } }
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 OpenItemContextMenu(ShellItem itemHit, int x, int y) { // TODO: we need a min and max for the menu items. // see http://www.codeproject.com/Articles/4025/Use-Shell-ContextMenu-in-your-applications for more // The shell folder we use to get the UI object is either the folder itself if the // item is a folder, or the parent folder otherwise. var shellFolder = itemHit.IsFolder ? itemHit.ShellFolderInterface : itemHit.ParentItem.ShellFolderInterface; // The item pidl is either the folder if the item is a folder, or the combined pidl otherwise. var fullIdList = itemHit.IsFolder ? PidlManager.PidlToIdlist(itemHit.PIDL) : PidlManager.Combine(PidlManager.PidlToIdlist(itemHit.ParentItem.PIDL), PidlManager.PidlToIdlist(itemHit.RelativePIDL)); // Get the UI object of the context menu. IntPtr apidl = PidlManager.PidlsToAPidl(new IntPtr[] { PidlManager.IdListToPidl(fullIdList) }); IntPtr ppv = IntPtr.Zero; shellFolder.GetUIObjectOf(Handle, 1, apidl, Shell32.IID_IContextMenu, 0, out ppv); // If we have an item, cast it. if (ppv != IntPtr.Zero) { IContextMenu contextMenu = (IContextMenu)Marshal.GetObjectForIUnknown(ppv); var popupMenu = new ContextMenu(); contextMenu.QueryContextMenu(popupMenu.Handle, 0, 0, 65525, CMF.CMF_EXPLORE); popupMenu.Show(this, new Point(x, y)); } }
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 static void HandleApplicationLaunch(string application, AppServiceRequestReceivedEventArgs args) { var arguments = args.Request.Message.Get("Arguments", ""); var workingDirectory = args.Request.Message.Get("WorkingDirectory", ""); try { Process process = new Process(); process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = application; // Show window if workingDirectory (opening terminal) process.StartInfo.CreateNoWindow = string.IsNullOrEmpty(workingDirectory); if (arguments == "runas") { process.StartInfo.UseShellExecute = true; process.StartInfo.Verb = "runas"; if (Path.GetExtension(application).ToLower() == ".msi") { process.StartInfo.FileName = "msiexec.exe"; process.StartInfo.Arguments = $"/a \"{application}\""; } } else if (arguments == "runasuser") { process.StartInfo.UseShellExecute = true; process.StartInfo.Verb = "runasuser"; if (Path.GetExtension(application).ToLower() == ".msi") { process.StartInfo.FileName = "msiexec.exe"; process.StartInfo.Arguments = $"/i \"{application}\""; } } else { process.StartInfo.Arguments = arguments; } process.StartInfo.WorkingDirectory = workingDirectory; process.Start(); } catch (Win32Exception) { Process process = new Process(); process.StartInfo.UseShellExecute = true; process.StartInfo.Verb = "runas"; process.StartInfo.FileName = application; process.StartInfo.CreateNoWindow = true; process.StartInfo.Arguments = arguments; process.StartInfo.WorkingDirectory = workingDirectory; try { process.Start(); } catch (Win32Exception) { try { var split = application.Split(';').Where(x => !string.IsNullOrWhiteSpace(x)); if (split.Count() == 1) { Process.Start(application); } else { var groups = split.GroupBy(x => new { Dir = Path.GetDirectoryName(x), Prog = Win32API.GetFileAssociation(x).Result ?? Path.GetExtension(x) }); foreach (var group in groups) { if (!group.Any()) { continue; } var files = group.Select(x => new ShellItem(x)); using var sf = files.First().Parent; IContextMenu menu = null; try { menu = sf.GetChildrenUIObjects <IContextMenu>(null, files.ToArray()); menu.QueryContextMenu(Vanara.PInvoke.HMENU.NULL, 0, 0, 0, CMF.CMF_DEFAULTONLY); var pici = new CMINVOKECOMMANDINFOEX(); pici.lpVerb = CMDSTR_OPEN; pici.nShow = Vanara.PInvoke.ShowWindowCommand.SW_SHOW; pici.cbSize = (uint)Marshal.SizeOf(pici); menu.InvokeCommand(pici); } finally { foreach (var elem in files) { elem.Dispose(); } if (menu != null) { Marshal.ReleaseComObject(menu); } } } } } catch (Win32Exception) { // Cannot open file (e.g DLL) } catch (ArgumentException) { // Cannot open file (e.g DLL) } } } }
/// <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 static string[] GetVerbs(IContextMenu cm, bool ansi = true) { IntPtr menu = IntPtr.Zero; try { menu = CreateMenu(); // It isn't clear why short.MaxValue, but 0x7FFF is very used around the .NET! int res = cm.QueryContextMenu(menu, 0, 0, short.MaxValue, 0); if (res < 0) { Marshal.ThrowExceptionForHR(res); } //var sb = new StringBuilder(128); int count = GetMenuItemCount(menu); var verbs = new List <string>(count); var handle = default(GCHandle); try { var bytes = new byte[ansi ? 128 : 256]; handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); for (int i = 0; i < count; i++) { uint id = GetMenuItemID(menu, i); if (id == uint.MaxValue) { continue; } //GetMenuString(menu, (uint)i, sb, sb.Capacity, 0x00000400 /* MF_BYPOSITION */); //string description = sb.ToString(); //sb.Clear(); res = cm.GetCommandString((UIntPtr)id, ansi ? (uint)0x00000002 /* GCS_VALIDATEA */ : 0x00000006 /* GCS_VALIDATEW */, IntPtr.Zero, ptr, bytes.Length); if (res < 0) { continue; } if (res == 0) { res = cm.GetCommandString((UIntPtr)id, ansi ? (uint)0x00000000 /* GCS_VERBA */ : 0x00000004 /* GCS_VERBW */, IntPtr.Zero, ptr, bytes.Length); if (res < 0) { Marshal.ThrowExceptionForHR(res); } verbs.Add(ansi ? Marshal.PtrToStringAnsi(ptr) : Marshal.PtrToStringUni(ptr)); } } } finally { if (handle.IsAllocated) { handle.Free(); } } return(verbs.ToArray()); } finally { if (menu != IntPtr.Zero) { DestroyMenu(menu); } } }
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; } } }
//色々サンプルを書きたいのよ 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 static void ShowContextMenuFolder(IntPtr handle, IShellFolder desktop, string parent, List <FileSystemInfo> lst, double x, double y, ref IContextMenu2 FolderContextMenu, ref IntPtr FolderContextPtr) { IntPtr PopupPtr = IntPtr.Zero; IntPtr newContextMenuPtr = IntPtr.Zero, newContextMenuPtr2 = IntPtr.Zero; IContextMenu newContextMenu = null; IntPtr PIDLParent = IntPtr.Zero; try { uint fcharcnt = 0; SFGAO fattr = SFGAO.BROWSABLE; //親フォルダのパス文字列からPIDLを取得 desktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, parent, ref fcharcnt, out PIDLParent, ref fattr); //メニューを作成 PopupPtr = User32Wrapper.CreatePopupMenu(); #region gomi //コンテキストメニューに項目追加 //不必要なのでやらない //viewSubMenu = User32Wrapper.CreatePopupMenu(); //MENUITEMINFO itemInfo = new MENUITEMINFO("View"); //itemInfo.cbSize = Shell32Wrapper.cbMenuItemInfo; //itemInfo.fMask = MIIM.SUBMENU | MIIM.STRING; //itemInfo.hSubMenu = viewSubMenu; //User32Wrapper.InsertMenuItem(PopupPtr, 0, true, ref itemInfo); //MFT rCheck = MFT.RADIOCHECK | MFT.CHECKED; //User32Wrapper.AppendMenu(viewSubMenu, // rCheck, (uint)0, "Tiles"); //User32Wrapper.AppendMenu(viewSubMenu, // rCheck, (uint)1, "Icons"); //User32Wrapper.AppendMenu(viewSubMenu, // rCheck, (uint)2, "List"); //User32Wrapper.AppendMenu(viewSubMenu, // rCheck, (uint)3, "Details"); #endregion #region New Submenu //IContextMenuを作成する if (GetNewContextMenu(PIDLParent, out newContextMenuPtr, out newContextMenu)) { //セパレータ //User32Wrapper.AppendMenu(PopupPtr, MFT.SEPARATOR, 0, string.Empty); //作成したIContextMenuをメニュー(ここではcontextMenu)に追加する newContextMenu.QueryContextMenu(PopupPtr, 0, Shell32Wrapper.CMD_FIRST, Shell32Wrapper.CMD_LAST, CMF.NORMAL); //サブメニューを取得(ここでは追加したIContextMenu? //WndProcで使用される FolderContextPtr = User32Wrapper.GetSubMenu(PopupPtr, 0); Marshal.QueryInterface(newContextMenuPtr, ref GUIDs.IID_IContextMenu2, out newContextMenuPtr2); FolderContextMenu = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(newContextMenuPtr2, typeof(IContextMenu2)); } #endregion uint selected = User32Wrapper.TrackPopupMenuEx(PopupPtr, TPM.RETURNCMD, (int)x, (int)y, handle, IntPtr.Zero); if (selected >= Shell32Wrapper.CMD_FIRST) { uint cmdidx = selected - Shell32Wrapper.CMD_FIRST; Helper.InvokeCommand(newContextMenu, cmdidx, parent, new Point(x, y)); } } #region finally finally { if (PopupPtr != IntPtr.Zero) { User32Wrapper.DestroyMenu(PopupPtr); } if (newContextMenuPtr != IntPtr.Zero) { Marshal.Release(newContextMenuPtr); newContextMenuPtr = IntPtr.Zero; } if (newContextMenuPtr2 != IntPtr.Zero) { Marshal.Release(newContextMenuPtr2); newContextMenuPtr2 = IntPtr.Zero; } if (newContextMenu != null) { Marshal.FinalReleaseComObject(newContextMenu); newContextMenu = null; } if (FolderContextMenu != null) { Marshal.FinalReleaseComObject(FolderContextMenu); FolderContextMenu = null; } } #endregion }
/// <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); }
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 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 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(); } } }