示例#1
0
        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();
            }
        }
示例#2
0
        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);
     }
 }
示例#4
0
        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();
            }
        }
示例#5
0
        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}");
                        }
                    }
                }
            }
        }
示例#7
0
        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));
            }
        }
示例#8
0
文件: Helper.cs 项目: turky-9/yu
        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
        }
示例#9
0
        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;
        }
示例#11
0
        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);
                }
            }
        }
示例#12
0
        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;
                }
            }
        }
示例#13
0
        //色々サンプルを書きたいのよ
        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);
            }
        }
示例#14
0
文件: Helper.cs 项目: turky-9/yu
        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
        }
示例#15
0
        /// <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);
        }
示例#17
0
        /// <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);
        }
示例#18
0
        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();
                }
            }
        }