Change a lot of CharSet.Auto's to CharSet.Unicode, explicitly put W postfix on relevant winapi functions/structs, put ExactSpelling = true for winapi functions.
We don't care for ANSI functions (no way somebody is going to run BizHawk on Windows 98/ME), and ExactSpelling = false (default) has a minor runtime cost, so this should be slightly more performant. Also, replace ShellLink COM usage with custom COM interaction code. See https://github.com/TASEmulators/BizHawk/issues/3767. The same is yet to be done for the two other COM usages.
This commit is contained in:
parent
391190b6d4
commit
956af3577e
|
@ -90,7 +90,7 @@ namespace BizHawk.Bizware.Input
|
|||
{
|
||||
const uint MAPVK_VSC_TO_VK_EX = 0x03;
|
||||
// DInputKey is a scancode as is
|
||||
var virtualKey = MapVirtualKey((uint) key, MAPVK_VSC_TO_VK_EX);
|
||||
var virtualKey = MapVirtualKeyW((uint) key, MAPVK_VSC_TO_VK_EX);
|
||||
return VKeyToDKeyMap.GetValueOrDefault(virtualKey, DInputKey.Unknown);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,12 +32,12 @@ namespace BizHawk.Bizware.Input
|
|||
|
||||
private static readonly Lazy<IntPtr> _rawInputWindowAtom = new(() =>
|
||||
{
|
||||
var wc = default(WNDCLASS);
|
||||
var wc = default(WNDCLASSW);
|
||||
wc.lpfnWndProc = _wndProc;
|
||||
wc.hInstance = LoaderApiImports.GetModuleHandleW(null);
|
||||
wc.lpszClassName = "RawKeyInputClass";
|
||||
|
||||
var atom = RegisterClass(ref wc);
|
||||
var atom = RegisterClassW(ref wc);
|
||||
if (atom == IntPtr.Zero)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to register RAWINPUT window class");
|
||||
|
@ -48,27 +48,27 @@ namespace BizHawk.Bizware.Input
|
|||
|
||||
private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
var ud = GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
var ud = GetWindowLongPtrW(hWnd, GWLP_USERDATA);
|
||||
if (ud == IntPtr.Zero)
|
||||
{
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
if (uMsg != WM_INPUT)
|
||||
{
|
||||
if (uMsg == WM_CLOSE)
|
||||
{
|
||||
SetWindowLongPtr(hWnd, GWLP_USERDATA, IntPtr.Zero);
|
||||
SetWindowLongPtrW(hWnd, GWLP_USERDATA, IntPtr.Zero);
|
||||
GCHandle.FromIntPtr(ud).Free();
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
if (GetRawInputData(lParam, RID.INPUT, IntPtr.Zero,
|
||||
out var size, Marshal.SizeOf<RAWINPUTHEADER>()) == -1)
|
||||
{
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
// don't think size should ever be this big, but just in case
|
||||
|
@ -83,7 +83,7 @@ namespace BizHawk.Bizware.Input
|
|||
if (GetRawInputData(lParam, RID.INPUT, input,
|
||||
ref size, Marshal.SizeOf<RAWINPUTHEADER>()) == -1)
|
||||
{
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
if (input->header.dwType == RAWINPUTHEADER.RIM_TYPE.KEYBOARD && input->data.keyboard.Flags <= RAWKEYBOARD.RIM_KEY.E1)
|
||||
|
@ -116,7 +116,7 @@ namespace BizHawk.Bizware.Input
|
|||
private static IntPtr CreateRawInputWindow()
|
||||
{
|
||||
const int WS_CHILD = 0x40000000;
|
||||
var window = CreateWindowEx(
|
||||
var window = CreateWindowExW(
|
||||
dwExStyle: 0,
|
||||
lpClassName: _rawInputWindowAtom.Value,
|
||||
lpWindowName: "RawKeyInput",
|
||||
|
@ -170,7 +170,7 @@ namespace BizHawk.Bizware.Input
|
|||
if (RawInputWindow != IntPtr.Zero)
|
||||
{
|
||||
// Can't use DestroyWindow, that's only allowed in the thread that created the window!
|
||||
PostMessage(RawInputWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
|
||||
PostMessageW(RawInputWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
|
||||
RawInputWindow = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -184,15 +184,15 @@ namespace BizHawk.Bizware.Input
|
|||
{
|
||||
RawInputWindow = CreateRawInputWindow();
|
||||
var handle = GCHandle.Alloc(this, GCHandleType.Normal);
|
||||
SetWindowLongPtr(RawInputWindow, GWLP_USERDATA, GCHandle.ToIntPtr(handle));
|
||||
SetWindowLongPtrW(RawInputWindow, GWLP_USERDATA, GCHandle.ToIntPtr(handle));
|
||||
}
|
||||
|
||||
HandleAltKbLayouts = handleAltKbLayouts;
|
||||
|
||||
while (PeekMessage(out var msg, RawInputWindow, 0, 0, PM_REMOVE))
|
||||
while (PeekMessageW(out var msg, RawInputWindow, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(ref msg);
|
||||
DispatchMessage(ref msg);
|
||||
DispatchMessageW(ref msg);
|
||||
}
|
||||
|
||||
var ret = KeyEvents;
|
||||
|
|
|
@ -46,10 +46,10 @@ namespace BizHawk.Bizware.Input
|
|||
// similar code shouldn't be needed on other platforms (which have global message queues and not thread local message queues)
|
||||
if (!OSTailoredCode.IsUnixHost)
|
||||
{
|
||||
while (WmImports.PeekMessage(out var msg, IntPtr.Zero, 0, 0, WmImports.PM_REMOVE))
|
||||
while (WmImports.PeekMessageW(out var msg, IntPtr.Zero, 0, 0, WmImports.PM_REMOVE))
|
||||
{
|
||||
WmImports.TranslateMessage(ref msg);
|
||||
WmImports.DispatchMessage(ref msg);
|
||||
WmImports.DispatchMessageW(ref msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// </remarks>
|
||||
public sealed class FolderBrowserEx : Component
|
||||
{
|
||||
private const BROWSEINFO.FLAGS BrowseOptions = BROWSEINFO.FLAGS.RestrictToFilesystem | BROWSEINFO.FLAGS.RestrictToDomain |
|
||||
BROWSEINFO.FLAGS.NewDialogStyle | BROWSEINFO.FLAGS.ShowTextBox;
|
||||
private const BROWSEINFOW.FLAGS BrowseOptions = BROWSEINFOW.FLAGS.RestrictToFilesystem | BROWSEINFOW.FLAGS.RestrictToDomain |
|
||||
BROWSEINFOW.FLAGS.NewDialogStyle | BROWSEINFOW.FLAGS.ShowTextBox;
|
||||
|
||||
public string Description = "Please select a folder below:";
|
||||
|
||||
|
@ -41,7 +41,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
var str = Marshal.StringToHGlobalUni(SelectedPath);
|
||||
try
|
||||
{
|
||||
WmImports.SendMessage(hwnd, BFFM_SETSELECTIONW, new(1), str);
|
||||
WmImports.SendMessageW(hwnd, BFFM_SETSELECTIONW, new(1), str);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -62,14 +62,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
var browseOptions = BrowseOptions;
|
||||
if (ApartmentState.MTA == Application.OleRequired())
|
||||
{
|
||||
browseOptions &= ~BROWSEINFO.FLAGS.NewDialogStyle;
|
||||
browseOptions &= ~BROWSEINFOW.FLAGS.NewDialogStyle;
|
||||
}
|
||||
|
||||
var pidlRet = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
var buffer = Marshal.AllocHGlobal(Win32Imports.MAX_PATH);
|
||||
var bi = new BROWSEINFO
|
||||
var bi = new BROWSEINFOW
|
||||
{
|
||||
hwndOwner = hWndOwner,
|
||||
pidlRoot = pidlRoot,
|
||||
|
@ -79,20 +79,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
lpfn = Callback
|
||||
};
|
||||
|
||||
pidlRet = SHBrowseForFolder(ref bi);
|
||||
pidlRet = SHBrowseForFolderW(ref bi);
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
if (pidlRet == IntPtr.Zero)
|
||||
{
|
||||
return DialogResult.Cancel; // user clicked Cancel
|
||||
}
|
||||
|
||||
var path = new StringBuilder(Win32Imports.MAX_PATH);
|
||||
if (SHGetPathFromIDList(pidlRet, path) == 0)
|
||||
var path = new char[Win32Imports.MAX_PATH];
|
||||
if (SHGetPathFromIDListW(pidlRet, path) == 0)
|
||||
{
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
|
||||
SelectedPath = path.ToString();
|
||||
SelectedPath = new string(path).TrimEnd('\0');
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
@ -15,17 +15,24 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// <remarks>http://stackoverflow.com/questions/139010/how-to-resolve-a-lnk-in-c-sharp</remarks>
|
||||
public static string ResolveShortcut(string filename)
|
||||
{
|
||||
if (filename.Contains("|") || OSTailoredCode.IsUnixHost || !".lnk".Equals(Path.GetExtension(filename), StringComparison.OrdinalIgnoreCase)) return filename; // archive internal files are never shortcuts (and choke when analyzing any further)
|
||||
var link = new ShellLinkImports.ShellLink();
|
||||
if (filename.Contains("|") || OSTailoredCode.IsUnixHost ||
|
||||
!".lnk".Equals(Path.GetExtension(filename), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return filename; // archive internal files are never shortcuts (and choke when analyzing any further)
|
||||
}
|
||||
|
||||
using var link = new ShellLinkImports.ShellLink();
|
||||
|
||||
const uint STGM_READ = 0;
|
||||
((ShellLinkImports.IPersistFile) link).Load(filename, STGM_READ);
|
||||
link.Load(filename, STGM_READ);
|
||||
|
||||
#if false
|
||||
// TODO: if I can get hold of the hwnd call resolve first. This handles moved and renamed files.
|
||||
((ShellLinkImports.IShellLinkW) link).Resolve(hwnd, 0);
|
||||
link.Resolve(hwnd, 0);
|
||||
#endif
|
||||
var sb = new StringBuilder(Win32Imports.MAX_PATH);
|
||||
((ShellLinkImports.IShellLinkW) link).GetPath(sb, sb.Capacity, out _, 0);
|
||||
return sb.Length == 0 ? filename : sb.ToString(); // maybe? what if it's invalid?
|
||||
|
||||
link.GetPath(out var path, Win32Imports.MAX_PATH + 1, out _, 0);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,34 +191,34 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
var columnHeader = WmImports.SendMessage(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
|
||||
var columnHeader = WmImports.SendMessageW(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
|
||||
for (int columnNumber = 0, l = listViewControl.Columns.Count; columnNumber < l; columnNumber++)
|
||||
{
|
||||
var columnPtr = new IntPtr(columnNumber);
|
||||
var item = new HDITEM { mask = HDITEM.Mask.Format };
|
||||
if (SendMessage(columnHeader, HDM_GETITEM, columnPtr, ref item) == IntPtr.Zero)
|
||||
var item = new HDITEMW { mask = HDITEMW.Mask.Format };
|
||||
if (SendMessageW(columnHeader, HDM_GETITEMW, columnPtr, ref item) == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
if (columnNumber != columnIndex || order == SortOrder.None)
|
||||
{
|
||||
item.fmt &= ~HDITEM.Format.SortDown & ~HDITEM.Format.SortUp;
|
||||
item.fmt &= ~HDITEMW.Format.SortDown & ~HDITEMW.Format.SortUp;
|
||||
}
|
||||
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
|
||||
else switch (order)
|
||||
{
|
||||
case SortOrder.Ascending:
|
||||
item.fmt &= ~HDITEM.Format.SortDown;
|
||||
item.fmt |= HDITEM.Format.SortUp;
|
||||
item.fmt &= ~HDITEMW.Format.SortDown;
|
||||
item.fmt |= HDITEMW.Format.SortUp;
|
||||
break;
|
||||
case SortOrder.Descending:
|
||||
item.fmt &= ~HDITEM.Format.SortUp;
|
||||
item.fmt |= HDITEM.Format.SortDown;
|
||||
item.fmt &= ~HDITEMW.Format.SortUp;
|
||||
item.fmt |= HDITEMW.Format.SortDown;
|
||||
break;
|
||||
}
|
||||
|
||||
if (SendMessage(columnHeader, HDM_SETITEM, columnPtr, ref item) == IntPtr.Zero)
|
||||
if (SendMessageW(columnHeader, HDM_SETITEMW, columnPtr, ref item) == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
const int SPI_GETSCREENSAVERTIMEOUT = 14;
|
||||
int value = default;
|
||||
Win32Imports.SystemParametersInfo(SPI_GETSCREENSAVERTIMEOUT, 0, ref value, 0);
|
||||
Win32Imports.SystemParametersInfoW(SPI_GETSCREENSAVERTIMEOUT, 0, ref value, 0);
|
||||
return value;
|
||||
}
|
||||
set
|
||||
|
@ -29,7 +29,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
const int SPI_SETSCREENSAVERTIMEOUT = 15;
|
||||
const int SPIF_SENDWININICHANGE = 2;
|
||||
int nullVar = default;
|
||||
Win32Imports.SystemParametersInfo(SPI_SETSCREENSAVERTIMEOUT, value, ref nullVar, SPIF_SENDWININICHANGE);
|
||||
Win32Imports.SystemParametersInfoW(SPI_SETSCREENSAVERTIMEOUT, value, ref nullVar, SPIF_SENDWININICHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -868,7 +868,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
groupFreeze.SuspendLayout();
|
||||
|
||||
WmImports.SendMessage(groupFreeze.Handle, 11, (IntPtr)0, IntPtr.Zero); //WM_SETREDRAW false
|
||||
if (!OSTailoredCode.IsUnixHost)
|
||||
{
|
||||
// WM_SETREDRAW false
|
||||
WmImports.SendMessageW(groupFreeze.Handle, 11, (IntPtr)0, IntPtr.Zero);
|
||||
}
|
||||
|
||||
var tp = tabctrlDetails.SelectedTab;
|
||||
|
||||
|
@ -886,7 +890,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
groupFreeze.ResumeLayout();
|
||||
|
||||
WmImports.SendMessage(groupFreeze.Handle, 11, (IntPtr)1, IntPtr.Zero); //WM_SETREDRAW true
|
||||
if (!OSTailoredCode.IsUnixHost)
|
||||
{
|
||||
// WM_SETREDRAW true
|
||||
WmImports.SendMessageW(groupFreeze.Handle, 11, (IntPtr)1, IntPtr.Zero);
|
||||
}
|
||||
|
||||
groupFreeze.Refresh();
|
||||
}
|
||||
|
||||
|
|
|
@ -82,9 +82,9 @@ namespace BizHawk.Common.PathExtensions
|
|||
if (File.Exists(path1.SubstringBefore('|'))) return FileAttributes.Normal;
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
var path = new StringBuilder(Win32Imports.MAX_PATH);
|
||||
return Win32Imports.PathRelativePathTo(path, fromPath, GetPathAttribute(fromPath), toPath, GetPathAttribute(toPath))
|
||||
? path.ToString()
|
||||
var path = new char[Win32Imports.MAX_PATH];
|
||||
return Win32Imports.PathRelativePathToW(path, fromPath, GetPathAttribute(fromPath), toPath, GetPathAttribute(toPath))
|
||||
? new string(path).TrimEnd('\0')
|
||||
: throw new ArgumentException(message: "Paths must have a common prefix", paramName: nameof(toPath));
|
||||
}
|
||||
|
||||
|
|
|
@ -101,41 +101,41 @@ namespace BizHawk.Common
|
|||
}
|
||||
|
||||
/// <summary>Create a new stream in an existing file and creates an interface to the new stream</summary>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern int AVIFileCreateStreamW(IntPtr pfile, out IntPtr ppavi, ref AVISTREAMINFOW psi);
|
||||
|
||||
[DllImport("avifil32.dll", SetLastError = true)]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern void AVIFileInit();
|
||||
|
||||
[DllImport("avifil32.dll", SetLastError = true)]
|
||||
[DllImport("avifil32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern int AVIFileOpenW(ref IntPtr pAviFile, [MarshalAs(UnmanagedType.LPWStr)] string szFile, OpenFileStyle uMode, int lpHandler);
|
||||
|
||||
/// <summary>Release an open AVI stream</summary>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern int AVIFileRelease(IntPtr pfile);
|
||||
|
||||
/// <summary>Create a compressed stream from an uncompressed stream and a compression filter, and returns the address of a pointer to the compressed stream</summary>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern int AVIMakeCompressedStream(out IntPtr ppsCompressed, IntPtr psSource, ref AVICOMPRESSOPTIONS lpOptions, IntPtr pclsidHandler);
|
||||
|
||||
/// <summary>Retrieve the save options for a file and returns them in a buffer</summary>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern unsafe int AVISaveOptions(IntPtr hwnd, int flags, int streams, void* ppAvi, void* plpOptions);
|
||||
|
||||
/// <inheritdoc cref="AVIFileRelease"/>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern int AVIStreamRelease(IntPtr pavi);
|
||||
|
||||
/// <summary>Set the format of a stream at the specified position</summary>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern int AVIStreamSetFormat(IntPtr pavi, int lPos, ref BITMAPINFOHEADER lpFormat, int cbFormat);
|
||||
|
||||
/// <inheritdoc cref="AVIStreamSetFormat(System.IntPtr,int,ref BizHawk.Common.AVIWriterImports.BITMAPINFOHEADER,int)"/>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern int AVIStreamSetFormat(IntPtr pavi, int lPos, ref WAVEFORMATEX lpFormat, int cbFormat);
|
||||
|
||||
/// <summary>Write data to a stream</summary>
|
||||
[DllImport("avifil32.dll")]
|
||||
[DllImport("avifil32.dll", ExactSpelling = true)]
|
||||
public static extern int AVIStreamWrite(IntPtr pavi, int lStart, int lSamples, IntPtr lpBuffer, int cbBuffer, int dwFlags, IntPtr plSampWritten, out int plBytesWritten);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ namespace BizHawk.Common
|
|||
/// <summary>Gets/Sets the current working directory while bypassing the security checks triggered by the public API (<see cref="Environment.CurrentDirectory"/>).</summary>
|
||||
public static class CWDHacks
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
private static extern unsafe int GetCurrentDirectoryW(int nBufferLength, char* lpBuffer);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
private static extern bool SetCurrentDirectoryW(string lpPathName);
|
||||
|
||||
public static bool Set(string newCWD)
|
||||
|
|
|
@ -10,16 +10,19 @@ namespace BizHawk.Common
|
|||
{
|
||||
public static class CommctrlImports
|
||||
{
|
||||
public const int LVM_GETHEADER = 4127;
|
||||
public const int HDM_GETITEM = 4619;
|
||||
public const int HDM_SETITEM = 4620;
|
||||
public const int LVM_FIRST = 0x1000;
|
||||
public const int LVM_GETHEADER = LVM_FIRST + 31;
|
||||
|
||||
public const int HDM_FIRST = 0x1200;
|
||||
public const int HDM_GETITEMW = HDM_FIRST + 11;
|
||||
public const int HDM_SETITEMW = HDM_FIRST + 12;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct HDITEM
|
||||
public struct HDITEMW
|
||||
{
|
||||
public Mask mask;
|
||||
public int cxy;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszText;
|
||||
public IntPtr hbm;
|
||||
public int cchTextMax;
|
||||
|
@ -38,20 +41,20 @@ namespace BizHawk.Common
|
|||
public uint state;
|
||||
|
||||
[Flags]
|
||||
public enum Mask
|
||||
public enum Mask : uint
|
||||
{
|
||||
Format = 0x4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum Format
|
||||
public enum Format : int
|
||||
{
|
||||
SortDown = 0x200,
|
||||
SortUp = 0x400
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, ref HDITEM lParam);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr SendMessageW(IntPtr hWnd, uint msg, IntPtr wParam, ref HDITEMW lParam);
|
||||
}
|
||||
}
|
|
@ -8,14 +8,14 @@ namespace BizHawk.Common
|
|||
{
|
||||
public static class HeapApiImports
|
||||
{
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcessHeap();
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = false)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = false)]
|
||||
public static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, int dwBytes);
|
||||
|
||||
/// <remarks>used in <c>#if false</c> code in <c>AviWriter.CodecToken.DeallocateAVICOMPRESSOPTIONS</c>, don't delete it</remarks>
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool HeapFree(IntPtr hHeap, uint dwFlags, IntPtr lpMem);
|
||||
}
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public static class LoaderApiImports
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetModuleHandleW(string? lpModuleName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr LoadLibraryW(string lpLibFileName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FreeLibrary(IntPtr hLibModule);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, IntPtr lpProcName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@ namespace BizHawk.Common
|
|||
WRITECOMBINE_Modifierflag = 0x400
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern UIntPtr VirtualAlloc(UIntPtr lpAddress, UIntPtr dwSize,
|
||||
AllocationType flAllocationType, MemoryProtection flProtect);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool VirtualProtect(
|
||||
UIntPtr lpAddress,
|
||||
|
@ -56,7 +56,7 @@ namespace BizHawk.Common
|
|||
Release = 0x8000,
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool VirtualFree(UIntPtr lpAddress, UIntPtr dwSize, FreeType dwFreeType);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public static class Ole32Imports
|
||||
{
|
||||
public enum CLSCTX : uint
|
||||
{
|
||||
INPROC_SERVER = 0x1,
|
||||
INPROC_HANDLER = 0x2,
|
||||
LOCAL_SERVER = 0x4,
|
||||
INPROC_SERVER16 = 0x8,
|
||||
REMOTE_SERVER = 0x10,
|
||||
INPROC_HANDLER16 = 0x20,
|
||||
RESERVED1 = 0x40,
|
||||
RESERVED2 = 0x80,
|
||||
RESERVED3 = 0x100,
|
||||
RESERVED4 = 0x200,
|
||||
NO_CODE_DOWNLOAD = 0x400,
|
||||
RESERVED5 = 0x800,
|
||||
NO_CUSTOM_MARSHAL = 0x1000,
|
||||
ENABLE_CODE_DOWNLOAD = 0x2000,
|
||||
NO_FAILURE_LOG = 0x4000,
|
||||
DISABLE_AAA = 0x8000,
|
||||
ENABLE_AAA = 0x10000,
|
||||
FROM_DEFAULT_CONTEXT = 0x20000,
|
||||
ACTIVATE_X86_SERVER = 0x40000,
|
||||
ACTIVATE_32_BIT_SERVER,
|
||||
ACTIVATE_64_BIT_SERVER = 0x80000,
|
||||
ENABLE_CLOAKING = 0x100000,
|
||||
APPCONTAINER = 0x400000,
|
||||
ACTIVATE_AAA_AS_IU = 0x800000,
|
||||
RESERVED6 = 0x1000000,
|
||||
ACTIVATE_ARM32_SERVER = 0x2000000,
|
||||
ALLOW_LOWER_TRUST_REGISTRATION,
|
||||
PS_DLL = 0x80000000
|
||||
}
|
||||
|
||||
[DllImport("Ole32.dll", ExactSpelling = true)]
|
||||
public static extern int CoCreateInstance(
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
|
||||
IntPtr pUnkOuter,
|
||||
CLSCTX dwClsContext,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
|
||||
out IntPtr ppv);
|
||||
}
|
||||
}
|
|
@ -129,20 +129,20 @@ namespace BizHawk.Common
|
|||
public RAWINPUTDATA data;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern unsafe IntPtr DefRawInputProc(RAWINPUT* paRawInput, int nInput, int cbSizeHeader);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[DllImport("user32.dll", ExactSpelling = true)]
|
||||
public static extern int GetRawInputData(IntPtr hRawInput, RID uiCommand, IntPtr pData, out int bSize, int cbSizeHeader);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[DllImport("user32.dll", ExactSpelling = true)]
|
||||
public static extern unsafe int GetRawInputData(IntPtr hRawInput, RID uiCommand, RAWINPUT* pData, ref int bSize, int cbSizeHeader);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool RegisterRawInputDevices(ref RAWINPUTDEVICE pRawInputDevice, uint uiNumDevices, int cbSize);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, int cbSize);
|
||||
}
|
||||
|
|
|
@ -2,122 +2,200 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public static class ShellLinkImports
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct WIN32_FIND_DATAW
|
||||
{
|
||||
public uint dwFileAttributes;
|
||||
public long ftCreationTime;
|
||||
public long ftLastAccessTime;
|
||||
public long ftLastWriteTime;
|
||||
public FILETIME ftCreationTime;
|
||||
public FILETIME ftLastAccessTime;
|
||||
public FILETIME ftLastWriteTime;
|
||||
public uint nFileSizeHigh;
|
||||
public uint nFileSizeLow;
|
||||
public uint dwReserved0;
|
||||
public uint dwReserved1;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Win32Imports.MAX_PATH)]
|
||||
public string cFileName;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
|
||||
public string cAlternateFileName;
|
||||
}
|
||||
// Obsolete fields
|
||||
public uint dwFileType;
|
||||
public uint dwCreatorType;
|
||||
public int wFinderFlags;
|
||||
|
||||
[Flags]
|
||||
public enum SLGP_FLAGS
|
||||
{
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SLR_FLAGS
|
||||
{
|
||||
public struct FILETIME
|
||||
{
|
||||
public uint dwLowDateTime;
|
||||
public uint dwHighDateTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The IShellLink interface allows Shell links to be created, modified, and resolved</summary>
|
||||
[ComImport]
|
||||
[Guid("000214F9-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IShellLinkW
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IShellLinkW
|
||||
{
|
||||
/// <summary>Retrieves the path and file name of a Shell link object</summary>
|
||||
void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags);
|
||||
/// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
|
||||
void GetIDList(out IntPtr ppidl);
|
||||
/// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
|
||||
void SetIDList(IntPtr pidl);
|
||||
/// <summary>Retrieves the description string for a Shell link object</summary>
|
||||
void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
|
||||
/// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
|
||||
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
|
||||
/// <summary>Retrieves the name of the working directory for a Shell link object</summary>
|
||||
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
|
||||
/// <summary>Sets the name of the working directory for a Shell link object</summary>
|
||||
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
|
||||
/// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
|
||||
void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
|
||||
/// <summary>Sets the command-line arguments for a Shell link object</summary>
|
||||
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
|
||||
/// <summary>Retrieves the hot key for a Shell link object</summary>
|
||||
void GetHotkey(out short pwHotkey);
|
||||
/// <summary>Sets a hot key for a Shell link object</summary>
|
||||
void SetHotkey(short wHotkey);
|
||||
/// <summary>Retrieves the show command for a Shell link object</summary>
|
||||
void GetShowCmd(out int piShowCmd);
|
||||
/// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
|
||||
void SetShowCmd(int iShowCmd);
|
||||
/// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
|
||||
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
|
||||
/// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
|
||||
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
|
||||
/// <summary>Sets the relative path to the Shell link object</summary>
|
||||
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
|
||||
/// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
|
||||
void Resolve(IntPtr hwnd, SLR_FLAGS fFlags);
|
||||
/// <summary>Sets the path and file name of a Shell link object</summary>
|
||||
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
|
||||
public static readonly Guid Guid = new("000214F9-0000-0000-C000-000000000046");
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IShellLinkWVtbl
|
||||
{
|
||||
// IUnknown functions
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, in Guid, out IntPtr, int> QueryInterface;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, uint> AddRef;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, uint> Release;
|
||||
// IShellLinkW functions
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, IntPtr, uint, int> GetPath;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, out IntPtr, int> GetIDList;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int> SetIDList;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, int> GetDescription;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int> SetDescription;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, int> GetWorkingDirectory;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int> SetWorkingDirectory;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, int> GetArguments;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int> SetArguments;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, out short, int> GetHotkey;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, short, int> SetHotkey;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, out int, int> GetShowCmd;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, int, int> SetShowCmd;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, out int, int> GetIconLocation;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, int> SetIconLocation;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, int> SetRelativePath;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int, int> Resolve;
|
||||
public delegate* unmanaged[Stdcall]<IShellLinkW*, IntPtr, int> SetPath;
|
||||
}
|
||||
|
||||
public IShellLinkWVtbl* lpVtbl;
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("0000010c-0000-0000-c000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IPersist
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IPersist
|
||||
{
|
||||
[PreserveSig]
|
||||
void GetClassID(out Guid pClassID);
|
||||
public static readonly Guid Guid = new("0000010c-0000-0000-C000-000000000046");
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IPersistVtbl
|
||||
{
|
||||
// IUnknown functions
|
||||
public delegate* unmanaged[Stdcall]<IPersist*, in Guid, out IntPtr, int> QueryInterface;
|
||||
public delegate* unmanaged[Stdcall]<IPersist*, uint> AddRef;
|
||||
public delegate* unmanaged[Stdcall]<IPersist*, uint> Release;
|
||||
// IPersist functions
|
||||
public delegate* unmanaged[Stdcall]<IPersist*, out Guid, int> GetClassID;
|
||||
}
|
||||
|
||||
public IPersistVtbl* lpVtbl;
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("0000010b-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IPersistFile : IPersist
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IPersistFile
|
||||
{
|
||||
new void GetClassID(out Guid pClassID);
|
||||
public static readonly Guid Guid = new("0000010b-0000-0000-C000-000000000046");
|
||||
|
||||
[PreserveSig]
|
||||
int IsDirty();
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IPersistFileVtbl
|
||||
{
|
||||
// IUnknown functions
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, in Guid, out IntPtr, int> QueryInterface;
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, uint> AddRef;
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, uint> Release;
|
||||
// IPersist functions
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, out Guid, int> GetClassID;
|
||||
// IPersistFile functions
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, int> IsDirty;
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, IntPtr, uint, int> Load;
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, IntPtr, bool, int> Save;
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, IntPtr, int> SaveCompleted;
|
||||
public delegate* unmanaged[Stdcall]<IPersistFile*, out IntPtr, int> GetCurFile;
|
||||
}
|
||||
|
||||
[PreserveSig]
|
||||
void Load([In, MarshalAs(UnmanagedType.LPWStr)]string pszFileName, uint dwMode);
|
||||
|
||||
[PreserveSig]
|
||||
void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [In, MarshalAs(UnmanagedType.Bool)] bool fRemember);
|
||||
|
||||
[PreserveSig]
|
||||
void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
|
||||
|
||||
[PreserveSig]
|
||||
void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
|
||||
public IPersistFileVtbl* lpVtbl;
|
||||
}
|
||||
|
||||
/// <remarks>CLSID_ShellLink from ShlGuid.h</remarks>
|
||||
[ComImport]
|
||||
[Guid("00021401-0000-0000-C000-000000000046")]
|
||||
public class ShellLink /* : IPersistFile, IShellLinkW */
|
||||
public unsafe class ShellLink : IDisposable
|
||||
{
|
||||
public static readonly Guid Guid = new("00021401-0000-0000-C000-000000000046");
|
||||
|
||||
private IShellLinkW* SLI;
|
||||
private IPersistFile* PFI;
|
||||
|
||||
public ShellLink()
|
||||
{
|
||||
var hr = Ole32Imports.CoCreateInstance(Guid, IntPtr.Zero, Ole32Imports.CLSCTX.INPROC_SERVER, IShellLinkW.Guid, out var psl);
|
||||
Marshal.ThrowExceptionForHR(hr);
|
||||
|
||||
var sli = (IShellLinkW*)psl;
|
||||
hr = sli->lpVtbl->QueryInterface(sli, in IPersist.Guid, out var ppf);
|
||||
var hrEx = Marshal.GetExceptionForHR(hr);
|
||||
if (hrEx != null)
|
||||
{
|
||||
sli->lpVtbl->Release(sli);
|
||||
throw hrEx;
|
||||
}
|
||||
|
||||
SLI = sli;
|
||||
PFI = (IPersistFile*)ppf;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (PFI != null)
|
||||
{
|
||||
PFI->lpVtbl->Release(PFI);
|
||||
PFI = null;
|
||||
}
|
||||
|
||||
if (SLI != null)
|
||||
{
|
||||
SLI->lpVtbl->Release(SLI);
|
||||
SLI = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetPath(out string pszFile, int cch, out WIN32_FIND_DATAW pfd, uint fFlags)
|
||||
{
|
||||
var pszFile_ = Marshal.AllocCoTaskMem(cch * sizeof(char));
|
||||
#if false // should we do this? we don't need pfd (NULL is valid), and we could delete the WIN32_FIND_DATAW definition by doing this
|
||||
var hr = SLI->lpVtbl->GetPath(SLI, pszFile_, cch, IntPtr.Zero, fFlags);
|
||||
#else
|
||||
var pfd_ = Marshal.AllocCoTaskMem(Marshal.SizeOf<WIN32_FIND_DATAW>());
|
||||
var hr = SLI->lpVtbl->GetPath(SLI, pszFile_, cch, pfd_, fFlags);
|
||||
#endif
|
||||
try
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(hr);
|
||||
pszFile = Marshal.PtrToStringUni(pszFile_);
|
||||
pfd = Marshal.PtrToStructure<WIN32_FIND_DATAW>(pfd_);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeCoTaskMem(pszFile_);
|
||||
Marshal.FreeCoTaskMem(pfd_);
|
||||
}
|
||||
}
|
||||
|
||||
#if false
|
||||
public void Resolve(IntPtr hwnd, int fFlags)
|
||||
{
|
||||
var hr = SLI->lpVtbl->Resolve(SLI, hwnd, fFlags);
|
||||
Marshal.ThrowExceptionForHR(hr);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void Load(string pszFileName, uint dwMode)
|
||||
{
|
||||
var pszFileName_ = Marshal.StringToCoTaskMemUni(pszFileName);
|
||||
var hr = PFI->lpVtbl->Load(PFI, pszFileName_, dwMode);
|
||||
Marshal.FreeCoTaskMem(pszFileName_);
|
||||
Marshal.ThrowExceptionForHR(hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ namespace BizHawk.Common
|
|||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
public delegate int BFFCALLBACK(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||
public struct BROWSEINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct BROWSEINFOW
|
||||
{
|
||||
public IntPtr hwndOwner;
|
||||
public IntPtr pidlRoot;
|
||||
public IntPtr pszDisplayName;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string lpszTitle;
|
||||
public FLAGS ulFlags;
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
|
@ -78,16 +78,16 @@ namespace BizHawk.Common
|
|||
void HeapMinimize();
|
||||
}
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr SHBrowseForFolder(ref BROWSEINFO bi);
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern IntPtr SHBrowseForFolderW(ref BROWSEINFOW bi);
|
||||
|
||||
[DllImport("shell32.dll")]
|
||||
[DllImport("shell32.dll", ExactSpelling = true)]
|
||||
public static extern int SHGetMalloc(out IMalloc ppMalloc);
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath);
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern int SHGetPathFromIDListW(IntPtr pidl, char[] pszPath);
|
||||
|
||||
[DllImport("shell32.dll")]
|
||||
[DllImport("shell32.dll", ExactSpelling = true)]
|
||||
public static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, out IntPtr ppidl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ namespace BizHawk.Common
|
|||
public const uint QS_ALLINPUT = 0x4FFU;
|
||||
public const uint MWMO_INPUTAVAILABLE = 0x0004U;
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern uint MsgWaitForMultipleObjectsEx(uint nCount, IntPtr[] pHandles, uint dwMilliseconds, uint dwWakeMask, uint dwFlags);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern int WaitForSingleObject(SafeWaitHandle handle, uint milliseconds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,19 +13,19 @@ namespace BizHawk.Common
|
|||
{
|
||||
public const int MAX_PATH = 260;
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern bool DeleteFileW(string lpFileName);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern uint MapVirtualKeyW(uint uCode, uint uMapType);
|
||||
|
||||
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool PathRelativePathTo([Out] StringBuilder pszPath, [In] string pszFrom, [In] FileAttributes dwAttrFrom, [In] string pszTo, [In] FileAttributes dwAttrTo);
|
||||
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern bool PathRelativePathToW([Out] char[] pszPath, [In] string pszFrom, [In] FileAttributes dwAttrFrom, [In] string pszTo, [In] FileAttributes dwAttrTo);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool SystemParametersInfo(int uAction, int uParam, ref int lpvParam, int flags);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern bool SystemParametersInfoW(int uAction, int uParam, ref int lpvParam, int flags);
|
||||
|
||||
[DllImport("winmm.dll")]
|
||||
[DllImport("winmm.dll", ExactSpelling = true)]
|
||||
public static extern uint timeBeginPeriod(uint uMilliseconds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,19 +224,19 @@ namespace BizHawk.Common
|
|||
int HandleMenuMsg(int uMsg, IntPtr wParam, IntPtr lParam);
|
||||
}
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
|
||||
public static extern IShellItem SHCreateItemFromParsingName(
|
||||
[In] string pszPath,
|
||||
[In] IntPtr pbc,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
|
||||
|
||||
[DllImport("shell32.dll", PreserveSig = false)]
|
||||
[DllImport("shell32.dll", ExactSpelling = true, PreserveSig = false)]
|
||||
public static extern IntPtr SHGetIDListFromObject([In, MarshalAs(UnmanagedType.IUnknown)] object punk);
|
||||
|
||||
[DllImport("shell32.dll", EntryPoint = "#16")]
|
||||
[DllImport("shell32.dll", EntryPoint = "#16", ExactSpelling = true)]
|
||||
public static extern IntPtr ILFindLastID(IntPtr pidl);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[DllImport("user32.dll", ExactSpelling = true)]
|
||||
public static extern int TrackPopupMenuEx(IntPtr hmenu, TPM fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm);
|
||||
|
||||
private IContextMenu ComInterface { get; }
|
||||
|
@ -271,10 +271,11 @@ namespace BizHawk.Common
|
|||
|
||||
private ref struct TempMenu
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
[DllImport("user32.dll", ExactSpelling = true)]
|
||||
private static extern IntPtr CreatePopupMenu();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool DestroyMenu(IntPtr hMenu);
|
||||
|
||||
public IntPtr Handle { get; private set; }
|
||||
|
|
|
@ -23,13 +23,14 @@ namespace BizHawk.Common
|
|||
public uint time;
|
||||
public int x;
|
||||
public int y;
|
||||
public uint lPrivate;
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
public delegate IntPtr WNDPROC(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct WNDCLASS
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct WNDCLASSW
|
||||
{
|
||||
public uint style;
|
||||
public WNDPROC lpfnWndProc;
|
||||
|
@ -43,47 +44,47 @@ namespace BizHawk.Common
|
|||
public string lpszClassName;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr CreateWindowEx(int dwExStyle, IntPtr lpClassName, string lpWindowName,
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr CreateWindowExW(int dwExStyle, IntPtr lpClassName, string lpWindowName,
|
||||
int dwStyle, int X, int Y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr DefWindowProcW(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool DestroyWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr DispatchMessage([In] ref MSG lpMsg);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr DispatchMessageW([In] ref MSG lpMsg);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[DllImport("user32.dll", ExactSpelling = true)]
|
||||
public static extern IntPtr GetActiveWindow();
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetWindowLongPtrW(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[DllImport("user32.dll", ExactSpelling = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool HideCaret(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
|
||||
public static extern bool PeekMessageW(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr PostMessageW(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr RegisterClass([In] ref WNDCLASS lpWndClass);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr RegisterClassW([In] ref WNDCLASSW lpWndClass);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr SendMessageW(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr SetWindowLongPtrW(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool TranslateMessage([In] ref MSG lpMsg);
|
||||
}
|
||||
|
|
|
@ -796,10 +796,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
nativeResult = ThreadHacks.MsgWaitForMultipleObjectsEx(count, waitHandles, 0xFFFFFFFF, QS_MASK, ThreadHacks.MWMO_INPUTAVAILABLE);
|
||||
if (IsNativeWaitSuccessful(count, nativeResult, out int managedResult) || WaitHandle.WaitTimeout == managedResult) break;
|
||||
// there is a message, pump and dispatch it
|
||||
if (WmImports.PeekMessage(out msg, IntPtr.Zero, 0, 0, WmImports.PM_REMOVE))
|
||||
if (WmImports.PeekMessageW(out msg, IntPtr.Zero, 0, 0, WmImports.PM_REMOVE))
|
||||
{
|
||||
WmImports.TranslateMessage(ref msg);
|
||||
WmImports.DispatchMessage(ref msg);
|
||||
WmImports.DispatchMessageW(ref msg);
|
||||
}
|
||||
}
|
||||
// handle.WaitOne();
|
||||
|
|
Loading…
Reference in New Issue