⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browsercontextmenuwrappers.cs

📁 C#界面编程
💻 CS
📖 第 1 页 / 共 5 页
字号:
                        IntPtr[] pidls = new IntPtr[br.FileView.SelectedOrder.Count - startIndex];
                        for (int i = startIndex; i < pidls.Length; i++)
                        {
                            pidls[i - startIndex] = ((ShellItem)((ListViewItem)br.FileView.SelectedOrder[i]).Tag).PIDLRel.Ptr;
                        }

                        IntPtr icontextMenuPtr = IntPtr.Zero, context2Ptr = IntPtr.Zero, context3Ptr = IntPtr.Zero;
                        ContextMenu contextMenu = new ContextMenu();
                        ShellItem parentShellItem = (ShellItem)parent.Tag;
                        IShellFolder parentShellFolder = parentShellItem.ShellFolder;

                        #endregion

                        #region Show / Invoke

                        try
                        {
                            if (ContextMenuHelper.GetIContextMenu(parentShellFolder, pidls, out icontextMenuPtr, out iContextMenu))
                            {
                                iContextMenu.QueryContextMenu(
                                    contextMenu.Handle,
                                    0,
                                    ShellAPI.CMD_FIRST,
                                    ShellAPI.CMD_LAST,
                                    ShellAPI.CMF.DEFAULTONLY);

                                int defaultCommand = ShellAPI.GetMenuDefaultItem(contextMenu.Handle, false, 0);
                                if (defaultCommand >= ShellAPI.CMD_FIRST)
                                {
                                    ContextMenuHelper.InvokeCommand(
                                        iContextMenu,
                                        (uint)defaultCommand - ShellAPI.CMD_FIRST,
                                        ShellItem.GetRealPath(parentShellItem),
                                        Control.MousePosition);
                                }
                            }
                        }
                        #endregion
                        catch (Exception) { }
                        #region Finally
                        finally
                        {
                            if (iContextMenu != null)
                            {
                                Marshal.ReleaseComObject(iContextMenu);
                                iContextMenu = null;
                            }

                            if (contextMenu.Handle != null)
                                Marshal.FreeCoTaskMem(contextMenu.Handle);

                            Marshal.Release(icontextMenuPtr);
                        }
                        #endregion
                    }
                }
                else
                {
                    IntPtr[] pidls = new IntPtr[br.FileView.SelectedOrder.Count - startIndex];
                    for (int i = startIndex; i < pidls.Length; i++)
                    {
                        pidls[i - startIndex] = ((ShellItem)((ListViewItem)br.FileView.SelectedOrder[i]).Tag).PIDLRel.Ptr;
                    }

                    ContextMenuHelper.InvokeCommand(shellItem.ParentItem, pidls, "properties", Control.MousePosition);
                }
            }
        }

        /// <summary>
        /// When the mouse goes up on an item and suspendContextMenu is true, this method will show the
        /// ContextMenu for that item and after the user selects an item, it will execute that command.
        /// </summary>
        void FileView_MouseUp(object sender, MouseEventArgs e)
        {
            if (suspendContextMenu || contextMenuVisible)
            {
                suspendContextMenu = false;
                return;
            }

            ListViewHitTestInfo hitTest = br.FileView.HitTest(e.Location);
            Point ptInvoke = br.FileView.PointToScreen(e.Location);

            contextMenuVisible = true;
            if (e.Button == MouseButtons.Right &&
                hitTest.Item != null && 
                (br.FileView.View != View.Details || (hitTest.SubItem != null && hitTest.Item.Name == hitTest.SubItem.Name)) &&
                (hitTest.Location == ListViewHitTestLocations.Image ||
                hitTest.Location == ListViewHitTestLocations.Label ||
                hitTest.Location == ListViewHitTestLocations.StateImage))
            {
                CreateNormalMenu(ptInvoke, hitTest, e);
            }
            else if (e.Button == MouseButtons.Right)
            {
                CreateFolderMenu(ptInvoke, e);
            }
            contextMenuVisible = false;
        }

        private void CreateNormalMenu(Point ptInvoke, ListViewHitTestInfo hitTest, MouseEventArgs e)
        {
            hitTest.Item.Selected = true;

            #region Fields

            ShellItem item = (ShellItem)hitTest.Item.Tag;

            int offset = br.FileView.SelectedOrder.Contains(hitTest.Item) ? 0 : 1;
            IntPtr[] pidls = new IntPtr[br.FileView.SelectedOrder.Count + offset];

            if (offset == 1)
                pidls[0] = item.PIDLRel.Ptr;

            for (int i = offset; i < pidls.Length; i++)
            {
                pidls[i] = ((ShellItem)((ListViewItem)br.FileView.SelectedOrder[i - offset]).Tag).PIDLRel.Ptr;
            }

            
            IntPtr contextMenu = IntPtr.Zero,
                iContextMenuPtr = IntPtr.Zero,
                iContextMenuPtr2 = IntPtr.Zero,
                iContextMenuPtr3 = IntPtr.Zero;
            IShellFolder parentShellFolder =
                (item.ParentItem != null) ? item.ParentItem.ShellFolder : item.ShellFolder;

            #endregion

            #region Show / Invoke

            try
            {
                if (ContextMenuHelper.GetIContextMenu(parentShellFolder, pidls, out iContextMenuPtr, out iContextMenu))
                {
                    contextMenu = ShellAPI.CreatePopupMenu();
                    iContextMenu.QueryContextMenu(
                        contextMenu,
                        0,
                        ShellAPI.CMD_FIRST,
                        ShellAPI.CMD_LAST,
                        ShellAPI.CMF.EXPLORE |
                        ShellAPI.CMF.CANRENAME |
                        ((Control.ModifierKeys & Keys.Shift) != 0 ? ShellAPI.CMF.EXTENDEDVERBS : 0));

                    Marshal.QueryInterface(iContextMenuPtr, ref ShellAPI.IID_IContextMenu2, out iContextMenuPtr2);
                    Marshal.QueryInterface(iContextMenuPtr, ref ShellAPI.IID_IContextMenu3, out iContextMenuPtr3);

                    try
                    {
                        iContextMenu2 =
                            (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2));

                        iContextMenu3 =
                            (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3));
                    }
                    catch (Exception) { }

                    uint selected = ShellAPI.TrackPopupMenuEx(
                                        contextMenu,
                                        ShellAPI.TPM.RETURNCMD,
                                        ptInvoke.X,
                                        ptInvoke.Y,
                                        this.Handle,
                                        IntPtr.Zero);

                    br.OnContextMenuMouseHover(new ContextMenuMouseHoverEventArgs(string.Empty));

                    if (selected >= ShellAPI.CMD_FIRST)
                    {
                        string command = ContextMenuHelper.GetCommandString(iContextMenu, selected - ShellAPI.CMD_FIRST, true);

                        if (command == "Explore" && br.FolderView.SelectedNode != null)
                        {
                            if (!br.FolderView.SelectedNode.IsExpanded)
                                br.FolderView.SelectedNode.Expand();

                            br.FolderView.SelectedNode = br.FolderView.SelectedNode.Nodes[hitTest.Item.Text];
                        }
                        else if (command == "rename")
                        {
                            hitTest.Item.BeginEdit();
                        }
                        else
                        {
                            ContextMenuHelper.InvokeCommand(
                                iContextMenu,
                                selected - ShellAPI.CMD_FIRST,
                                ShellItem.GetRealPath(br.SelectedItem),
                                ptInvoke);
                        }
                    }
                }
            }
            #endregion
            catch (Exception) { }
            #region Finally
            finally
            {
                if (iContextMenu != null)
                {
                    Marshal.ReleaseComObject(iContextMenu);
                    iContextMenu = null;
                }

                if (iContextMenu2 != null)
                {
                    Marshal.ReleaseComObject(iContextMenu2);
                    iContextMenu2 = null;
                }

                if (iContextMenu3 != null)
                {
                    Marshal.ReleaseComObject(iContextMenu3);
                    iContextMenu3 = null;
                }

                if (contextMenu != null)
                    ShellAPI.DestroyMenu(contextMenu);

                if (iContextMenuPtr != IntPtr.Zero)
                    Marshal.Release(iContextMenuPtr);

                if (iContextMenuPtr2 != IntPtr.Zero)
                    Marshal.Release(iContextMenuPtr2);

                if (iContextMenuPtr3 != IntPtr.Zero)
                    Marshal.Release(iContextMenuPtr3);
            }
            #endregion
        }

        private void CreateFolderMenu(Point ptInvoke, MouseEventArgs e)
        {
            #region Fields

            ShellItem currentItem = br.SelectedItem;

            foreach (ListViewItem item in br.FileView.SelectedItems)
                item.Selected = false;

            IntPtr contextMenu = IntPtr.Zero, viewSubMenu = IntPtr.Zero;
            IntPtr newContextMenuPtr = IntPtr.Zero, newContextMenuPtr2 = IntPtr.Zero, newContextMenuPtr3 = IntPtr.Zero;
            newSubmenuPtr = IntPtr.Zero;

            #endregion

            try
            {
                #region Make Menu

                contextMenu = ShellAPI.CreatePopupMenu();
                viewSubMenu = ShellAPI.CreatePopupMenu();

                #region View Submenu

                ShellAPI.MENUITEMINFO itemInfo = new ShellAPI.MENUITEMINFO("View");
                itemInfo.cbSize = ShellAPI.cbMenuItemInfo;
                itemInfo.fMask = ShellAPI.MIIM.SUBMENU | ShellAPI.MIIM.STRING;
                itemInfo.hSubMenu = viewSubMenu;
                ShellAPI.InsertMenuItem(contextMenu, 0, true, ref itemInfo);

                ShellAPI.MFT rCheck = ShellAPI.MFT.RADIOCHECK | ShellAPI.MFT.CHECKED;
                ShellAPI.AppendMenu(viewSubMenu, 
                    (br.CurrentViewPlugin == null && br.FileView.View == View.Tile ? rCheck : 0), (uint)CMD_CUSTOM.Tiles, "Tiles");
                ShellAPI.AppendMenu(viewSubMenu,
                    (br.CurrentViewPlugin == null && br.FileView.View == View.LargeIcon ? rCheck : 0), (uint)CMD_CUSTOM.Icons, "Icons");
                ShellAPI.AppendMenu(viewSubMenu,
                    (br.CurrentViewPlugin == null && br.FileView.View == View.List ? rCheck : 0), (uint)CMD_CUSTOM.List, "List");
                ShellAPI.AppendMenu(viewSubMenu,
                    (br.CurrentViewPlugin == null && br.FileView.View == View.Details ? rCheck : 0), (uint)CMD_CUSTOM.Details, "Details");

                for (int i = 0; i < pluginWrapper.ViewPlugins.Count; i++)
                {
                    ShellAPI.AppendMenu(viewSubMenu,
                        (IViewPlugin.Equals(br.CurrentViewPlugin, pluginWrapper.ViewPlugins[i]) ? rCheck : 0), 
                            (uint)CMD_CUSTOM.SpecialView + (uint)i, ((IViewPlugin)pluginWrapper.ViewPlugins[i]).ViewName);
                }

                #endregion

                #region Paste Menu

                DragDropEffects effects = ShellHelper.CanDropClipboard(currentItem);
                bool canPaste = (effects & DragDropEffects.Copy) != 0 || (effects & DragDropEffects.Move) != 0;
                bool canPasteShortCut = (effects & DragDropEffects.Link) != 0;

                ShellAPI.AppendMenu(contextMenu, ShellAPI.MFT.SEPARATOR, 0, string.Empty);
                ShellAPI.AppendMenu(contextMenu, canPaste ? 0 : ShellAPI.MFT.GRAYED, (int)CMD_CUSTOM.Paste, "Paste");
                ShellAPI.AppendMenu(contextMenu, canPasteShortCut ? 0 : ShellAPI.MFT.GRAYED, (int)CMD_CUSTOM.Paste_ShortCut, "Paste Shortcut");

                #endregion

                #region New Submenu

                if (br.SelectedItem.IsFileSystem &&
                    ContextMenuHelper.GetNewContextMenu(br.SelectedItem, out newContextMenuPtr, out newContextMenu))
                {
                    ShellAPI.AppendMenu(contextMenu, ShellAPI.MFT.SEPARATOR, 0, string.Empty);
                    newContextMenu.QueryContextMenu(
                        contextMenu,
                        5,
                        ShellAPI.CMD_FIRST,
                        ShellAPI.CMD_LAST,
                        ShellAPI.CMF.NORMAL);

                    newSubmenuPtr = ShellAPI.GetSubMenu(contextMenu, 5);

                    Marshal.QueryInterface(newContextMenuPtr, ref ShellAPI.IID_IContextMenu2, out newContextMenuPtr2);
                    Marshal.QueryInterface(newContextMenuPtr, ref ShellAPI.IID_IContextMenu3, out newContextMenuPtr3);

                    try
                    {
                        newContextMenu2 =
                            (IContextMenu2)Marshal.GetTypedObjectForIUnknown(newContextMenuPtr2, typeof(IContextMenu2));

                        newContextMenu3 =
                            (IContextMenu3)Marshal.GetTypedObjectForIUnknown(newContextMenuPtr3, typeof(IContextMenu3));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -