📄 browsercontextmenuwrappers.cs
字号:
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 + -