private void InvokeCommand(int index) { var invoke = new CMINVOKECOMMANDINFOEX(index) { nShow = ShowWindowCommand.SW_SHOWNORMAL }; m_ComInterface2.InvokeCommand(invoke); }
public void InvokeCommand(int index) { const int SW_SHOWNORMAL = 1; var invoke = new CMINVOKECOMMANDINFO_ByIndex { iVerb = index, nShow = SW_SHOWNORMAL }; invoke.cbSize = Marshal.SizeOf(invoke); _contextMenu2.InvokeCommand(ref invoke); }
public static int PopUpSystemContextMenu(IDLWrapper idlw, Point pntShow, ref IContextMenu2 pIContextMenu2, IntPtr hwndParent, bool fCanRemove) { IShellFolder ppv = null; int num5; try { IntPtr ptr; if((!idlw.Available || (PInvoke.SHBindToParent(idlw.PIDL, ExplorerGUIDs.IID_IShellFolder, out ppv, out ptr) != 0)) || (ppv == null)) { return -1; } IntPtr[] apidl = new IntPtr[] { ptr }; uint rgfReserved = 0; Guid riid = ExplorerGUIDs.IID_IContextMenu; object obj2 = null; ppv.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ref riid, ref rgfReserved, out obj2); if(pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } pIContextMenu2 = obj2 as IContextMenu2; if(pIContextMenu2 == null) { return -2; } ContextMenu menu = new ContextMenu(); uint uFlags = 0; if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= 0x100; } pIContextMenu2.QueryContextMenu(menu.Handle, 0, 1, 0xffff, uFlags); if(fCanRemove) { PInvoke.AppendMenu(menu.Handle, 0x800, IntPtr.Zero, null); PInvoke.AppendMenu(menu.Handle, 0, new IntPtr(0xffff), QTUtility.ResMain[0x19]); } if((idlw.HasPath && (idlw.Path.Length > 3)) && (idlw.IsFileSystemFolder || idlw.IsFileSystemFile)) { if(!fCanRemove) { PInvoke.AppendMenu(menu.Handle, 0x800, IntPtr.Zero, null); } PInvoke.AppendMenu(menu.Handle, 0, new IntPtr(0xfffe), QTUtility.ResMain[0x1a]); } uint num3 = PInvoke.TrackPopupMenu(menu.Handle, 0x100, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); int num4 = -3; switch(num3) { case 0: num4 = 0xfffd; break; case 0xffff: menu.Dispose(); return 0xffff; case 0xfffe: if(idlw.HasPath) { try { string directoryName = Path.GetDirectoryName(idlw.Path); if(Directory.Exists(directoryName)) { IntPtr currentHandle = QTUtility.instanceManager.CurrentHandle; if(PInvoke.IsWindow(currentHandle)) { QTUtility2.SendCOPYDATASTRUCT(currentHandle, (IntPtr)0x10, directoryName, IntPtr.Zero); num4 = 0xfffe; } else { Process.Start(directoryName); num4 = -4; } } } catch { SystemSounds.Asterisk.Play(); } } break; default: { CMINVOKECOMMANDINFO structure = new CMINVOKECOMMANDINFO(); structure.cbSize = Marshal.SizeOf(structure); structure.fMask = 0; structure.hwnd = hwndParent; structure.lpVerb = (IntPtr)((num3 - 1) & 0xffff); structure.lpParameters = IntPtr.Zero; structure.lpDirectory = IntPtr.Zero; structure.nShow = 1; structure.dwHotKey = 0; structure.hIcon = IntPtr.Zero; num4 = pIContextMenu2.InvokeCommand(ref structure); break; } } menu.Dispose(); num5 = num4; } catch { num5 = -1; } finally { if(ppv != null) { Marshal.ReleaseComObject(ppv); ppv = null; } } return num5; }
public static int PopUpSystemContextMenu(List<string> lstPaths, Point pntShow, ref IContextMenu2 pIContextMenu2, IntPtr hwndParent) { IShellFolder ppv = null; List<IntPtr> list = new List<IntPtr>(); try { IntPtr ptr; List<IntPtr> list2 = new List<IntPtr>(); foreach(string str in lstPaths) { IntPtr item = PInvoke.ILCreateFromPath(str); if(item != IntPtr.Zero) { list.Add(item); list2.Add(PInvoke.ILFindLastID(item)); } } if((list.Count == 0) || (PInvoke.SHBindToParent(list[0], ExplorerGUIDs.IID_IShellFolder, out ppv, out ptr) != 0)) { return -1; } IntPtr[] apidl = list2.ToArray(); uint rgfReserved = 0; Guid riid = ExplorerGUIDs.IID_IContextMenu; object obj2 = null; ppv.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ref riid, ref rgfReserved, out obj2); if(pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } pIContextMenu2 = obj2 as IContextMenu2; if(pIContextMenu2 == null) { return -1; } using(ContextMenu menu = new ContextMenu()) { uint uFlags = 0; if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= 0x100; } pIContextMenu2.QueryContextMenu(menu.Handle, 0, 1, 0xffff, uFlags); uint num3 = PInvoke.TrackPopupMenu(menu.Handle, 0x100, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); if(num3 != 0) { CMINVOKECOMMANDINFO structure = new CMINVOKECOMMANDINFO(); structure.cbSize = Marshal.SizeOf(structure); structure.fMask = 0; structure.hwnd = hwndParent; structure.lpVerb = (IntPtr)((num3 - 1) & 0xffff); structure.lpParameters = IntPtr.Zero; structure.lpDirectory = IntPtr.Zero; structure.nShow = 1; structure.dwHotKey = 0; structure.hIcon = IntPtr.Zero; pIContextMenu2.InvokeCommand(ref structure); return 0; } } } catch { } finally { if(ppv != null) { Marshal.ReleaseComObject(ppv); } foreach(IntPtr ptr3 in list) { if(ptr3 != IntPtr.Zero) { PInvoke.CoTaskMemFree(ptr3); } } } return -1; }
public static int PopUpSystemContextMenu(IDLWrapper idlw, Point pntShow, ref IContextMenu2 pIContextMenu2, IntPtr hwndParent, bool fCanRemove) { IShellFolder ppv = null; int num5; try { IntPtr ptr; if ((!idlw.Available || (PInvoke.SHBindToParent(idlw.PIDL, ExplorerGUIDs.IID_IShellFolder, out ppv, out ptr) != 0)) || (ppv == null)) { return(-1); } IntPtr[] apidl = new IntPtr[] { ptr }; uint rgfReserved = 0; Guid riid = ExplorerGUIDs.IID_IContextMenu; object obj2; ppv.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ref riid, ref rgfReserved, out obj2); if (pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } pIContextMenu2 = obj2 as IContextMenu2; if (pIContextMenu2 == null) { return(-2); } ContextMenu menu = new ContextMenu(); uint uFlags = 0; if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= 0x100; } pIContextMenu2.QueryContextMenu(menu.Handle, 0, 1, 0xffff, uFlags); if (fCanRemove) { PInvoke.AppendMenu(menu.Handle, 0x800, IntPtr.Zero, null); PInvoke.AppendMenu(menu.Handle, 0, new IntPtr(0xffff), QTUtility.ResMain[0x19]); } if ((idlw.HasPath && (idlw.Path.Length > 3)) && (idlw.IsFileSystemFolder || idlw.IsFileSystemFile)) { if (!fCanRemove) { PInvoke.AppendMenu(menu.Handle, 0x800, IntPtr.Zero, null); } PInvoke.AppendMenu(menu.Handle, 0, new IntPtr(0xfffe), QTUtility.ResMain[0x1a]); } uint num3 = PInvoke.TrackPopupMenu(menu.Handle, 0x100, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); int num4 = -3; switch (num3) { case 0: num4 = 0xfffd; break; case 0xffff: menu.Dispose(); return(0xffff); case 0xfffe: if (idlw.HasPath) { try { string directoryName = Path.GetDirectoryName(idlw.Path); if (Directory.Exists(directoryName)) { IntPtr currentHandle = QTUtility.instanceManager.CurrentHandle; if (PInvoke.IsWindow(currentHandle)) { QTUtility2.SendCOPYDATASTRUCT(currentHandle, (IntPtr)0x10, directoryName, IntPtr.Zero); num4 = 0xfffe; } else { Process.Start(directoryName); num4 = -4; } } } catch { SystemSounds.Asterisk.Play(); } } break; default: { CMINVOKECOMMANDINFO structure = new CMINVOKECOMMANDINFO(); structure.cbSize = Marshal.SizeOf(structure); structure.fMask = 0; structure.hwnd = hwndParent; structure.lpVerb = (IntPtr)((num3 - 1) & 0xffff); structure.lpParameters = IntPtr.Zero; structure.lpDirectory = IntPtr.Zero; structure.nShow = 1; structure.dwHotKey = 0; structure.hIcon = IntPtr.Zero; num4 = pIContextMenu2.InvokeCommand(ref structure); break; } } menu.Dispose(); num5 = num4; } catch { num5 = -1; } finally { if (ppv != null) { Marshal.ReleaseComObject(ppv); } } return(num5); }
public static int PopUpSystemContextMenu(List <string> lstPaths, Point pntShow, ref IContextMenu2 pIContextMenu2, IntPtr hwndParent) { IShellFolder ppv = null; List <IntPtr> list = new List <IntPtr>(); try { IntPtr ptr; List <IntPtr> list2 = new List <IntPtr>(); foreach (IntPtr item in lstPaths.Select(PInvoke.ILCreateFromPath).Where(item => item != IntPtr.Zero)) { list.Add(item); list2.Add(PInvoke.ILFindLastID(item)); } if ((list.Count == 0) || (PInvoke.SHBindToParent(list[0], ExplorerGUIDs.IID_IShellFolder, out ppv, out ptr) != 0)) { return(-1); } IntPtr[] apidl = list2.ToArray(); uint rgfReserved = 0; Guid riid = ExplorerGUIDs.IID_IContextMenu; object obj2; ppv.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ref riid, ref rgfReserved, out obj2); if (pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } pIContextMenu2 = obj2 as IContextMenu2; if (pIContextMenu2 == null) { return(-1); } using (ContextMenu menu = new ContextMenu()) { uint uFlags = 0; if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= 0x100; } pIContextMenu2.QueryContextMenu(menu.Handle, 0, 1, 0xffff, uFlags); uint num3 = PInvoke.TrackPopupMenu(menu.Handle, 0x100, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); if (num3 != 0) { CMINVOKECOMMANDINFO structure = new CMINVOKECOMMANDINFO(); structure.cbSize = Marshal.SizeOf(structure); structure.fMask = 0; structure.hwnd = hwndParent; structure.lpVerb = (IntPtr)((num3 - 1) & 0xffff); structure.lpParameters = IntPtr.Zero; structure.lpDirectory = IntPtr.Zero; structure.nShow = 1; structure.dwHotKey = 0; structure.hIcon = IntPtr.Zero; pIContextMenu2.InvokeCommand(ref structure); return(0); } } } catch { } finally { if (ppv != null) { Marshal.ReleaseComObject(ppv); } foreach (IntPtr ptr3 in list) { if (ptr3 != IntPtr.Zero) { PInvoke.CoTaskMemFree(ptr3); } } } return(-1); }
/// <summary> /// Displays shell shortcut menu. /// </summary> /// <param name="idlw">IDLWrapper object that specifies shell item</param> /// <param name="pntShow">location of the shortcut menu, in screen coordinates.</param> /// <param name="hwndParent">Handle of parent control. Parent control will get focus, and receives the messages about drawing 'Send to' submenues.</param> /// <param name="fCanRemove">set true to add 'remove this' menu item.</param> /// <returns> /// 0xFFFF user selected "Remove this item from menu". /// 0xFFFE user selected "Open containing folder". /// 0xFFFD If the user cancels the menu without making a selection, or if an error occurs /// </returns> public int Open(IDLWrapper idlw, Point pntShow, IntPtr hwndParent, bool fCanRemove) { const uint MF_STRING = 0x00000000; const uint MF_SEPARATOR = 0x00000800; const uint CMF_NORMAL = 0x00000000; const uint CMF_EXTENDEDVERBS = 0x00000100; const uint TPM_RETURNCMD = 0x0100; const uint S_OK = 0; const int COMMANDID_REMOVEITEM = 0xffff; // todo: move to const class const int COMMANDID_OPENPARENT = 0xfffe; const int COMMANDID_USERCANCEL = 0xfffd; IShellFolder shellFolderParent = null; try { // get IShellFolder IntPtr pIDLRelative; if(idlw.Available && S_OK == PInvoke.SHBindToParent(idlw.PIDL, ExplorerGUIDs.IID_IShellFolder, out shellFolderParent, out pIDLRelative) && shellFolderParent != null) { // get IContextMenu2 IntPtr[] pIDLs = new IntPtr[] { pIDLRelative }; uint reserved = 0; object oUnk; if(S_OK == shellFolderParent.GetUIObjectOf(IntPtr.Zero, (uint)pIDLs.Length, pIDLs, ExplorerGUIDs.IID_IContextMenu, ref reserved, out oUnk)) { pIContextMenu2 = oUnk as IContextMenu2; if(pIContextMenu2 != null) { using(ContextMenu contextMenu = new ContextMenu()) { int nResult = -1; uint uFlags = CMF_NORMAL; if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= CMF_EXTENDEDVERBS; } pIContextMenu2.QueryContextMenu(contextMenu.Handle, 0, 1, 0xffff, uFlags); // append optional menus if(fCanRemove) { // "Remove this item from menu" PInvoke.AppendMenu(contextMenu.Handle, MF_SEPARATOR, IntPtr.Zero, null); PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_REMOVEITEM), QTUtility.ResMain[25]); } if(idlw.HasPath && idlw.Path.Length > 3 && idlw.IsFileSystem /*&& ( idlw.IsFileSystemFolder || idlw.IsFileSystemFile )*/ ) { // "Open containing folder" if(!fCanRemove) { // separator PInvoke.AppendMenu(contextMenu.Handle, MF_SEPARATOR, IntPtr.Zero, null); } PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_OPENPARENT), QTUtility.ResMain[26]); } uint commandID = PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); if(commandID != 0) { if(commandID == COMMANDID_REMOVEITEM) { return COMMANDID_REMOVEITEM; } else if(commandID == COMMANDID_OPENPARENT) { if(idlw.HasPath) { try { QTTabBarClass tabbar = InstanceManager.GetThreadTabBar(); if(tabbar != null) { using(IDLWrapper idlwParent = idlw.GetParent()) { if(idlwParent.Available) { tabbar.OpenNewTabOrWindow(idlwParent); } } } // DesktopTool will handle it by itself nResult = COMMANDID_OPENPARENT; } catch { System.Media.SystemSounds.Asterisk.Play(); } } } else { CMINVOKECOMMANDINFO cmInfo = new CMINVOKECOMMANDINFO { cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)), fMask = 0, hwnd = hwndParent, lpVerb = (IntPtr)((commandID - 1) & 0xFFFF), lpParameters = IntPtr.Zero, lpDirectory = IntPtr.Zero, nShow = 1, //SW_SHOWNORMAL; dwHotKey = 0, hIcon = IntPtr.Zero }; // returns S_OK if successful, or an error value otherwise. // E_ABORT when user clicked "Open folder link target exists" of link file...( E_ABORT _HRESULT_TYPEDEF_(0x80004004L) ) nResult = pIContextMenu2.InvokeCommand(ref cmInfo); } } else { // 'if the user cancels the menu without making a selection, or if an error occurs' (MSDN) nResult = COMMANDID_USERCANCEL; } return nResult; } } } } // if failed to create shell context menu, show 'remove this' menu instead if(fCanRemove) { using(ContextMenu contextMenu = new ContextMenu()) { PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_REMOVEITEM), QTUtility.ResMain[25]); if(COMMANDID_REMOVEITEM == PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero)) { return COMMANDID_REMOVEITEM; } } } return COMMANDID_USERCANCEL; } catch { } finally { if(shellFolderParent != null) { Marshal.ReleaseComObject(shellFolderParent); } if(pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } } return -1; }
/// <summary> /// Displays shell shortcut menu for multiple items. Paths must be sub items of one directory. /// </summary> /// <param name="lstIDLs"></param> /// <param name="pntShow"></param> /// <param name="hwndParent"></param> /// <returns></returns> public int Open(List<byte[]> lstIDLs, Point pntShow, IntPtr hwndParent) { // All lstIDLs members must share the same parent, for compatibility. const uint S_OK = 0; if(lstIDLs == null || lstIDLs.Count == 0) return -1; IShellFolder shellFolder = null; List<IntPtr> lstRltvPIDLs = new List<IntPtr>(); IntPtr pIDLFirst = IntPtr.Zero; try { // build array of relative idls for(int i = 0; i < lstIDLs.Count; i++) { if(i == 0) { pIDLFirst = ShellMethods.CreateIDL(lstIDLs[0]); } using(IDLWrapper idlw = new IDLWrapper(lstIDLs[i])) { if(!idlw.Available) continue; IntPtr p = PInvoke.ILClone(PInvoke.ILFindLastID(idlw.PIDL)); if(p != IntPtr.Zero) { lstRltvPIDLs.Add(p); } } } IntPtr[] apidl = lstRltvPIDLs.ToArray(); if(apidl.Length > 0) { IntPtr pIDLRltv1st; if(S_OK == PInvoke.SHBindToParent(pIDLFirst, ExplorerGUIDs.IID_IShellFolder, out shellFolder, out pIDLRltv1st)) { // get IContextMenu2 uint rsv = 0; object oUnk; if(S_OK == shellFolder.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ExplorerGUIDs.IID_IContextMenu, ref rsv, out oUnk)) { pIContextMenu2 = oUnk as IContextMenu2; if(pIContextMenu2 != null) { using(ContextMenu contextMenu = new ContextMenu()) { const uint CMF_EXTENDEDVERBS = 0x00000100; const uint TPM_RETURNCMD = 0x0100; uint uFlags = 0; if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) uFlags |= CMF_EXTENDEDVERBS; pIContextMenu2.QueryContextMenu(contextMenu.Handle, 0, 1, 0xffff, uFlags); uint commandID = PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); if(commandID != 0) { CMINVOKECOMMANDINFO cmInfo = new CMINVOKECOMMANDINFO { cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)), fMask = 0, hwnd = hwndParent, lpVerb = (IntPtr)((commandID - 1) & 0xFFFF), lpParameters = IntPtr.Zero, lpDirectory = IntPtr.Zero, nShow = 1, //SW_SHOWNORMAL dwHotKey = 0, hIcon = IntPtr.Zero }; // this returns E_ABORT when user clicked "Open folder link target exists" of link file... pIContextMenu2.InvokeCommand(ref cmInfo); return 0; } } } } } } } catch { } finally { if(shellFolder != null) { Marshal.ReleaseComObject(shellFolder); } if(pIDLFirst != IntPtr.Zero) { PInvoke.CoTaskMemFree(pIDLFirst); } foreach(IntPtr pIDL in lstRltvPIDLs.Where(pIDL => pIDL != IntPtr.Zero)) { PInvoke.CoTaskMemFree(pIDL); } if(pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } } return -1; }
/// <summary> /// Displays shell shortcut menu. /// </summary> /// <param name="idlw">IDLWrapper object that specifies shell item</param> /// <param name="pntShow">location of the shortcut menu, in screen coordinates.</param> /// <param name="hwndParent">Handle of parent control. Parent control will get focus, and receives the messages about drawing 'Send to' submenues.</param> /// <param name="fCanRemove">set true to add 'remove this' menu item.</param> /// <returns> /// 0xFFFF user selected "Remove this item from menu". /// 0xFFFE user selected "Open containing folder". /// 0xFFFD If the user cancels the menu without making a selection, or if an error occurs /// </returns> public int Open(IDLWrapper idlw, Point pntShow, IntPtr hwndParent, bool fCanRemove) { const uint MF_STRING = 0x00000000; const uint MF_SEPARATOR = 0x00000800; const uint CMF_NORMAL = 0x00000000; const uint CMF_EXTENDEDVERBS = 0x00000100; const uint TPM_RETURNCMD = 0x0100; const uint S_OK = 0; const int COMMANDID_REMOVEITEM = 0xffff; // todo: move to const class const int COMMANDID_OPENPARENT = 0xfffe; const int COMMANDID_USERCANCEL = 0xfffd; IShellFolder shellFolderParent = null; try { // get IShellFolder IntPtr pIDLRelative; if (idlw.Available && S_OK == PInvoke.SHBindToParent(idlw.PIDL, ExplorerGUIDs.IID_IShellFolder, out shellFolderParent, out pIDLRelative) && shellFolderParent != null) { // get IContextMenu2 IntPtr[] pIDLs = new IntPtr[] { pIDLRelative }; uint reserved = 0; object oUnk; if (S_OK == shellFolderParent.GetUIObjectOf(IntPtr.Zero, (uint)pIDLs.Length, pIDLs, ExplorerGUIDs.IID_IContextMenu, ref reserved, out oUnk)) { pIContextMenu2 = oUnk as IContextMenu2; if (pIContextMenu2 != null) { using (ContextMenu contextMenu = new ContextMenu()) { int nResult = -1; uint uFlags = CMF_NORMAL; if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= CMF_EXTENDEDVERBS; } pIContextMenu2.QueryContextMenu(contextMenu.Handle, 0, 1, 0xffff, uFlags); // append optional menus if (fCanRemove) { // "Remove this item from menu" PInvoke.AppendMenu(contextMenu.Handle, MF_SEPARATOR, IntPtr.Zero, null); PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_REMOVEITEM), QTUtility.ResMain[25]); } if (idlw.HasPath && idlw.Path.Length > 3 && idlw.IsFileSystem /*&& ( idlw.IsFileSystemFolder || idlw.IsFileSystemFile )*/) { // "Open containing folder" if (!fCanRemove) { // separator PInvoke.AppendMenu(contextMenu.Handle, MF_SEPARATOR, IntPtr.Zero, null); } PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_OPENPARENT), QTUtility.ResMain[26]); } uint commandID = PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); if (commandID != 0) { if (commandID == COMMANDID_REMOVEITEM) { return(COMMANDID_REMOVEITEM); } else if (commandID == COMMANDID_OPENPARENT) { if (idlw.HasPath) { try { QTTabBarClass tabbar = InstanceManager.GetThreadTabBar(); if (tabbar != null) { using (IDLWrapper idlwParent = idlw.GetParent()) { if (idlwParent.Available) { tabbar.OpenNewTabOrWindow(idlwParent); } } } // DesktopTool will handle it by itself nResult = COMMANDID_OPENPARENT; } catch { System.Media.SystemSounds.Asterisk.Play(); } } } else { CMINVOKECOMMANDINFO cmInfo = new CMINVOKECOMMANDINFO { cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)), fMask = 0, hwnd = hwndParent, lpVerb = (IntPtr)((commandID - 1) & 0xFFFF), lpParameters = IntPtr.Zero, lpDirectory = IntPtr.Zero, nShow = 1, //SW_SHOWNORMAL; dwHotKey = 0, hIcon = IntPtr.Zero }; // returns S_OK if successful, or an error value otherwise. // E_ABORT when user clicked "Open folder link target exists" of link file...( E_ABORT _HRESULT_TYPEDEF_(0x80004004L) ) nResult = pIContextMenu2.InvokeCommand(ref cmInfo); } } else { // 'if the user cancels the menu without making a selection, or if an error occurs' (MSDN) nResult = COMMANDID_USERCANCEL; } return(nResult); } } } } // if failed to create shell context menu, show 'remove this' menu instead if (fCanRemove) { using (ContextMenu contextMenu = new ContextMenu()) { PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_REMOVEITEM), QTUtility.ResMain[25]); if (COMMANDID_REMOVEITEM == PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero)) { return(COMMANDID_REMOVEITEM); } } } return(COMMANDID_USERCANCEL); } catch { } finally { if (shellFolderParent != null) { Marshal.ReleaseComObject(shellFolderParent); } if (pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } } return(-1); }
/// <summary> /// Displays shell shortcut menu for multiple items. Paths must be sub items of one directory. /// </summary> /// <param name="lstIDLs"></param> /// <param name="pntShow"></param> /// <param name="hwndParent"></param> /// <returns></returns> public int Open(List <byte[]> lstIDLs, Point pntShow, IntPtr hwndParent) { // All lstIDLs members must share the same parent, for compatibility. const uint S_OK = 0; if (lstIDLs == null || lstIDLs.Count == 0) { return(-1); } IShellFolder shellFolder = null; List <IntPtr> lstRltvPIDLs = new List <IntPtr>(); IntPtr pIDLFirst = IntPtr.Zero; try { // build array of relative idls for (int i = 0; i < lstIDLs.Count; i++) { if (i == 0) { pIDLFirst = ShellMethods.CreateIDL(lstIDLs[0]); } using (IDLWrapper idlw = new IDLWrapper(lstIDLs[i])) { if (!idlw.Available) { continue; } IntPtr p = PInvoke.ILClone(PInvoke.ILFindLastID(idlw.PIDL)); if (p != IntPtr.Zero) { lstRltvPIDLs.Add(p); } } } IntPtr[] apidl = lstRltvPIDLs.ToArray(); if (apidl.Length > 0) { IntPtr pIDLRltv1st; if (S_OK == PInvoke.SHBindToParent(pIDLFirst, ExplorerGUIDs.IID_IShellFolder, out shellFolder, out pIDLRltv1st)) { // get IContextMenu2 uint rsv = 0; object oUnk; if (S_OK == shellFolder.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ExplorerGUIDs.IID_IContextMenu, ref rsv, out oUnk)) { pIContextMenu2 = oUnk as IContextMenu2; if (pIContextMenu2 != null) { using (ContextMenu contextMenu = new ContextMenu()) { const uint CMF_EXTENDEDVERBS = 0x00000100; const uint TPM_RETURNCMD = 0x0100; uint uFlags = 0; if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { uFlags |= CMF_EXTENDEDVERBS; } pIContextMenu2.QueryContextMenu(contextMenu.Handle, 0, 1, 0xffff, uFlags); uint commandID = PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero); if (commandID != 0) { CMINVOKECOMMANDINFO cmInfo = new CMINVOKECOMMANDINFO { cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)), fMask = 0, hwnd = hwndParent, lpVerb = (IntPtr)((commandID - 1) & 0xFFFF), lpParameters = IntPtr.Zero, lpDirectory = IntPtr.Zero, nShow = 1, //SW_SHOWNORMAL dwHotKey = 0, hIcon = IntPtr.Zero }; // this returns E_ABORT when user clicked "Open folder link target exists" of link file... pIContextMenu2.InvokeCommand(ref cmInfo); return(0); } } } } } } } catch { } finally { if (shellFolder != null) { Marshal.ReleaseComObject(shellFolder); } if (pIDLFirst != IntPtr.Zero) { PInvoke.CoTaskMemFree(pIDLFirst); } foreach (IntPtr pIDL in lstRltvPIDLs.Where(pIDL => pIDL != IntPtr.Zero)) { PInvoke.CoTaskMemFree(pIDL); } if (pIContextMenu2 != null) { Marshal.ReleaseComObject(pIContextMenu2); pIContextMenu2 = null; } } return(-1); }