remove gongshell, add "simple" code for opening win32 context menu (gongshell's only actual use), re: #2261
This commit is contained in:
parent
d58a4a07f5
commit
98a8cdf693
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -16,7 +16,6 @@
|
||||||
<Reference Include="System.IO.Compression" />
|
<Reference Include="System.IO.Compression" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="GongShell" HintPath="$(ProjectDir)../../References/GongShell.dll" Private="true" />
|
|
||||||
<Reference Include="NLua, Version=1.3.2.0, Culture=neutral, processorArchitecture=MSIL" SpecificVersion="false" HintPath="$(ProjectDir)../../Assets/dll/nlua/NLua.dll" Private="false" /><!-- don't copy, will be copied with Assets -->
|
<Reference Include="NLua, Version=1.3.2.0, Culture=neutral, processorArchitecture=MSIL" SpecificVersion="false" HintPath="$(ProjectDir)../../Assets/dll/nlua/NLua.dll" Private="false" /><!-- don't copy, will be copied with Assets -->
|
||||||
<Reference Include="PcxFileTypePlugin.HawkQuantizer" HintPath="$(ProjectDir)../../References/PcxFileTypePlugin.HawkQuantizer.dll" Private="true" />
|
<Reference Include="PcxFileTypePlugin.HawkQuantizer" HintPath="$(ProjectDir)../../References/PcxFileTypePlugin.HawkQuantizer.dll" Private="true" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using BizHawk.Common;
|
using BizHawk.Common;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
using BizHawk.Client.Common;
|
using BizHawk.Client.Common;
|
||||||
|
@ -113,16 +114,20 @@ namespace BizHawk.Client.EmuHawk.ToolExtensions
|
||||||
tsmiCopyFile.Click += (o, ev) => { Clipboard.SetFileDropList(lame); };
|
tsmiCopyFile.Click += (o, ev) => { Clipboard.SetFileDropList(lame); };
|
||||||
tsdd.Items.Add(tsmiCopyFile);
|
tsdd.Items.Add(tsmiCopyFile);
|
||||||
|
|
||||||
|
if (!OSTailoredCode.IsUnixHost)
|
||||||
|
{
|
||||||
var tsmiTest = new ToolStripMenuItem { Text = "&Shell Context Menu" };
|
var tsmiTest = new ToolStripMenuItem { Text = "&Shell Context Menu" };
|
||||||
tsmiTest.Click += (o, ev) =>
|
tsmiTest.Click += (o, ev) =>
|
||||||
{
|
{
|
||||||
var si = new GongSolutions.Shell.ShellItem(hf.FullPathWithoutMember);
|
|
||||||
var scm = new GongSolutions.Shell.ShellContextMenu(si);
|
|
||||||
var tsddi = o as ToolStripDropDownItem;
|
var tsddi = o as ToolStripDropDownItem;
|
||||||
tsddi.Owner.Update();
|
tsddi.Owner.Update();
|
||||||
scm.ShowContextMenu(tsddi.Owner, new System.Drawing.Point(0, 0));
|
using var menu = new ContextMenu();
|
||||||
|
using var dummy = new Control();
|
||||||
|
Win32ShellContextMenu.ShowContextMenu(
|
||||||
|
hf.FullPathWithoutMember, menu.Handle, dummy.Handle, tsddi.Owner.Location.X, tsddi.Owner.Location.Y);
|
||||||
};
|
};
|
||||||
tsdd.Items.Add(tsmiTest);
|
tsdd.Items.Add(tsmiTest);
|
||||||
|
}
|
||||||
|
|
||||||
tsdd.Items.Add(new ToolStripSeparator());
|
tsdd.Items.Add(new ToolStripSeparator());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,284 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BizHawk.Common
|
||||||
|
{
|
||||||
|
public class Win32ShellContextMenu
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
|
||||||
|
public interface IShellItem
|
||||||
|
{
|
||||||
|
IntPtr BindToHandler(IntPtr pbc,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid riid);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
int GetParent(out IShellItem ppsi);
|
||||||
|
|
||||||
|
IntPtr GetDisplayName(uint sigdnName);
|
||||||
|
|
||||||
|
uint GetAttributes(uint sfgaoMask);
|
||||||
|
|
||||||
|
int Compare(IShellItem psi, uint hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("000214F2-0000-0000-C000-000000000046")]
|
||||||
|
public interface IEnumIDList
|
||||||
|
{
|
||||||
|
[PreserveSig]
|
||||||
|
int Next(uint celt, out IntPtr rgelt, out uint pceltFetched);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
int Skip(uint celt);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
int Reset();
|
||||||
|
|
||||||
|
IEnumIDList Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("000214E6-0000-0000-C000-000000000046")]
|
||||||
|
public interface IShellFolder
|
||||||
|
{
|
||||||
|
void ParseDisplayName(
|
||||||
|
[In] IntPtr hwnd,
|
||||||
|
[In] IntPtr pbc,
|
||||||
|
[In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,
|
||||||
|
[Out] out uint pchEaten,
|
||||||
|
[Out] out IntPtr ppidl,
|
||||||
|
[In, Out] ref uint pdwAttributes);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
int EnumObjects(
|
||||||
|
[In] IntPtr hwnd,
|
||||||
|
[In] SHCONTF grfFlags,
|
||||||
|
[Out] out IEnumIDList ppenumIDList);
|
||||||
|
|
||||||
|
void BindToObject(IntPtr pidl, IntPtr pbc,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
|
||||||
|
out IntPtr ppv);
|
||||||
|
|
||||||
|
void BindToStorage(IntPtr pidl, IntPtr pbc,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
|
||||||
|
out IntPtr ppv);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
short CompareIDs(uint lParam, IntPtr pidl1, IntPtr pidl2);
|
||||||
|
|
||||||
|
IntPtr CreateViewObject(IntPtr hwndOwner,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid riid);
|
||||||
|
|
||||||
|
void GetAttributesOf(uint cidl,
|
||||||
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] apidl,
|
||||||
|
ref uint rgfInOut);
|
||||||
|
|
||||||
|
void GetUIObjectOf(IntPtr hwndOwner, uint cidl,
|
||||||
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] IntPtr[] apidl,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
|
||||||
|
uint rgfReserved,
|
||||||
|
out IntPtr ppv);
|
||||||
|
|
||||||
|
void GetDisplayNameOf(IntPtr pidl, int uFlags, out STRRET pName);
|
||||||
|
|
||||||
|
void SetNameOf(IntPtr hwnd, IntPtr pidl, string pszName, SHCONTF uFlags, out IntPtr ppidlOut);
|
||||||
|
|
||||||
|
public enum SHCONTF
|
||||||
|
{
|
||||||
|
FOLDERS = 0x0020,
|
||||||
|
NONFOLDERS = 0x0040,
|
||||||
|
INCLUDEHIDDEN = 0x0080,
|
||||||
|
INIT_ON_FIRST_NEXT = 0x0100,
|
||||||
|
NETPRINTERSRCH = 0x0200,
|
||||||
|
SHAREABLE = 0x0400,
|
||||||
|
STORAGE = 0x0800
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = 264)]
|
||||||
|
public struct STRRET
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public uint uType;
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public IntPtr pOleStr;
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public IntPtr pStr;
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public uint uOffset;
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public IntPtr cStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum TPM
|
||||||
|
{
|
||||||
|
TPM_LEFTBUTTON = 0x0000,
|
||||||
|
TPM_RIGHTBUTTON = 0x0002,
|
||||||
|
TPM_LEFTALIGN = 0x0000,
|
||||||
|
TPM_CENTERALIGN = 0x000,
|
||||||
|
TPM_RIGHTALIGN = 0x000,
|
||||||
|
TPM_TOPALIGN = 0x0000,
|
||||||
|
TPM_VCENTERALIGN = 0x0010,
|
||||||
|
TPM_BOTTOMALIGN = 0x0020,
|
||||||
|
TPM_HORIZONTAL = 0x0000,
|
||||||
|
TPM_VERTICAL = 0x0040,
|
||||||
|
TPM_NONOTIFY = 0x0080,
|
||||||
|
TPM_RETURNCMD = 0x0100,
|
||||||
|
TPM_RECURSE = 0x0001,
|
||||||
|
TPM_HORPOSANIMATION = 0x0400,
|
||||||
|
TPM_HORNEGANIMATION = 0x0800,
|
||||||
|
TPM_VERPOSANIMATION = 0x1000,
|
||||||
|
TPM_VERNEGANIMATION = 0x2000,
|
||||||
|
TPM_NOANIMATION = 0x4000,
|
||||||
|
TPM_LAYOUTRTL = 0x8000,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum CMF : uint
|
||||||
|
{
|
||||||
|
NORMAL = 0x00000000,
|
||||||
|
DEFAULTONLY = 0x00000001,
|
||||||
|
VERBSONLY = 0x00000002,
|
||||||
|
EXPLORE = 0x00000004,
|
||||||
|
NOVERBS = 0x00000008,
|
||||||
|
CANRENAME = 0x00000010,
|
||||||
|
NODEFAULT = 0x00000020,
|
||||||
|
INCLUDESTATIC = 0x00000040,
|
||||||
|
EXTENDEDVERBS = 0x00000100,
|
||||||
|
RESERVED = 0xffff0000,
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||||
|
public struct CMINVOKECOMMANDINFO
|
||||||
|
{
|
||||||
|
public int cbSize;
|
||||||
|
public int fMask;
|
||||||
|
public IntPtr hwnd;
|
||||||
|
public string lpVerb;
|
||||||
|
public string lpParameters;
|
||||||
|
public string lpDirectory;
|
||||||
|
public int nShow;
|
||||||
|
public int dwHotKey;
|
||||||
|
public IntPtr hIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||||
|
public struct CMINVOKECOMMANDINFO_ByIndex
|
||||||
|
{
|
||||||
|
public int cbSize;
|
||||||
|
public int fMask;
|
||||||
|
public IntPtr hwnd;
|
||||||
|
public int iVerb;
|
||||||
|
public string lpParameters;
|
||||||
|
public string lpDirectory;
|
||||||
|
public int nShow;
|
||||||
|
public int dwHotKey;
|
||||||
|
public IntPtr hIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("000214e4-0000-0000-c000-000000000046")]
|
||||||
|
public interface IContextMenu
|
||||||
|
{
|
||||||
|
[PreserveSig]
|
||||||
|
int QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags);
|
||||||
|
|
||||||
|
void InvokeCommand(ref CMINVOKECOMMANDINFO pici);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
int GetCommandString(int idcmd, uint uflags, int reserved,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] StringBuilder commandstring,
|
||||||
|
int cch);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("000214f4-0000-0000-c000-000000000046")]
|
||||||
|
public interface IContextMenu2 : IContextMenu
|
||||||
|
{
|
||||||
|
[PreserveSig]
|
||||||
|
new int QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags);
|
||||||
|
|
||||||
|
void InvokeCommand(ref CMINVOKECOMMANDINFO_ByIndex pici);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
new int GetCommandString(int idcmd, uint uflags, int reserved,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] StringBuilder commandstring,
|
||||||
|
int cch);
|
||||||
|
|
||||||
|
[PreserveSig]
|
||||||
|
int HandleMenuMsg(int uMsg, IntPtr wParam, IntPtr lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
||||||
|
public static extern IShellItem SHCreateItemFromParsingName(
|
||||||
|
[In] string pszPath,
|
||||||
|
[In] IntPtr pbc,
|
||||||
|
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
|
||||||
|
|
||||||
|
[DllImport("shell32.dll", PreserveSig = false)]
|
||||||
|
public static extern IntPtr SHGetIDListFromObject([In, MarshalAs(UnmanagedType.IUnknown)] object punk);
|
||||||
|
|
||||||
|
[DllImport("shell32.dll", EntryPoint = "#16")]
|
||||||
|
public static extern IntPtr ILFindLastID(IntPtr pidl);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int TrackPopupMenuEx(IntPtr hmenu, TPM fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm);
|
||||||
|
|
||||||
|
private IContextMenu ComInterface { get; }
|
||||||
|
private IContextMenu2 ComInterface2 { get; }
|
||||||
|
|
||||||
|
private static Guid SFObject = new("3981e224-f559-11d3-8e3a-00c04f6837d5");
|
||||||
|
|
||||||
|
private Win32ShellContextMenu(string path)
|
||||||
|
{
|
||||||
|
var uri = new Uri(path);
|
||||||
|
|
||||||
|
// gongshell supported shell schemes, although that seems complicated to support and very edge case, so not bothering for now --cpp
|
||||||
|
if (uri.Scheme != "file")
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Non-file Uri schemes are unsupported");
|
||||||
|
}
|
||||||
|
|
||||||
|
var shellItem = SHCreateItemFromParsingName(uri.LocalPath, IntPtr.Zero, typeof(IShellItem).GUID);
|
||||||
|
|
||||||
|
var pidls = new IntPtr[1];
|
||||||
|
pidls[0] = ILFindLastID(SHGetIDListFromObject(shellItem));
|
||||||
|
shellItem.GetParent(out var parent);
|
||||||
|
|
||||||
|
var result = parent.BindToHandler(IntPtr.Zero, SFObject, typeof(IShellFolder).GUID);
|
||||||
|
|
||||||
|
var shellFolder = (IShellFolder)Marshal.GetObjectForIUnknown(result);
|
||||||
|
shellFolder.GetUIObjectOf(IntPtr.Zero, 1, pidls, typeof(IContextMenu).GUID, 0, out result);
|
||||||
|
|
||||||
|
ComInterface = (IContextMenu)Marshal.GetObjectForIUnknown(result);
|
||||||
|
ComInterface2 = (IContextMenu2)ComInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowContextMenu(string path, IntPtr handle, IntPtr hwnd, int x, int y)
|
||||||
|
{
|
||||||
|
var ctxMenu = new Win32ShellContextMenu(path);
|
||||||
|
const int CmdFirst = 0x8000;
|
||||||
|
ctxMenu.ComInterface.QueryContextMenu(handle, 0, CmdFirst, int.MaxValue, CMF.EXPLORE);
|
||||||
|
int command = TrackPopupMenuEx(handle, TPM.TPM_RETURNCMD, x, y, hwnd, IntPtr.Zero);
|
||||||
|
if (command > 0)
|
||||||
|
{
|
||||||
|
const int SW_SHOWNORMAL = 1;
|
||||||
|
CMINVOKECOMMANDINFO_ByIndex invoke = default;
|
||||||
|
invoke.cbSize = Marshal.SizeOf(invoke);
|
||||||
|
invoke.iVerb = command - CmdFirst;
|
||||||
|
invoke.nShow = SW_SHOWNORMAL;
|
||||||
|
ctxMenu.ComInterface2.InvokeCommand(ref invoke);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue