📄 browsercontextmenuwrappers.cs
字号:
/// <param name="executeString">indicating whether it should return an execute string or not</param>
/// <returns>if executeString is true it will return the executeString for the item,
/// otherwise it will return the help info string</returns>
public static string GetCommandStringW(IContextMenu iContextMenu, uint idcmd, bool executeString)
{
string info = string.Empty;
byte[] bytes = new byte[256];
int index;
iContextMenu.GetCommandString(
idcmd,
(executeString ? ShellAPI.GCS.VERBW : ShellAPI.GCS.HELPTEXTW),
0,
bytes,
ShellAPI.MAX_PATH);
index = 0;
while (index < bytes.Length - 1 && (bytes[index] != 0 || bytes[index + 1] != 0))
{ index += 2; }
if (index < bytes.Length - 1)
info = Encoding.Unicode.GetString(bytes, 0, index + 1);
return info;
}
#endregion
#region Invoke Commands
/// <summary>
/// Invokes a specific command from an IContextMenu
/// </summary>
/// <param name="iContextMenu">the IContextMenu containing the item</param>
/// <param name="cmd">the index of the command to invoke</param>
/// <param name="parentDir">the parent directory from where to invoke</param>
/// <param name="ptInvoke">the point (in screen co鰎dinates) from which to invoke</param>
public static void InvokeCommand(IContextMenu iContextMenu, uint cmd, string parentDir, Point ptInvoke)
{
ShellAPI.CMINVOKECOMMANDINFOEX invoke = new ShellAPI.CMINVOKECOMMANDINFOEX();
invoke.cbSize = ShellAPI.cbInvokeCommand;
invoke.lpVerb = (IntPtr)cmd;
invoke.lpDirectory = parentDir;
invoke.lpVerbW = (IntPtr)cmd;
invoke.lpDirectoryW = parentDir;
invoke.fMask = ShellAPI.CMIC.UNICODE | ShellAPI.CMIC.PTINVOKE |
((Control.ModifierKeys & Keys.Control) != 0 ? ShellAPI.CMIC.CONTROL_DOWN : 0) |
((Control.ModifierKeys & Keys.Shift) != 0 ? ShellAPI.CMIC.SHIFT_DOWN : 0);
invoke.ptInvoke = new ShellAPI.POINT(ptInvoke.X, ptInvoke.Y);
invoke.nShow = ShellAPI.SW.SHOWNORMAL;
iContextMenu.InvokeCommand(ref invoke);
}
/// <summary>
/// Invokes a specific command from an IContextMenu
/// </summary>
/// <param name="iContextMenu">the IContextMenu containing the item</param>
/// <param name="cmdA">the Ansi execute string to invoke</param>
/// <param name="cmdW">the Unicode execute string to invoke</param>
/// <param name="parentDir">the parent directory from where to invoke</param>
/// <param name="ptInvoke">the point (in screen co鰎dinates) from which to invoke</param>
public static void InvokeCommand(IContextMenu iContextMenu, string cmd, string parentDir, Point ptInvoke)
{
ShellAPI.CMINVOKECOMMANDINFOEX invoke = new ShellAPI.CMINVOKECOMMANDINFOEX();
invoke.cbSize = ShellAPI.cbInvokeCommand;
invoke.lpVerb = Marshal.StringToHGlobalAnsi(cmd);
invoke.lpDirectory = parentDir;
invoke.lpVerbW = Marshal.StringToHGlobalUni(cmd);
invoke.lpDirectoryW = parentDir;
invoke.fMask = ShellAPI.CMIC.UNICODE | ShellAPI.CMIC.PTINVOKE |
((Control.ModifierKeys & Keys.Control) != 0 ? ShellAPI.CMIC.CONTROL_DOWN : 0) |
((Control.ModifierKeys & Keys.Shift) != 0 ? ShellAPI.CMIC.SHIFT_DOWN : 0);
invoke.ptInvoke = new ShellAPI.POINT(ptInvoke.X, ptInvoke.Y);
invoke.nShow = ShellAPI.SW.SHOWNORMAL;
iContextMenu.InvokeCommand(ref invoke);
}
/// <summary>
/// Invokes a specific command for a set of pidls
/// </summary>
/// <param name="parent">the parent ShellItem which contains the pidls</param>
/// <param name="pidls">the pidls from the items for which to invoke</param>
/// <param name="cmd">the execute string from the command to invoke</param>
/// <param name="ptInvoke">the point (in screen co鰎dinates) from which to invoke</param>
public static void InvokeCommand(ShellItem parent, IntPtr[] pidls, string cmd, Point ptInvoke)
{
IntPtr icontextMenuPtr;
IContextMenu iContextMenu;
if (GetIContextMenu(parent.ShellFolder, pidls, out icontextMenuPtr, out iContextMenu))
{
try
{
InvokeCommand(
iContextMenu,
cmd,
ShellItem.GetRealPath(parent),
ptInvoke);
}
catch (Exception) { }
finally
{
if (iContextMenu != null)
Marshal.ReleaseComObject(iContextMenu);
if (icontextMenuPtr != IntPtr.Zero)
Marshal.Release(icontextMenuPtr);
}
}
}
#endregion
/// <summary>
/// Retrieves the IContextMenu for specific items
/// </summary>
/// <param name="parent">the parent IShellFolder which contains the items</param>
/// <param name="pidls">the pidls of the items for which to retrieve the IContextMenu</param>
/// <param name="icontextMenuPtr">the pointer to the IContextMenu</param>
/// <param name="iContextMenu">the IContextMenu for the items</param>
/// <returns>true if the IContextMenu has been retrieved succesfully, false otherwise</returns>
public static bool GetIContextMenu(
IShellFolder parent,
IntPtr[] pidls,
out IntPtr iContextMenuPtr,
out IContextMenu iContextMenu)
{
if (parent.GetUIObjectOf(
IntPtr.Zero,
(uint)pidls.Length,
pidls,
ref ShellAPI.IID_IContextMenu,
IntPtr.Zero,
out iContextMenuPtr) == ShellAPI.S_OK)
{
iContextMenu =
(IContextMenu)Marshal.GetTypedObjectForIUnknown(
iContextMenuPtr, typeof(IContextMenu));
return true;
}
else
{
iContextMenuPtr = IntPtr.Zero;
iContextMenu = null;
return false;
}
}
public static bool GetNewContextMenu(ShellItem item, out IntPtr iContextMenuPtr, out IContextMenu iContextMenu)
{
if (ShellAPI.CoCreateInstance(
ref ShellAPI.CLSID_NewMenu,
IntPtr.Zero,
ShellAPI.CLSCTX.INPROC_SERVER,
ref ShellAPI.IID_IContextMenu,
out iContextMenuPtr) == ShellAPI.S_OK)
{
iContextMenu = Marshal.GetTypedObjectForIUnknown(iContextMenuPtr, typeof(IContextMenu)) as IContextMenu;
IntPtr iShellExtInitPtr;
if (Marshal.QueryInterface(
iContextMenuPtr,
ref ShellAPI.IID_IShellExtInit,
out iShellExtInitPtr) == ShellAPI.S_OK)
{
IShellExtInit iShellExtInit = Marshal.GetTypedObjectForIUnknown(
iShellExtInitPtr, typeof(IShellExtInit)) as IShellExtInit;
PIDL pidlFull = item.PIDLFull;
iShellExtInit.Initialize(pidlFull.Ptr, IntPtr.Zero, 0);
Marshal.ReleaseComObject(iShellExtInit);
Marshal.Release(iShellExtInitPtr);
pidlFull.Free();
return true;
}
else
{
if (iContextMenu != null)
{
Marshal.ReleaseComObject(iContextMenu);
iContextMenu = null;
}
if (iContextMenuPtr != IntPtr.Zero)
{
Marshal.Release(iContextMenuPtr);
iContextMenuPtr = IntPtr.Zero;
}
return false;
}
}
else
{
iContextMenuPtr = IntPtr.Zero;
iContextMenu = null;
return false;
}
}
/// <summary>
/// When keys are pressed, this method will check for known key combinations. For example copy and past with
/// Ctrl + C and Ctrl + V.
/// </summary>
public static void ProcessKeyCommands(Browser br, object sender, KeyEventArgs e)
{
if (e.Control && !e.Shift && !e.Alt)
{
switch (e.KeyCode)
{
case Keys.C:
case Keys.Insert:
case Keys.V:
case Keys.X:
#region Copy/Paste/Cut
{
Cursor.Current = Cursors.WaitCursor;
IntPtr[] pidls;
ShellItem parent;
if (sender.Equals(br.FileView) && e.KeyCode != Keys.V)
{
pidls = new IntPtr[br.FileView.SelectedItems.Count];
for (int i = 0; i < pidls.Length; i++)
{
pidls[i] = ((ShellItem)br.FileView.SelectedItems[i].Tag).PIDLRel.Ptr;
}
parent = br.SelectedItem;
}
else
{
pidls = new IntPtr[1];
pidls[0] = br.SelectedItem.PIDLRel.Ptr;
parent = (br.SelectedItem.ParentItem != null ? br.SelectedItem.ParentItem : br.SelectedItem);
}
if (pidls.Length > 0)
{
string cmd;
if (e.KeyCode == Keys.C || e.KeyCode == Keys.Insert)
cmd = "copy";
else if (e.KeyCode == Keys.V)
cmd = "paste";
else
cmd = "cut";
ContextMenuHelper.InvokeCommand(parent, pidls, cmd, new Point(0, 0));
Cursor.Current = Cursors.Default;
}
e.Handled = true;
e.SuppressKeyPress = true;
}
#endregion
break;
case Keys.A:
#region Select All
{
foreach (ListViewItem item in br.FileView.Items)
item.Selected = true;
br.FileView.Focus();
}
e.Handled = true;
e.SuppressKeyPress = true;
#endregion
break;
case Keys.N:
#region Create New Folder
if (!br.CreateNewFolder())
System.Media.SystemSounds.Beep.Play();
e.Handled = true;
e.SuppressKeyPress = true;
#endregion
break;
case Keys.Z:
break;
case Keys.Y:
break;
}
}
else
{
switch (e.KeyCode)
{
case Keys.Insert:
#region Paste
if (e.Shift && !e.Control && !e.Alt)
{
IntPtr[] pidls = new IntPtr[1];
pidls[0] = br.SelectedItem.PIDLRel.Ptr;
ShellItem parent = (br.SelectedItem.ParentItem != null ? br.SelectedItem.ParentItem : br.SelectedItem);
ContextMenuHelper.InvokeCommand(parent, pidls, "paste", new Point(0, 0));
}
e.Handled = true;
e.SuppressKeyPress = true;
#endregion
break;
case Keys.Delete:
#region Delete
if (!e.Control && !e.Alt)
{
IntPtr[] pidls;
ShellItem parent;
if (sender.Equal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -