diff --git a/BizHawk.sln b/BizHawk.sln
index 2067752ffe5..550da2e24fd 100644
--- a/BizHawk.sln
+++ b/BizHawk.sln
@@ -37,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{74391239
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.Tests", "src\BizHawk.Tests\BizHawk.Tests.csproj", "{284E19E2-661D-4A7D-864A-AC2FC91E7C25}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Bizware.Externs", "src\BizHawk.Bizware.Externs\BizHawk.Bizware.Externs.csproj", "{DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -99,6 +101,10 @@ Global
{284E19E2-661D-4A7D-864A-AC2FC91E7C25}.Debug|Any CPU.Build.0 = Debug|Any CPU
{284E19E2-661D-4A7D-864A-AC2FC91E7C25}.Release|Any CPU.ActiveCfg = Release|Any CPU
{284E19E2-661D-4A7D-864A-AC2FC91E7C25}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Common.props b/Common.props
index 1ea6589d6cd..1c7e41a7422 100644
--- a/Common.props
+++ b/Common.props
@@ -6,7 +6,7 @@
Recommended
Recommended
Recommended
- false
+ true
true
true
true
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 439384498f4..2aa7d9cf5b8 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -18,6 +18,7 @@
+
diff --git a/src/BizHawk.Bizware.Externs/AVIFIL32.dll.cs b/src/BizHawk.Bizware.Externs/AVIFIL32.dll.cs
new file mode 100644
index 00000000000..d0a0379b6a9
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/AVIFIL32.dll.cs
@@ -0,0 +1,17 @@
+using Windows.Win32.Foundation;
+using Windows.Win32.Media.Multimedia;
+
+namespace Windows.Win32
+{
+ public static partial class Win32Imports
+ {
+ ///
+ public static unsafe nint AVISaveOptions(IAVIStream ppavi, ref AVICOMPRESSOPTIONS opts, HWND owner)
+ {
+ fixed (AVICOMPRESSOPTIONS* popts = &opts)
+ {
+ return AVISaveOptions(owner, uiFlags: 0, nStreams: 1, [ ppavi ], &popts);
+ }
+ }
+ }
+}
diff --git a/src/BizHawk.Bizware.Externs/BizHawk.Bizware.Externs.csproj b/src/BizHawk.Bizware.Externs/BizHawk.Bizware.Externs.csproj
new file mode 100644
index 00000000000..b01d74fa477
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/BizHawk.Bizware.Externs.csproj
@@ -0,0 +1,11 @@
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/src/BizHawk.Bizware.Externs/GetLastError.cs b/src/BizHawk.Bizware.Externs/GetLastError.cs
new file mode 100644
index 00000000000..89f797fd128
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/GetLastError.cs
@@ -0,0 +1,11 @@
+using System.Runtime.InteropServices;
+
+namespace Windows.Win32
+{
+ public static partial class Win32Imports
+ {
+ /// alias for , per PInvoke003/
+ public static uint GetLastError()
+ => unchecked((uint) Marshal.GetLastWin32Error());
+ }
+}
diff --git a/src/BizHawk.Bizware.Externs/KERNEL32.dll.cs b/src/BizHawk.Bizware.Externs/KERNEL32.dll.cs
new file mode 100644
index 00000000000..b5439a4228a
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/KERNEL32.dll.cs
@@ -0,0 +1,56 @@
+using System.Runtime.InteropServices;
+
+using Windows.Win32.Foundation;
+using Windows.Win32.System.Memory;
+
+namespace Windows.Win32
+{
+ public static partial class Win32Imports
+ {
+ ///
+ public static unsafe uint GetShortPathNameW(string lpszLongPath)
+ {
+ fixed (char* lpszLongPathLocal = lpszLongPath)
+ {
+ return Win32Imports.GetShortPathNameW(lpszLongPathLocal, default, 0U);
+ }
+ }
+
+ ///
+ public static unsafe void* HeapAlloc(int dwBytes, HEAP_FLAGS dwFlags = HEAP_FLAGS.HEAP_NONE)
+ => HeapAlloc(GetProcessHeap_SafeHandle(), dwFlags, dwBytes: (UIntPtr) dwBytes);
+
+ ///
+ public static unsafe BOOL IsWow64Process(HANDLE hProcess, out BOOL Wow64Process)
+ {
+ fixed (BOOL* ptr = &Wow64Process) return IsWow64Process(hProcess, ptr);
+ }
+
+ ///
+ public static unsafe UIntPtr VirtualAlloc(
+ UIntPtr lpAddress,
+ UIntPtr dwSize,
+ VIRTUAL_ALLOCATION_TYPE flAllocationType,
+ PAGE_PROTECTION_FLAGS flProtect)
+ => unchecked((UIntPtr) VirtualAlloc(
+ lpAddress: (void*) lpAddress,
+ dwSize: dwSize,
+ flAllocationType,
+ flProtect));
+
+ ///
+ public static unsafe BOOL VirtualFree(
+ UIntPtr lpAddress,
+ UIntPtr dwSize,
+ VIRTUAL_FREE_TYPE dwFreeType)
+ => unchecked(VirtualFree((void*) lpAddress, (nuint) dwSize, dwFreeType));
+
+ ///
+ public static unsafe BOOL VirtualProtect(
+ UIntPtr lpAddress,
+ UIntPtr dwSize,
+ PAGE_PROTECTION_FLAGS flNewProtect,
+ out PAGE_PROTECTION_FLAGS lpflOldProtect)
+ => unchecked(VirtualProtect((void*) lpAddress, (nuint) dwSize, flNewProtect, out lpflOldProtect));
+ }
+}
diff --git a/src/BizHawk.Bizware.Externs/NativeMethods.json b/src/BizHawk.Bizware.Externs/NativeMethods.json
new file mode 100644
index 00000000000..f5055e25230
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/NativeMethods.json
@@ -0,0 +1,7 @@
+{
+ "className": "Win32Imports",
+ "multiTargetingFriendlyAPIs": true,
+ "public": true,
+ "wideCharOnly": false,
+ "$schema": "https://aka.ms/CsWin32.schema.json"
+}
diff --git a/src/BizHawk.Bizware.Externs/NativeMethods.txt b/src/BizHawk.Bizware.Externs/NativeMethods.txt
new file mode 100644
index 00000000000..9bfdf562fec
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/NativeMethods.txt
@@ -0,0 +1,83 @@
+AVIFileCreateStreamW
+AVIFileInit
+AVIFileOpenW
+AVIFileRelease
+AVIIF_KEYFRAME
+AVIMakeCompressedStream
+AVISaveOptions
+AVIStreamRelease
+AVIStreamSetFormat
+AVIStreamSetFormat
+AVIStreamWrite
+BFFM_INITIALIZED
+BFFM_SETSELECTIONW
+BIF_DONTGOBELOWDOMAIN
+BIF_EDITBOX
+BIF_NEWDIALOGSTYLE
+BIF_RETURNONLYFSDIRS
+BITMAPINFOHEADER
+BROWSEINFOW
+ChangeWindowMessageFilter
+CMF_EXPLORE
+CreatePopupMenu
+CreateWindowExW
+DefWindowProcW
+DeleteFileW
+DestroyMenu
+DestroyWindow
+DispatchMessageW
+FormatMessageW
+FreeLibrary
+GetActiveWindow
+GetCurrentDirectoryW
+GetCurrentProcess
+GetModuleHandleW
+GetProcAddress
+GetProcessHeap
+GetRawInputBuffer
+GetRawInputData
+GetShortPathNameW
+HDITEMW
+HDM_GETITEMW
+HDM_SETITEMW
+HeapAlloc
+HeapFree
+HideCaret
+HWND_MESSAGE
+IContextMenu
+IContextMenu2
+ILFindLastID
+IPersistFile
+IShellFolder
+IShellItem
+IShellLinkW
+IsWow64Process
+LoadLibraryW
+LVM_GETHEADER
+MAX_PATH
+MapVirtualKeyW
+PathRelativePathToW
+PeekMessageW
+PostMessageW
+RegisterClassW
+RegisterRawInputDevices
+SendMessageW
+SetCurrentDirectoryW
+SetDllDirectoryW
+SHBrowseForFolderW
+SHCreateItemFromParsingName
+ShellLink
+SHGetIDListFromObject
+SHGetPathFromIDListW
+SHGetSpecialFolderLocation
+STGM
+SystemParametersInfoW
+timeBeginPeriod
+TrackPopupMenuEx
+TranslateMessage
+VirtualAlloc
+VirtualFree
+VirtualProtect
+WAVEFORMATEX
+WINDOW_LONG_PTR_INDEX
+WM_SETREDRAW
diff --git a/src/BizHawk.Bizware.Externs/SHLWAPI.dll.cs b/src/BizHawk.Bizware.Externs/SHLWAPI.dll.cs
new file mode 100644
index 00000000000..cfe28f2b39a
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/SHLWAPI.dll.cs
@@ -0,0 +1,23 @@
+using System.IO;
+
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32
+{
+ public static partial class Win32Imports
+ {
+ ///
+ public static BOOL PathRelativePathToW(
+ Span pszPath,
+ string pszFrom,
+ FileAttributes dwAttrFrom,
+ string pszTo,
+ FileAttributes dwAttrTo)
+ => PathRelativePathToW(
+ pszPath: pszPath,
+ pszFrom: pszFrom,
+ dwAttrFrom: unchecked((uint) dwAttrFrom),
+ pszTo: pszTo,
+ dwAttrTo: unchecked((uint) dwAttrTo));
+ }
+}
diff --git a/src/BizHawk.Bizware.Externs/TPMFLAGS.cs b/src/BizHawk.Bizware.Externs/TPMFLAGS.cs
new file mode 100644
index 00000000000..6dc1258c16b
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/TPMFLAGS.cs
@@ -0,0 +1,37 @@
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32.UI.WindowsAndMessaging
+{
+ ///
+ ///
+ [Flags]
+ public enum TPMFLAGS : uint
+ {
+ CENTERALIGN = 0x0004U,
+ LEFTALIGN = 0x0000U,
+ RIGHTALIGN = 0x0008U,
+
+ BOTTOMALIGN = 0x0020U,
+ TOPALIGN = 0x0000U,
+ VCENTERALIGN = 0x0010U,
+
+ NONOTIFY = 0x0080U,
+ RETURNCMD = 0x0100U,
+
+ LEFTBUTTON = 0x0000U,
+ RIGHTBUTTON = 0x0002U,
+
+ HORNEGANIMATION = 0x0800U,
+ HORPOSANIMATION = 0x0400U,
+ NOANIMATION = 0x4000U,
+ VERNEGANIMATION = 0x2000U,
+ VERPOSANIMATION = 0x1000U,
+
+ RECURSE = 0x0001U, // value missing from official docs, but confirmed by https://github.com/microsoft/windows-rs/blob/bb15076311bf185400ecd244d47596b8415450fa/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs#L3461
+
+ HORIZONTAL = 0x0000U,
+ VERTICAL = 0x0040U,
+
+ LAYOUTRTL = 0x8000U, // value also missing from official docs, but confirmed by https://github.com/microsoft/windows-rs/blob/bb15076311bf185400ecd244d47596b8415450fa/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs#L3456
+ }
+}
diff --git a/src/BizHawk.Bizware.Externs/USER32.dll.cs b/src/BizHawk.Bizware.Externs/USER32.dll.cs
new file mode 100644
index 00000000000..1aeb156b789
--- /dev/null
+++ b/src/BizHawk.Bizware.Externs/USER32.dll.cs
@@ -0,0 +1,59 @@
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.WindowsAndMessaging;
+
+namespace Windows.Win32
+{
+ public static partial class Win32Imports
+ {
+ ///
+ ///
+ public static unsafe PCWSTR MAKEINTATOM(uint i)
+ => new(unchecked((char*) i));
+
+ ///
+ public static unsafe LRESULT SendMessageW(HWND hWnd, uint Msg, IntPtr wParam, ref T lParam)
+ where T : unmanaged
+ {
+ fixed (void* ptr = &lParam)
+ {
+ return SendMessageW(
+ hWnd,
+ Msg,
+ new(unchecked((UIntPtr) wParam.ToPointer())),
+ new(unchecked((IntPtr) ptr)));
+ }
+ }
+
+ /// getter
+ ///
+ public static unsafe BOOL SystemParametersInfoW(
+ SYSTEM_PARAMETERS_INFO_ACTION uiAction,
+ uint uiParam,
+ out nint pvParam)
+ {
+ const SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS NONE = 0;
+ fixed (void* ptr = &pvParam) return SystemParametersInfoW(uiAction, uiParam, ptr, NONE);
+ }
+
+ /// setter
+ ///
+ public static unsafe BOOL SystemParametersInfoW(
+ SYSTEM_PARAMETERS_INFO_ACTION uiAction,
+ uint uiParam,
+ SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS fWinIni)
+ {
+ nint pvParam = default;
+ return SystemParametersInfoW(uiAction, uiParam, &pvParam, fWinIni);
+ }
+
+ ///
+ public static unsafe BOOL TrackPopupMenuEx(
+ HMENU hMenu,
+ TPMFLAGS uFlags,
+ int x,
+ int y,
+ HWND hwnd,
+ TPMPARAMS* lptpm)
+ => TrackPopupMenuEx(hMenu, uFlags: unchecked((uint) uFlags), x: x, y: y, hwnd, lptpm);
+ }
+}
diff --git a/src/BizHawk.Bizware.Input/KeyMouseInput/RawKeyMouseInput.cs b/src/BizHawk.Bizware.Input/KeyMouseInput/RawKeyMouseInput.cs
index 3968cbc45b4..2a173943af4 100644
--- a/src/BizHawk.Bizware.Input/KeyMouseInput/RawKeyMouseInput.cs
+++ b/src/BizHawk.Bizware.Input/KeyMouseInput/RawKeyMouseInput.cs
@@ -7,8 +7,15 @@
using BizHawk.Common;
using BizHawk.Common.CollectionExtensions;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Input;
+using Windows.Win32.UI.Input.KeyboardAndMouse;
+using Windows.Win32.UI.WindowsAndMessaging;
+
using static BizHawk.Common.RawInputImports;
-using static BizHawk.Common.WmImports;
+using static BizHawk.Common.WmImports1;
+using static Windows.Win32.Win32Imports;
namespace BizHawk.Bizware.Input
{
@@ -16,12 +23,12 @@ namespace BizHawk.Bizware.Input
/// Note: Only 1 window per device class (e.g. keyboards) is actually allowed to use RAWINPUT (last one to call RegisterRawInputDevices)
/// So only one instance can actually be used at the same time
///
- internal sealed class RawKeyMouseInput : IKeyMouseInput
+ internal sealed unsafe class RawKeyMouseInput : IKeyMouseInput
{
private const int WM_CLOSE = 0x0010;
private const int WM_INPUT = 0x00FF;
- private IntPtr RawInputWindow;
+ private HWND RawInputWindow;
private bool _handleAltKbLayouts;
private List _keyEvents = [ ];
private (int X, int Y) _mouseDelta;
@@ -33,17 +40,19 @@ internal sealed class RawKeyMouseInput : IKeyMouseInput
private int RawInputBufferSize;
private readonly int RawInputBufferDataOffset;
- private static readonly WNDPROC _wndProc = WndProc;
-
- private static readonly Lazy _rawInputWindowAtom = new(() =>
+ private static unsafe readonly Lazy _rawInputWindowAtom = new(() =>
{
- var wc = default(WNDCLASSW);
- wc.lpfnWndProc = _wndProc;
- wc.hInstance = LoaderApiImports.GetModuleHandleW(null);
- wc.lpszClassName = "RawKeyMouseInputClass";
-
- var atom = RegisterClassW(ref wc);
- if (atom == IntPtr.Zero)
+ WNDCLASSW wc = default;
+ wc.lpfnWndProc = WndProc;
+ wc.hInstance = GetModuleHandleW(default(PCWSTR));
+ var lpszClassNameStr = "RawKeyMouseInputClass";
+ PCWSTR atom;
+ fixed (char* lpszClassName = lpszClassNameStr)
+ {
+ wc.lpszClassName = lpszClassName;
+ atom = MAKEINTATOM(RegisterClassW(in wc));
+ }
+ if (atom.Value is null)
{
throw new InvalidOperationException("Failed to register RAWINPUT window class");
}
@@ -51,9 +60,9 @@ internal sealed class RawKeyMouseInput : IKeyMouseInput
return atom;
});
- private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
+ private static LRESULT WndProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
{
- var ud = GetWindowLongPtrW(hWnd, GWLP_USERDATA);
+ var ud = GetWindowLongPtrW(hWnd, WINDOW_LONG_PTR_INDEX.GWLP_USERDATA);
if (ud == IntPtr.Zero)
{
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@@ -65,7 +74,7 @@ private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntP
{
if (uMsg == WM_CLOSE)
{
- SetWindowLongPtrW(hWnd, GWLP_USERDATA, IntPtr.Zero);
+ SetWindowLongPtrW(hWnd, WINDOW_LONG_PTR_INDEX.GWLP_USERDATA, IntPtr.Zero);
handle = GCHandle.FromIntPtr(ud);
rawKeyMouseInput = (RawKeyMouseInput)handle.Target;
Marshal.FreeCoTaskMem(rawKeyMouseInput.RawInputBuffer);
@@ -75,17 +84,24 @@ private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntP
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
- if (GetRawInputData(lParam, RID.INPUT, IntPtr.Zero,
- out var size, sizeof(RAWINPUTHEADER)) == -1)
+ uint size = default;
+ if (GetRawInputData(
+ new(lParam),
+ RAW_INPUT_DATA_COMMAND_FLAGS.RID_INPUT,
+ pData: default,
+ ref size,
+ cbSizeHeader: unchecked((uint) sizeof(RAWINPUTHEADER)))
+ is uint.MaxValue/*-1*/)
{
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
// don't think size should ever be this big, but just in case
+ var allocOnHeap = size > 1024;
// also, make sure to align the buffer to a pointer boundary
- var buffer = size > 1024
- ? new IntPtr[(size + sizeof(IntPtr) - 1) / sizeof(IntPtr)]
- : stackalloc IntPtr[(size + sizeof(IntPtr) - 1) / sizeof(IntPtr)];
+ var roundedSize = unchecked((int) (size / sizeof(IntPtr)));
+ if ((size & 0b11U) is not 0U) roundedSize++;
+ var buffer = allocOnHeap ? new IntPtr[roundedSize] : stackalloc IntPtr[roundedSize];
handle = GCHandle.FromIntPtr(ud);
rawKeyMouseInput = (RawKeyMouseInput)handle.Target;
@@ -93,18 +109,23 @@ private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntP
fixed (IntPtr* p = buffer)
{
var input = (RAWINPUT*)p;
- if (GetRawInputData(lParam, RID.INPUT, input,
- ref size, sizeof(RAWINPUTHEADER)) == -1)
+ if (GetRawInputData(
+ new(lParam),
+ RAW_INPUT_DATA_COMMAND_FLAGS.RID_INPUT,
+ pData: input,
+ ref size,
+ cbSizeHeader: unchecked((uint) sizeof(RAWINPUTHEADER)))
+ is uint.MaxValue/*-1*/)
{
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
- if (input->header.dwType == RAWINPUTHEADER.RIM_TYPE.KEYBOARD)
+ if (input->header.dwType == RIM_TYPE.KEYBOARD)
{
rawKeyMouseInput.AddKeyInput(&input->data.keyboard);
}
- if (input->header.dwType == RAWINPUTHEADER.RIM_TYPE.MOUSE)
+ if (input->header.dwType == RIM_TYPE.MOUSE)
{
rawKeyMouseInput.AddMouseInput(&input->data.mouse);
}
@@ -113,14 +134,14 @@ private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntP
while (true)
{
var rawInputBuffer = (RAWINPUT*)rawKeyMouseInput.RawInputBuffer;
- size = rawKeyMouseInput.RawInputBufferSize;
- var count = GetRawInputBuffer(rawInputBuffer, ref size, sizeof(RAWINPUTHEADER));
+ size = unchecked((uint) rawKeyMouseInput.RawInputBufferSize);
+ var count = GetRawInputBuffer(rawInputBuffer, ref size, unchecked((uint) sizeof(RAWINPUTHEADER)));
if (count == 0)
{
break;
}
- if (count == -1)
+ if (count is uint.MaxValue/*-1*/)
{
// From testing, it appears this never actually occurs in practice
// As GetRawInputBuffer will succeed as long as the buffer has room for at least 1 packet
@@ -136,15 +157,15 @@ private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntP
break;
}
- for (var i = 0u; i < (uint)count; i++)
+ for (var i = 0U; i < count; i++)
{
- if (rawInputBuffer->header.dwType == RAWINPUTHEADER.RIM_TYPE.KEYBOARD)
+ if (rawInputBuffer->header.dwType == RIM_TYPE.KEYBOARD)
{
var keyboard = (RAWKEYBOARD*)((byte*)&rawInputBuffer->data.keyboard + rawKeyMouseInput.RawInputBufferDataOffset);
rawKeyMouseInput.AddKeyInput(keyboard);
}
- if (rawInputBuffer->header.dwType == RAWINPUTHEADER.RIM_TYPE.MOUSE)
+ if (rawInputBuffer->header.dwType == RIM_TYPE.MOUSE)
{
var mouse = (RAWMOUSE*)((byte*)&rawInputBuffer->data.mouse + rawKeyMouseInput.RawInputBufferDataOffset);
rawKeyMouseInput.AddMouseInput(mouse);
@@ -157,20 +178,20 @@ private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntP
}
}
- return IntPtr.Zero;
+ return default;
}
private unsafe void AddKeyInput(RAWKEYBOARD* keyboard)
{
- if ((keyboard->Flags & ~(RAWKEYBOARD.RI_KEY.E0 | RAWKEYBOARD.RI_KEY.BREAK)) == 0)
+ if ((keyboard->Flags & ~(RI_KEY.E0 | RI_KEY.BREAK)) == 0)
{
- var rawKey = (RawKey)(keyboard->MakeCode | ((keyboard->Flags & RAWKEYBOARD.RI_KEY.E0) != 0 ? 0x80 : 0));
+ var rawKey = (RawKey)(keyboard->MakeCode | ((keyboard->Flags & RI_KEY.E0) != 0 ? 0x80 : 0));
// kind of a dumb hack, the Pause key is apparently special here
// keyboards would send scancode 0x1D with an E1 prefix, followed by 0x45 (which is NumLock!)
// this "NumLock" press will set the VKey to 255 (invalid VKey), so we can use that to know if this is actually a Pause press
// (note that DIK_PAUSE is just 0x45 with an E0 prefix, although this is likely just a conversion DirectInput does internally)
- if (rawKey == RawKey.NUMLOCK && keyboard->VKey == VirtualKey.VK_NONE)
+ if (rawKey is RawKey.NUMLOCK && (VirtualKey) keyboard->VKey is VirtualKey.VK_NONE)
{
rawKey = RawKey.PAUSE;
}
@@ -182,7 +203,7 @@ private unsafe void AddKeyInput(RAWKEYBOARD* keyboard)
if (KeyEnumMap.TryGetValue(rawKey, out var key))
{
- _keyEvents.Add(new(key, (keyboard->Flags & RAWKEYBOARD.RI_KEY.BREAK) == RAWKEYBOARD.RI_KEY.MAKE));
+ _keyEvents.Add(new(key, (keyboard->Flags & RI_KEY.BREAK) == RI_KEY.MAKE));
}
}
}
@@ -190,54 +211,56 @@ private unsafe void AddKeyInput(RAWKEYBOARD* keyboard)
private unsafe void AddMouseInput(RAWMOUSE* mouse)
{
// raw input usually doesn't report absolute inputs, only in odd cases with e.g. touchscreen and rdp screen
- if ((mouse->usFlags & RAWMOUSE.MOUSE_FLAGS.MOVE_ABSOLUTE) == RAWMOUSE.MOUSE_FLAGS.MOVE_ABSOLUTE)
+ if ((mouse->usFlags & MOUSE_STATE.MOUSE_MOVE_ABSOLUTE) == MOUSE_STATE.MOUSE_MOVE_ABSOLUTE)
{
_mouseDelta.X += mouse->lLastX - _lastMouseAbsPos.X;
_mouseDelta.Y += mouse->lLastY - _lastMouseAbsPos.Y;
_lastMouseAbsPos = (mouse->lLastX, mouse->lLastY);
}
- else // ((mouse->usFlags & RAWMOUSE.MOUSE_FLAGS.MOVE_ABSOLUTE) == RAWMOUSE.MOUSE_FLAGS.MOVE_RELATIVE)
+ else // ((mouse->usFlags & MOUSE_STATE.MOUSE_MOVE_ABSOLUTE) == MOUSE_STATE.MOUSE_MOVE_RELATIVE)
{
_mouseDelta.X += mouse->lLastX;
_mouseDelta.Y += mouse->lLastY;
}
}
- private static IntPtr CreateRawInputWindow()
+ private static unsafe HWND CreateRawInputWindow()
{
- const int WS_CHILD = 0x40000000;
- var window = CreateWindowExW(
+ var lpWindowNameStr = "RawKeyInput";
+ HWND window;
+ fixed (char* lpWindowName = lpWindowNameStr)
+ {
+ window = CreateWindowExW(
dwExStyle: 0,
lpClassName: _rawInputWindowAtom.Value,
- lpWindowName: "RawKeyInput",
- dwStyle: WS_CHILD,
+ lpWindowName: lpWindowName,
+ dwStyle: WINDOW_STYLE.WS_CHILD,
X: 0,
Y: 0,
nWidth: 1,
nHeight: 1,
- hWndParent: HWND_MESSAGE,
- hMenu: IntPtr.Zero,
- hInstance: LoaderApiImports.GetModuleHandleW(null),
- lpParam: IntPtr.Zero);
-
- if (window == IntPtr.Zero)
+ hWndParent: HWND.HWND_MESSAGE,
+ hMenu: default,
+ hInstance: GetModuleHandleW(default(PCWSTR)),
+ lpParam: default);
+ }
+ if (window.IsNull)
{
throw new InvalidOperationException("Failed to create RAWINPUT window");
}
unsafe
{
- var rid = stackalloc RAWINPUTDEVICE[2];
- rid[0].usUsagePage = RAWINPUTDEVICE.HidUsagePage.GENERIC;
- rid[0].usUsage = RAWINPUTDEVICE.HidUsageId.GENERIC_KEYBOARD;
- rid[0].dwFlags = RAWINPUTDEVICE.RIDEV.INPUTSINK;
+ Span rid = stackalloc RAWINPUTDEVICE[2];
+ rid[0].usUsagePage = HidUsagePage.GENERIC;
+ rid[0].usUsage = HidUsageId.GENERIC_KEYBOARD;
+ rid[0].dwFlags = RAWINPUTDEVICE_FLAGS.RIDEV_INPUTSINK;
rid[0].hwndTarget = window;
- rid[1].usUsagePage = RAWINPUTDEVICE.HidUsagePage.GENERIC;
- rid[1].usUsage = RAWINPUTDEVICE.HidUsageId.GENERIC_MOUSE;
- rid[1].dwFlags = RAWINPUTDEVICE.RIDEV.INPUTSINK;
+ rid[1].usUsagePage = HidUsagePage.GENERIC;
+ rid[1].usUsage = HidUsageId.GENERIC_MOUSE;
+ rid[1].dwFlags = RAWINPUTDEVICE_FLAGS.RIDEV_INPUTSINK;
rid[1].hwndTarget = window;
-
- if (!RegisterRawInputDevices(rid, 2, sizeof(RAWINPUTDEVICE)))
+ if (!RegisterRawInputDevices(rid, unchecked((uint) sizeof(RAWINPUTDEVICE))))
{
DestroyWindow(window);
throw new InvalidOperationException("Failed to register RAWINPUTDEVICE");
@@ -280,11 +303,11 @@ public void Dispose()
{
lock (_lockObj)
{
- if (RawInputWindow != IntPtr.Zero)
+ if (!RawInputWindow.IsNull)
{
// Can't use DestroyWindow, that's only allowed in the thread that created the window!
- PostMessageW(RawInputWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
- RawInputWindow = IntPtr.Zero;
+ PostMessageW(RawInputWindow, WM_CLOSE, default, default);
+ RawInputWindow = HWND.Null;
}
else
{
@@ -310,15 +333,20 @@ public IEnumerable UpdateKeyInputs(bool handleAltKbLayouts)
{
RawInputWindow = CreateRawInputWindow();
var handle = GCHandle.Alloc(this, GCHandleType.Normal);
- SetWindowLongPtrW(RawInputWindow, GWLP_USERDATA, GCHandle.ToIntPtr(handle));
+ SetWindowLongPtrW(RawInputWindow, WINDOW_LONG_PTR_INDEX.GWLP_USERDATA, GCHandle.ToIntPtr(handle));
}
_handleAltKbLayouts = handleAltKbLayouts;
- while (PeekMessageW(out var msg, RawInputWindow, 0, 0, PM_REMOVE))
+ while (PeekMessageW(
+ out var msg,
+ RawInputWindow,
+ wMsgFilterMin: 0,
+ wMsgFilterMax: 0,
+ PEEK_MESSAGE_REMOVE_TYPE.PM_REMOVE))
{
- TranslateMessage(ref msg);
- DispatchMessageW(ref msg);
+ TranslateMessage(in msg);
+ DispatchMessageW(in msg);
}
var ret = _keyEvents;
@@ -340,13 +368,13 @@ public IEnumerable UpdateKeyInputs(bool handleAltKbLayouts)
{
RawInputWindow = CreateRawInputWindow();
var handle = GCHandle.Alloc(this, GCHandleType.Normal);
- SetWindowLongPtrW(RawInputWindow, GWLP_USERDATA, GCHandle.ToIntPtr(handle));
+ SetWindowLongPtrW(RawInputWindow, WINDOW_LONG_PTR_INDEX.GWLP_USERDATA, GCHandle.ToIntPtr(handle));
}
- while (PeekMessageW(out var msg, RawInputWindow, 0, 0, PM_REMOVE))
+ while (PeekMessageW(out var msg, RawInputWindow, 0, 0, PEEK_MESSAGE_REMOVE_TYPE.PM_REMOVE))
{
- TranslateMessage(ref msg);
- DispatchMessageW(ref msg);
+ TranslateMessage(in msg);
+ DispatchMessageW(in msg);
}
var ret = _mouseDelta;
@@ -395,8 +423,7 @@ private static RawKey MapToRealKeyViaScanCode(RawKey key)
scanCode |= 0xE000;
}
- const uint MAPVK_VSC_TO_VK_EX = 0x03;
- var virtualKey = (VirtualKey)MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX);
+ var virtualKey = (VirtualKey) MapVirtualKeyW(scanCode, MAP_VIRTUAL_KEY_TYPE.MAPVK_VSC_TO_VK_EX);
return VKeyToRawKeyMap.GetValueOrDefault(virtualKey);
}
diff --git a/src/BizHawk.Bizware.Input/SDL2/SDL2InputAdapter.cs b/src/BizHawk.Bizware.Input/SDL2/SDL2InputAdapter.cs
index 796244cd044..14fa41d0269 100644
--- a/src/BizHawk.Bizware.Input/SDL2/SDL2InputAdapter.cs
+++ b/src/BizHawk.Bizware.Input/SDL2/SDL2InputAdapter.cs
@@ -9,6 +9,8 @@
using BizHawk.Common.NumberExtensions;
#endif
+using Windows.Win32.UI.WindowsAndMessaging;
+
using static SDL2.SDL;
#pragma warning disable BHI1007 // target-typed Exception TODO don't
@@ -49,10 +51,15 @@ private static void DoSDLEventLoop()
// 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.PeekMessageW(out var msg, IntPtr.Zero, 0, 0, WmImports.PM_REMOVE))
+ while (WmImports.PeekMessageW(
+ out var msg,
+ hWnd: default,
+ wMsgFilterMin: 0,
+ wMsgFilterMax: 0,
+ PEEK_MESSAGE_REMOVE_TYPE.PM_REMOVE))
{
- WmImports.TranslateMessage(ref msg);
- WmImports.DispatchMessageW(ref msg);
+ WmImports.TranslateMessage(in msg);
+ WmImports.DispatchMessageW(in msg);
}
}
diff --git a/src/BizHawk.Client.DiscoHawk/Program.cs b/src/BizHawk.Client.DiscoHawk/Program.cs
index f85d66f0a75..045dc677168 100644
--- a/src/BizHawk.Client.DiscoHawk/Program.cs
+++ b/src/BizHawk.Client.DiscoHawk/Program.cs
@@ -8,6 +8,9 @@
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.DiscSystem;
+using Windows.Win32;
+using Windows.Win32.UI.WindowsAndMessaging;
+
namespace BizHawk.Client.DiscoHawk
{
internal static class Program
@@ -67,9 +70,9 @@ private static void Main(string[] args)
const uint WM_DROPFILES = 0x0233;
const uint WM_COPYDATA = 0x004A;
const uint WM_COPYGLOBALDATA = 0x0049;
- WmImports.ChangeWindowMessageFilter(WM_DROPFILES, WmImports.ChangeWindowMessageFilterFlags.Add);
- WmImports.ChangeWindowMessageFilter(WM_COPYDATA, WmImports.ChangeWindowMessageFilterFlags.Add);
- WmImports.ChangeWindowMessageFilter(WM_COPYGLOBALDATA, WmImports.ChangeWindowMessageFilterFlags.Add);
+ WmImports.ChangeWindowMessageFilter(WM_DROPFILES, CHANGE_WINDOW_MESSAGE_FILTER_FLAGS.MSGFLT_ADD);
+ WmImports.ChangeWindowMessageFilter(WM_COPYDATA, CHANGE_WINDOW_MESSAGE_FILTER_FLAGS.MSGFLT_ADD);
+ WmImports.ChangeWindowMessageFilter(WM_COPYGLOBALDATA, CHANGE_WINDOW_MESSAGE_FILTER_FLAGS.MSGFLT_ADD);
// this will look in subdirectory "dll" to load pinvoked stuff
var dllDir = Path.Combine(AppContext.BaseDirectory, "dll");
@@ -83,7 +86,7 @@ private static void Main(string[] args)
if (dllDir.ContainsOrdinal(';'))
{
- var dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir, null, 0);
+ var dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir);
if (dllShortPathLen == 0)
{
MessageBox.Show(SEMICOLON_IN_DIR_MSG);
@@ -91,14 +94,14 @@ private static void Main(string[] args)
}
var dllShortPathBuffer = new char[dllShortPathLen];
- dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir, dllShortPathBuffer, dllShortPathLen);
+ dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir, dllShortPathBuffer);
if (dllShortPathLen == 0)
{
MessageBox.Show(SEMICOLON_IN_DIR_MSG);
return;
}
- dllDir = new string(dllShortPathBuffer, 0, dllShortPathLen);
+ dllDir = dllShortPathBuffer.AsSpan(start: 0, length: (int) dllShortPathLen).ToString();
if (dllDir.ContainsOrdinal(';'))
{
MessageBox.Show(SEMICOLON_IN_DIR_MSG);
diff --git a/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs b/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs
index ae16339af67..3d97806a79b 100644
--- a/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs
+++ b/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs
@@ -7,18 +7,21 @@
using System.Threading;
using BizHawk.Client.Common;
-using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common;
-using static BizHawk.Common.HeapApiImports;
+using Windows.Win32.Graphics.Gdi;
+using Windows.Win32.Media.Audio;
+using Windows.Win32.Media.Multimedia;
+
+using AVIWriterImports = Windows.Win32.Win32Imports;
// some helpful p/invoke from http://www.codeproject.com/KB/audio-video/Motion_Detection.aspx?msg=1142967
namespace BizHawk.Client.EmuHawk
{
[VideoWriter("vfwavi", "AVI writer",
"Uses the Microsoft AVIFIL32 system to write .avi files. Audio is uncompressed; Video can be compressed with any installed VCM codec. Splits on 2G and resolution change.")]
- internal class AviWriter : IVideoWriter
+ internal unsafe class AviWriter : IVideoWriter
{
private CodecToken _currVideoCodecToken;
private AviWriterSegment _currSegment;
@@ -292,9 +295,9 @@ private class Parameters
public int width, height;
public int pitch; //in bytes
public int pitch_add;
- public void PopulateBITMAPINFOHEADER24(ref AVIWriterImports.BITMAPINFOHEADER bmih)
+ public void PopulateBITMAPINFOHEADER24(ref BITMAPINFOHEADER bmih)
{
- bmih.Init();
+ bmih.biSize = unchecked((uint) Marshal.SizeOf(bmih));
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biHeight = height;
@@ -307,9 +310,9 @@ public void PopulateBITMAPINFOHEADER24(ref AVIWriterImports.BITMAPINFOHEADER bmi
bmih.biSizeImage = (uint)(pitch * height);
}
- public void PopulateBITMAPINFOHEADER32(ref AVIWriterImports.BITMAPINFOHEADER bmih)
+ public void PopulateBITMAPINFOHEADER32(ref BITMAPINFOHEADER bmih)
{
- bmih.Init();
+ bmih.biSize = unchecked((uint) Marshal.SizeOf(bmih));
bmih.biPlanes = 1;
bmih.biBitCount = 32;
pitch = width * 4;
@@ -322,7 +325,7 @@ public void PopulateBITMAPINFOHEADER32(ref AVIWriterImports.BITMAPINFOHEADER bmi
public int a_samplerate, a_channels, a_bits;
/// is not 8 or 16, or is not in range 1..2
- public void PopulateWAVEFORMATEX(ref AVIWriterImports.WAVEFORMATEX wfex)
+ public void PopulateWAVEFORMATEX(ref WAVEFORMATEX wfex)
{
const int WAVE_FORMAT_PCM = 1;
var bytes = a_bits switch
@@ -337,7 +340,7 @@ public void PopulateWAVEFORMATEX(ref AVIWriterImports.WAVEFORMATEX wfex)
throw new InvalidOperationException($"only 1/2 channels audio are supported by {nameof(AviWriter)} and you chose: {a_channels}");
}
- wfex.Init();
+ wfex.cbSize = unchecked((ushort) Marshal.SizeOf(wfex));
wfex.nBlockAlign = (ushort)(bytes * a_channels);
wfex.nChannels = (ushort)a_channels;
wfex.wBitsPerSample = (ushort)a_bits;
@@ -346,7 +349,8 @@ public void PopulateWAVEFORMATEX(ref AVIWriterImports.WAVEFORMATEX wfex)
wfex.nAvgBytesPerSec = (uint)(wfex.nBlockAlign * a_samplerate);
}
- public int fps, fps_scale;
+ public uint fps;
+ public uint fps_scale;
}
private readonly Parameters _parameters = new Parameters();
@@ -360,10 +364,10 @@ public void SetMovieParameters(int fpsNum, int fpsDen)
bool change = false;
change |= fpsNum != _parameters.fps;
- _parameters.fps = fpsNum;
+ _parameters.fps = (uint)fpsNum;
change |= _parameters.fps_scale != fpsDen;
- _parameters.fps_scale = fpsDen;
+ _parameters.fps_scale = (uint)fpsDen;
if (change)
{
@@ -408,12 +412,12 @@ private CodecToken()
{
}
- private AVIWriterImports.AVICOMPRESSOPTIONS _comprOptions;
+ private AVICOMPRESSOPTIONS _comprOptions;
public string codec;
public byte[] Format = Array.Empty();
public byte[] Parms = Array.Empty();
- private static unsafe string Decode_mmioFOURCC(int code)
+ private static string Decode_mmioFOURCC(uint code)
{
var chs = stackalloc char[4];
@@ -427,7 +431,7 @@ private static unsafe string Decode_mmioFOURCC(int code)
return new(chs, 0, 4);
}
- public static CodecToken CreateFromAVICOMPRESSOPTIONS(ref AVIWriterImports.AVICOMPRESSOPTIONS opts)
+ public static CodecToken CreateFromAVICOMPRESSOPTIONS(ref AVICOMPRESSOPTIONS opts)
{
var ret = new CodecToken
{
@@ -437,50 +441,50 @@ public static CodecToken CreateFromAVICOMPRESSOPTIONS(ref AVIWriterImports.AVICO
Parms = new byte[opts.cbParms],
};
- if (opts.lpFormat != IntPtr.Zero)
+ if (opts.lpFormat is not null)
{
- Marshal.Copy(opts.lpFormat, ret.Format, 0, opts.cbFormat);
+ Marshal.Copy((IntPtr)opts.lpFormat, ret.Format, 0, unchecked((int)opts.cbFormat));
}
- if (opts.lpParms != IntPtr.Zero)
+ if (opts.lpParms is not null)
{
- Marshal.Copy(opts.lpParms, ret.Parms, 0, opts.cbParms);
+ Marshal.Copy((IntPtr)opts.lpParms, ret.Parms, 0, unchecked((int)opts.cbParms));
}
return ret;
}
- public static void DeallocateAVICOMPRESSOPTIONS(ref AVIWriterImports.AVICOMPRESSOPTIONS opts)
+ public static void DeallocateAVICOMPRESSOPTIONS(ref AVICOMPRESSOPTIONS opts)
{
#endif
#if false // test: increase stability by never freeing anything, ever
- if (opts.lpParms != IntPtr.Zero)
+ if (opts.lpParms is not null)
{
- HeapFree(GetProcessHeap(), 0, opts.lpParms);
+ HeapFree(GetProcessHeap_SafeHandle(), 0, opts.lpParms);
}
- if (opts.lpFormat != IntPtr.Zero)
+ if (opts.lpFormat is not null)
{
- HeapFree(GetProcessHeap(), 0, opts.lpFormat);
+ HeapFree(GetProcessHeap_SafeHandle(), 0, opts.lpFormat);
}
#endif
#if AVI_SUPPORT
- opts.lpParms = IntPtr.Zero;
- opts.lpFormat = IntPtr.Zero;
+ opts.lpParms = null;
+ opts.lpFormat = null;
}
- public void AllocateToAVICOMPRESSOPTIONS(out AVIWriterImports.AVICOMPRESSOPTIONS opts)
+ public void AllocateToAVICOMPRESSOPTIONS(out AVICOMPRESSOPTIONS opts)
{
if (_comprOptions.cbParms != 0)
{
- _comprOptions.lpParms = HeapAlloc(GetProcessHeap(), 0, _comprOptions.cbParms);
- Marshal.Copy(Parms, 0, _comprOptions.lpParms, _comprOptions.cbParms);
+ _comprOptions.lpParms = AVIWriterImports.HeapAlloc(unchecked((int)_comprOptions.cbParms));
+ Marshal.Copy(Parms, 0, (IntPtr)_comprOptions.lpParms, unchecked((int)_comprOptions.cbParms));
}
if (_comprOptions.cbFormat != 0)
{
- _comprOptions.lpFormat = HeapAlloc(GetProcessHeap(), 0, _comprOptions.cbFormat);
- Marshal.Copy(Format, 0, _comprOptions.lpFormat, _comprOptions.cbFormat);
+ _comprOptions.lpFormat = AVIWriterImports.HeapAlloc(unchecked((int)_comprOptions.cbFormat));
+ Marshal.Copy(Format, 0, (IntPtr)_comprOptions.lpFormat, unchecked((int)_comprOptions.cbFormat));
}
opts = _comprOptions;
@@ -513,7 +517,7 @@ private static CodecToken DeSerializeFromByteArray(byte[] data)
var m = new MemoryStream(data, false);
var b = new BinaryReader(m);
- var comprOptions = default(AVIWriterImports.AVICOMPRESSOPTIONS);
+ AVICOMPRESSOPTIONS comprOptions = default;
byte[] format;
byte[] parms;
@@ -521,20 +525,20 @@ private static CodecToken DeSerializeFromByteArray(byte[] data)
try
{
- comprOptions.fccType = b.ReadInt32();
- comprOptions.fccHandler = b.ReadInt32();
- comprOptions.dwKeyFrameEvery = b.ReadInt32();
- comprOptions.dwQuality = b.ReadInt32();
- comprOptions.dwBytesPerSecond = b.ReadInt32();
- comprOptions.dwFlags = b.ReadInt32();
- //comprOptions.lpFormat = b.ReadInt32();
- comprOptions.cbFormat = b.ReadInt32();
- //comprOptions.lpParms = b.ReadInt32();
- comprOptions.cbParms = b.ReadInt32();
- comprOptions.dwInterleaveEvery = b.ReadInt32();
-
- format = b.ReadBytes(comprOptions.cbFormat);
- parms = b.ReadBytes(comprOptions.cbParms);
+ comprOptions.fccType = b.ReadUInt32();
+ comprOptions.fccHandler = b.ReadUInt32();
+ comprOptions.dwKeyFrameEvery = b.ReadUInt32();
+ comprOptions.dwQuality = b.ReadUInt32();
+ comprOptions.dwBytesPerSecond = b.ReadUInt32();
+ comprOptions.dwFlags = b.ReadUInt32();
+ //comprOptions.lpFormat = b.ReadUInt32();
+ comprOptions.cbFormat = b.ReadUInt32();
+ //comprOptions.lpParms = b.ReadUInt32();
+ comprOptions.cbParms = b.ReadUInt32();
+ comprOptions.dwInterleaveEvery = b.ReadUInt32();
+
+ format = b.ReadBytes(unchecked((int)comprOptions.cbFormat));
+ parms = b.ReadBytes(unchecked((int)comprOptions.cbParms));
}
catch (IOException)
{
@@ -574,7 +578,7 @@ private class AviWriterSegment : IDisposable
{
static AviWriterSegment()
{
- AVIWriterImports.AVIFileInit();
+ MemoryApiImports.AVIFileInit();
}
public void Dispose()
@@ -582,7 +586,10 @@ public void Dispose()
private CodecToken _currVideoCodecToken;
private bool _isOpen;
- private IntPtr _pAviFile, _pAviRawVideoStream, _pAviRawAudioStream, _pAviCompressedVideoStream;
+ private IAVIFile _pAviFile;
+ private IAVIStream _pAviRawVideoStream;
+ private IAVIStream _pAviRawAudioStream;
+ private IAVIStream _pAviCompressedVideoStream;
private IntPtr _pGlobalBuf;
private int _pGlobalBuffSize;
@@ -624,23 +631,15 @@ private class OutputStatus
public long GetLengthApproximation()
=> _outStatus.video_bytes + _outStatus.audio_bytes;
- private static unsafe int AVISaveOptions(IntPtr stream, ref AVIWriterImports.AVICOMPRESSOPTIONS opts, IntPtr owner)
- {
- fixed (AVIWriterImports.AVICOMPRESSOPTIONS* _popts = &opts)
- {
- var pStream = &stream;
- var popts = _popts;
- var ppopts = &popts;
- return AVIWriterImports.AVISaveOptions(owner, 0, 1, pStream, ppopts);
- }
- }
+ public static int AVISaveOptions(IAVIStream stream, ref AVICOMPRESSOPTIONS opts, IntPtr owner)
+ => unchecked((int) AVIWriterImports.AVISaveOptions(stream, ref opts, new(owner)));
private Parameters _parameters;
/// unmanaged call failed
public void OpenFile(string destPath, Parameters parameters, CodecToken videoCodecToken)
{
- static int mmioFOURCC(string str) => (
+ static uint mmioFOURCC(string str) => (uint)(
(byte)str[0] |
((byte)str[1] << 8) |
((byte)str[2] << 16) |
@@ -658,8 +657,11 @@ static int mmioFOURCC(string str) => (
File.Delete(destPath);
}
- var hr = AVIWriterImports.AVIFileOpenW(ref _pAviFile, destPath,
- AVIWriterImports.OpenFileStyle.OF_CREATE | AVIWriterImports.OpenFileStyle.OF_WRITE, 0);
+ var hr = AVIWriterImports.AVIFileOpenW(
+ out _pAviFile,
+ destPath,
+ (uint)(BizHawk.Common.AVIWriterImports.OpenFileStyle.OF_CREATE | BizHawk.Common.AVIWriterImports.OpenFileStyle.OF_WRITE),
+ null);
var hrEx = Marshal.GetExceptionForHR(hr);
if (hrEx != null)
{
@@ -667,15 +669,18 @@ static int mmioFOURCC(string str) => (
}
// initialize the video stream
- var vidstream_header = default(AVIWriterImports.AVISTREAMINFOW);
- var bmih = default(AVIWriterImports.BITMAPINFOHEADER);
+ AVISTREAMINFOW vidstream_header = default;
+ BITMAPINFOHEADER bmih = default;
parameters.PopulateBITMAPINFOHEADER24(ref bmih);
vidstream_header.fccType = mmioFOURCC("vids");
vidstream_header.dwRate = parameters.fps;
vidstream_header.dwScale = parameters.fps_scale;
- vidstream_header.dwSuggestedBufferSize = (int)bmih.biSizeImage;
+ vidstream_header.dwSuggestedBufferSize = bmih.biSizeImage;
- hr = AVIWriterImports.AVIFileCreateStreamW(_pAviFile, out _pAviRawVideoStream, ref vidstream_header);
+ hr = AVIWriterImports.AVIFileCreateStreamW(
+ _pAviFile,
+ out _pAviRawVideoStream,
+ in vidstream_header);
hrEx = Marshal.GetExceptionForHR(hr);
if (hrEx != null)
{
@@ -684,17 +689,20 @@ static int mmioFOURCC(string str) => (
}
// initialize audio stream
- var audstream_header = default(AVIWriterImports.AVISTREAMINFOW);
- var wfex = default(AVIWriterImports.WAVEFORMATEX);
+ AVISTREAMINFOW audstream_header = default;
+ WAVEFORMATEX wfex = default;
parameters.PopulateWAVEFORMATEX(ref wfex);
audstream_header.fccType = mmioFOURCC("auds");
- audstream_header.dwQuality = -1;
+ audstream_header.dwQuality = unchecked((uint)-1);
audstream_header.dwScale = wfex.nBlockAlign;
- audstream_header.dwRate = (int)wfex.nAvgBytesPerSec;
+ audstream_header.dwRate = wfex.nAvgBytesPerSec;
audstream_header.dwSampleSize = wfex.nBlockAlign;
audstream_header.dwInitialFrames = 1; // ??? optimal value?
- hr = AVIWriterImports.AVIFileCreateStreamW(_pAviFile, out _pAviRawAudioStream, ref audstream_header);
+ hr = AVIWriterImports.AVIFileCreateStreamW(
+ _pAviFile,
+ out _pAviRawAudioStream,
+ ref audstream_header);
hrEx = Marshal.GetExceptionForHR(hr);
if (hrEx != null)
{
@@ -722,7 +730,7 @@ public IDisposable AcquireVideoCodecToken(IntPtr hwnd, CodecToken lastCodecToken
}
// encoder params
- var comprOptions = default(AVIWriterImports.AVICOMPRESSOPTIONS);
+ var comprOptions = default(AVICOMPRESSOPTIONS);
_currVideoCodecToken?.AllocateToAVICOMPRESSOPTIONS(out comprOptions);
var result = AVISaveOptions(_pAviRawVideoStream, ref comprOptions, hwnd) != 0;
@@ -752,7 +760,11 @@ public void OpenStreams()
// open compressed video stream
_currVideoCodecToken.AllocateToAVICOMPRESSOPTIONS(out var opts);
- var hr = AVIWriterImports.AVIMakeCompressedStream(out _pAviCompressedVideoStream, _pAviRawVideoStream, ref opts, IntPtr.Zero);
+ var hr = AVIWriterImports.AVIMakeCompressedStream(
+ out _pAviCompressedVideoStream,
+ _pAviRawVideoStream,
+ in opts,
+ null);
var hrEx = Marshal.GetExceptionForHR(hr);
CodecToken.DeallocateAVICOMPRESSOPTIONS(ref opts);
if (hrEx != null)
@@ -762,7 +774,7 @@ public void OpenStreams()
}
// set the compressed video stream input format
- var bmih = default(AVIWriterImports.BITMAPINFOHEADER);
+ var bmih = default(BITMAPINFOHEADER);
if (_bit32)
{
_parameters.PopulateBITMAPINFOHEADER32(ref bmih);
@@ -772,7 +784,11 @@ public void OpenStreams()
_parameters.PopulateBITMAPINFOHEADER24(ref bmih);
}
- hr = AVIWriterImports.AVIStreamSetFormat(_pAviCompressedVideoStream, 0, ref bmih, Marshal.SizeOf(bmih));
+ hr = AVIWriterImports.AVIStreamSetFormat(
+ _pAviCompressedVideoStream,
+ 0,
+ &bmih,
+ Marshal.SizeOf(bmih));
hrEx = Marshal.GetExceptionForHR(hr);
if (hrEx != null)
{
@@ -782,10 +798,14 @@ public void OpenStreams()
}
// set audio stream input format
- var wfex = default(AVIWriterImports.WAVEFORMATEX);
+ WAVEFORMATEX wfex = default;
_parameters.PopulateWAVEFORMATEX(ref wfex);
- hr = AVIWriterImports.AVIStreamSetFormat(_pAviRawAudioStream, 0, ref wfex, Marshal.SizeOf(wfex));
+ hr = AVIWriterImports.AVIStreamSetFormat(
+ _pAviRawAudioStream,
+ 0,
+ &wfex,
+ Marshal.SizeOf(wfex));
hrEx = Marshal.GetExceptionForHR(hr);
if (hrEx != null)
{
@@ -800,22 +820,22 @@ public void OpenStreams()
public void CloseFile()
{
CloseStreams();
- if (_pAviRawAudioStream != IntPtr.Zero)
+ if (_pAviRawAudioStream is not null)
{
_ = AVIWriterImports.AVIStreamRelease(_pAviRawAudioStream);
- _pAviRawAudioStream = IntPtr.Zero;
+ _pAviRawAudioStream = null;
}
- if (_pAviRawVideoStream != IntPtr.Zero)
+ if (_pAviRawVideoStream is not null)
{
_ = AVIWriterImports.AVIStreamRelease(_pAviRawVideoStream);
- _pAviRawVideoStream = IntPtr.Zero;
+ _pAviRawVideoStream = null;
}
- if (_pAviFile != IntPtr.Zero)
+ if (_pAviFile is not null)
{
_ = AVIWriterImports.AVIFileRelease(_pAviFile);
- _pAviFile = IntPtr.Zero;
+ _pAviFile = null;
}
if (_pGlobalBuf != IntPtr.Zero)
@@ -831,15 +851,15 @@ public void CloseFile()
///
private void CloseStreams()
{
- if (_pAviRawAudioStream != IntPtr.Zero)
+ if (_pAviRawAudioStream is not null)
{
FlushBufferedAudio();
}
- if (_pAviCompressedVideoStream != IntPtr.Zero)
+ if (_pAviCompressedVideoStream is not null)
{
_ = AVIWriterImports.AVIStreamRelease(_pAviCompressedVideoStream);
- _pAviCompressedVideoStream = IntPtr.Zero;
+ _pAviCompressedVideoStream = null;
}
}
@@ -867,7 +887,7 @@ public void AddSamples(IReadOnlyList samples)
}
}
- private unsafe void FlushBufferedAudio()
+ private void FlushBufferedAudio()
{
var todo = _outStatus.audio_buffered_shorts;
var todo_realsamples = todo / 2;
@@ -880,18 +900,24 @@ private unsafe void FlushBufferedAudio()
}
// (TODO - inefficient- build directly in a buffer)
- _ = AVIWriterImports.AVIStreamWrite(_pAviRawAudioStream, _outStatus.audio_samples,
- todo_realsamples, buf, todo_realsamples * 4, 0, IntPtr.Zero, out var bytes_written);
+ int bytesWritten;
+ _ = AVIWriterImports.AVIStreamWrite(
+ _pAviRawAudioStream,
+ _outStatus.audio_samples,
+ todo_realsamples,
+ buf.ToPointer(),
+ todo_realsamples * 4,
+ 0,
+ null,
+ &bytesWritten);
_outStatus.audio_samples += todo_realsamples;
- _outStatus.audio_bytes += bytes_written;
+ _outStatus.audio_bytes += bytesWritten;
_outStatus.audio_buffered_shorts = 0;
}
/// attempted frame resize during encoding
- public unsafe void AddFrame(IVideoProvider source)
+ public void AddFrame(IVideoProvider source)
{
- const int AVIIF_KEYFRAME = 0x00000010;
-
if (_parameters.width != source.BufferWidth
|| _parameters.height != source.BufferHeight)
throw new InvalidOperationException("video buffer changed between start and now");
@@ -930,9 +956,17 @@ public unsafe void AddFrame(IVideoProvider source)
bp += pitch_add;
}
- _ = AVIWriterImports.AVIStreamWrite(_pAviCompressedVideoStream, _outStatus.video_frames,
- 1, new(bytes_ptr), todo, AVIIF_KEYFRAME, IntPtr.Zero, out var bytes_written);
- _outStatus.video_bytes += bytes_written;
+ int bytesWritten;
+ _ = AVIWriterImports.AVIStreamWrite(
+ _pAviCompressedVideoStream,
+ lStart: _outStatus.video_frames,
+ lSamples: 1,
+ lpBuffer: bytes_ptr,
+ cbBuffer: todo,
+ dwFlags: AVIWriterImports.AVIIF_KEYFRAME,
+ plSampWritten: null,
+ plBytesWritten: &bytesWritten);
+ _outStatus.video_bytes += bytesWritten;
_outStatus.video_frames++;
}
}
@@ -963,9 +997,17 @@ public unsafe void AddFrame(IVideoProvider source)
idx -= w * 2;
}
- _ = AVIWriterImports.AVIStreamWrite(_pAviCompressedVideoStream, _outStatus.video_frames,
- 1, new(bytes_ptr), todo * 3, AVIIF_KEYFRAME, IntPtr.Zero, out var bytes_written);
- _outStatus.video_bytes += bytes_written;
+ int bytesWritten;
+ _ = AVIWriterImports.AVIStreamWrite(
+ _pAviCompressedVideoStream,
+ lStart: _outStatus.video_frames,
+ lSamples: 1,
+ lpBuffer: bytes_ptr,
+ cbBuffer: todo * 3,
+ dwFlags: AVIWriterImports.AVIIF_KEYFRAME,
+ plSampWritten: null,
+ plBytesWritten: &bytesWritten);
+ _outStatus.video_bytes += bytesWritten;
_outStatus.video_frames++;
}
}
diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/FolderBrowserDialogEx.cs b/src/BizHawk.Client.EmuHawk/CustomControls/FolderBrowserDialogEx.cs
index 1f8eb45df3d..deac9325f72 100644
--- a/src/BizHawk.Client.EmuHawk/CustomControls/FolderBrowserDialogEx.cs
+++ b/src/BizHawk.Client.EmuHawk/CustomControls/FolderBrowserDialogEx.cs
@@ -3,9 +3,12 @@
using System.Threading;
using System.Windows.Forms;
-using BizHawk.Common;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Shell;
+using Windows.Win32.UI.Shell.Common;
-using static BizHawk.Common.Shell32Imports;
+using static Windows.Win32.Win32Imports;
namespace BizHawk.Client.EmuHawk
{
@@ -21,25 +24,24 @@ namespace BizHawk.Client.EmuHawk
///
public sealed class FolderBrowserEx : Component
{
- private const BROWSEINFOW.FLAGS BrowseOptions = BROWSEINFOW.FLAGS.RestrictToFilesystem | BROWSEINFOW.FLAGS.RestrictToDomain |
- BROWSEINFOW.FLAGS.NewDialogStyle | BROWSEINFOW.FLAGS.ShowTextBox;
+ private const uint BrowseOptions = BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS;
public string Description = "Please select a folder below:";
public string SelectedPath;
/// Shows the folder browser dialog box with the specified owner window.
- public DialogResult ShowDialog(IWin32Window owner = null)
+ public unsafe DialogResult ShowDialog(IWin32Window owner = null)
{
const int startLocation = 0; // = Desktop CSIDL
- int Callback(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData)
+ int Callback(HWND hwnd, uint uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED)
{
var str = Marshal.StringToHGlobalUni(SelectedPath);
try
{
- WmImports.SendMessageW(hwnd, BFFM_SETSELECTIONW, new(1), str);
+ WmImports.SendMessageW(hwnd, BFFM_SETSELECTIONW, new WPARAM(1), new LPARAM(str));
}
finally
{
@@ -50,53 +52,44 @@ int Callback(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData)
return 0;
}
- var hWndOwner = owner?.Handle ?? WmImports.GetActiveWindow();
- _ = SHGetSpecialFolderLocation(hWndOwner, startLocation, out var pidlRoot);
- if (pidlRoot == IntPtr.Zero)
- {
- return DialogResult.Cancel;
- }
+ HWND hWndOwner = new(owner?.Handle ?? WmImports.GetActiveWindow());
+ ITEMIDLIST* pidlRoot = null;
+ _ = SHGetSpecialFolderLocation(hWndOwner, startLocation, &pidlRoot);
+ if (pidlRoot is null) return DialogResult.Cancel;
- var pidlRet = IntPtr.Zero;
- var pszDisplayName = IntPtr.Zero;
+ ITEMIDLIST* pidlRet = null;
+ PWSTR pszDisplayName = new(null);
try
{
var browseOptions = BrowseOptions;
- if (ApartmentState.MTA == Application.OleRequired())
- {
- browseOptions &= ~BROWSEINFOW.FLAGS.NewDialogStyle;
- }
-
- pszDisplayName = Marshal.AllocCoTaskMem(Win32Imports.MAX_PATH * sizeof(char));
- var bi = new BROWSEINFOW
+ if (Application.OleRequired() is ApartmentState.MTA) browseOptions &= ~BIF_NEWDIALOGSTYLE;
+ const int BUF_SIZE_BYTES = (int) Win32Imports.MAX_PATH * sizeof(char);
+ pszDisplayName = new(Marshal.AllocCoTaskMem(BUF_SIZE_BYTES));
+ fixed (char* lpszTitle = Description)
{
- hwndOwner = hWndOwner,
- pidlRoot = pidlRoot,
- pszDisplayName = pszDisplayName,
- lpszTitle = Description,
- ulFlags = browseOptions,
- lpfn = Callback,
- };
-
- pidlRet = SHBrowseForFolderW(ref bi);
- if (pidlRet == IntPtr.Zero)
- {
- return DialogResult.Cancel; // user clicked Cancel
+ var bi = new BROWSEINFOW
+ {
+ hwndOwner = hWndOwner,
+ pidlRoot = pidlRoot,
+ pszDisplayName = pszDisplayName,
+ lpszTitle = lpszTitle,
+ ulFlags = browseOptions,
+ lpfn = Callback,
+ };
+ pidlRet = SHBrowseForFolderW(in bi);
}
+ if (pidlRet is null) return DialogResult.Cancel; // user clicked Cancel
var path = new char[Win32Imports.MAX_PATH];
- if (SHGetPathFromIDListW(pidlRet, path) == 0)
- {
- return DialogResult.Cancel;
- }
+ if (!SHGetPathFromIDListW(*pidlRet, path)) return DialogResult.Cancel;
SelectedPath = new string(path).TrimEnd('\0');
}
finally
{
- Marshal.FreeCoTaskMem(pidlRoot);
- Marshal.FreeCoTaskMem(pidlRet);
- Marshal.FreeCoTaskMem(pszDisplayName);
+ Marshal.FreeCoTaskMem(unchecked((IntPtr) pidlRoot));
+ Marshal.FreeCoTaskMem(unchecked((IntPtr) pidlRet));
+ Marshal.FreeCoTaskMem(unchecked((IntPtr) pszDisplayName.Value));
}
return DialogResult.OK;
diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs
index c6941f81fe5..c1e518aa6cc 100644
--- a/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs
+++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs
@@ -64,7 +64,7 @@ protected override void OnMouseClick(MouseEventArgs e)
{
if (!OSTailoredCode.IsUnixHost)
{
- WmImports.HideCaret(Handle);
+ WmImports.HideCaret(new(Handle));
}
base.OnMouseClick(e);
@@ -260,7 +260,7 @@ protected override void OnGotFocus(EventArgs e)
{
if (!OSTailoredCode.IsUnixHost)
{
- WmImports.HideCaret(Handle);
+ WmImports.HideCaret(new(Handle));
}
}
@@ -269,4 +269,4 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
return !(keyData.ToString() == "F4" || keyData.ToString().Contains("Alt"));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/BizHawk.Client.EmuHawk/EmuHawkUtil.cs b/src/BizHawk.Client.EmuHawk/EmuHawkUtil.cs
index ed731e4f71d..06ab0999fe6 100644
--- a/src/BizHawk.Client.EmuHawk/EmuHawkUtil.cs
+++ b/src/BizHawk.Client.EmuHawk/EmuHawkUtil.cs
@@ -4,6 +4,10 @@
using BizHawk.Common;
using BizHawk.Common.StringExtensions;
+using Windows.Win32;
+using Windows.Win32.System.Com;
+using Windows.Win32.UI.Shell;
+
namespace BizHawk.Client.EmuHawk
{
public static class EmuHawkUtil
@@ -21,21 +25,13 @@ public static string ResolveShortcut(string filename)
return filename; // archive internal files are never shortcuts (and choke when analyzing any further)
}
- using var link = new ShellLinkImports.ShellLink();
-
- unsafe
- {
- const uint STGM_READ = 0;
- ((ShellLinkImports.IPersistFile*)link)->Load(filename, STGM_READ);
-
+ ShellLink link = new();
+ ((IPersistFile) link).Load(filename, unchecked((uint) STGM.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);
+ // TODO: if I can get hold of the hwnd call resolve first. This handles moved and renamed files.
+ ((IShellLinkW) link).Resolve(hwnd, 0);
#endif
-
- ((ShellLinkImports.IShellLinkW*)link)->GetPath(out var path, Win32Imports.MAX_PATH + 1, 0);
- return path;
- }
+ return ((IShellLinkW) link).GetPath();
}
}
}
diff --git a/src/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs b/src/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
index b25d632af62..446d683f627 100644
--- a/src/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
+++ b/src/BizHawk.Client.EmuHawk/Extensions/ControlExtensions.cs
@@ -17,7 +17,10 @@
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common;
-using static BizHawk.Common.CommctrlImports;
+using Windows.Win32;
+using Windows.Win32.UI.Controls;
+
+using static Windows.Win32.Win32Imports;
namespace BizHawk.Client.EmuHawk
{
@@ -228,34 +231,38 @@ public static void SetSortIcon(this ListView listViewControl, int columnIndex, S
return;
}
- var columnHeader = WmImports.SendMessageW(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
+ var columnHeader = WmImports.SendMessageW(
+ new(listViewControl.Handle),
+ Win32Imports.LVM_GETHEADER,
+ default,
+ IntPtr.Zero);
for (int columnNumber = 0, l = listViewControl.Columns.Count; columnNumber < l; columnNumber++)
{
var columnPtr = new IntPtr(columnNumber);
- var item = new HDITEMW { mask = HDITEMW.Mask.Format };
- if (SendMessageW(columnHeader, HDM_GETITEMW, columnPtr, ref item) == IntPtr.Zero)
+ var item = new HDITEMW { mask = HDI_MASK.HDI_FORMAT };
+ if (SendMessageW(new(columnHeader.Value), Win32Imports.HDM_GETITEMW, columnPtr, ref item) == IntPtr.Zero)
{
throw new Win32Exception();
}
if (columnNumber != columnIndex || order == SortOrder.None)
{
- item.fmt &= ~HDITEMW.Format.SortDown & ~HDITEMW.Format.SortUp;
+ item.fmt &= ~(HEADER_CONTROL_FORMAT_FLAGS.HDF_SORTDOWN | HEADER_CONTROL_FORMAT_FLAGS.HDF_SORTUP);
}
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
else switch (order)
{
case SortOrder.Ascending:
- item.fmt &= ~HDITEMW.Format.SortDown;
- item.fmt |= HDITEMW.Format.SortUp;
+ item.fmt &= ~HEADER_CONTROL_FORMAT_FLAGS.HDF_SORTDOWN;
+ item.fmt |= HEADER_CONTROL_FORMAT_FLAGS.HDF_SORTUP;
break;
case SortOrder.Descending:
- item.fmt &= ~HDITEMW.Format.SortUp;
- item.fmt |= HDITEMW.Format.SortDown;
+ item.fmt &= ~HEADER_CONTROL_FORMAT_FLAGS.HDF_SORTUP;
+ item.fmt |= HEADER_CONTROL_FORMAT_FLAGS.HDF_SORTDOWN;
break;
}
- if (SendMessageW(columnHeader, HDM_SETITEMW, columnPtr, ref item) == IntPtr.Zero)
+ if (SendMessageW(new(columnHeader.Value), Win32Imports.HDM_SETITEMW, columnPtr, ref item) == IntPtr.Zero)
{
throw new Win32Exception();
}
diff --git a/src/BizHawk.Client.EmuHawk/Program.cs b/src/BizHawk.Client.EmuHawk/Program.cs
index f1ea4b31e48..d6b236031d2 100644
--- a/src/BizHawk.Client.EmuHawk/Program.cs
+++ b/src/BizHawk.Client.EmuHawk/Program.cs
@@ -14,6 +14,8 @@
using BizHawk.Client.EmuHawk.CustomControls;
using BizHawk.Emulation.Cores;
+using Windows.Win32;
+
namespace BizHawk.Client.EmuHawk
{
internal static class Program
@@ -132,7 +134,7 @@ private static int SubMain(string[] args)
if (dllDir.ContainsOrdinal(';'))
{
- var dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir, null, 0);
+ var dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir);
if (dllShortPathLen == 0)
{
MessageBox.Show(SEMICOLON_IN_DIR_MSG);
@@ -140,14 +142,14 @@ private static int SubMain(string[] args)
}
var dllShortPathBuffer = new char[dllShortPathLen];
- dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir, dllShortPathBuffer, dllShortPathLen);
+ dllShortPathLen = Win32Imports.GetShortPathNameW(dllDir, dllShortPathBuffer);
if (dllShortPathLen == 0)
{
MessageBox.Show(SEMICOLON_IN_DIR_MSG);
return -1;
}
- dllDir = new string(dllShortPathBuffer, 0, dllShortPathLen);
+ dllDir = dllShortPathBuffer.AsSpan(start: 0, length: (int) dllShortPathLen).ToString();
if (dllDir.ContainsOrdinal(';'))
{
MessageBox.Show(SEMICOLON_IN_DIR_MSG);
diff --git a/src/BizHawk.Client.EmuHawk/ScreenSaver.cs b/src/BizHawk.Client.EmuHawk/ScreenSaver.cs
index 72163977e5d..ffee8da8f69 100644
--- a/src/BizHawk.Client.EmuHawk/ScreenSaver.cs
+++ b/src/BizHawk.Client.EmuHawk/ScreenSaver.cs
@@ -1,5 +1,8 @@
using BizHawk.Common;
+using Windows.Win32;
+using Windows.Win32.UI.WindowsAndMessaging;
+
namespace BizHawk.Client.EmuHawk
{
/// Derived from http://www.codeproject.com/KB/cs/ScreenSaverControl.aspx
@@ -19,17 +22,18 @@ public int Duration
{
get
{
- const int SPI_GETSCREENSAVERTIMEOUT = 14;
- int value = default;
- Win32Imports.SystemParametersInfoW(SPI_GETSCREENSAVERTIMEOUT, 0, ref value, 0);
- return value;
+ _ = Win32Imports.SystemParametersInfoW(
+ SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETSCREENSAVETIMEOUT,
+ uiParam: 0,
+ out var value);
+ return unchecked((int) value);
}
set
{
- const int SPI_SETSCREENSAVERTIMEOUT = 15;
- const int SPIF_SENDWININICHANGE = 2;
- int nullVar = default;
- Win32Imports.SystemParametersInfoW(SPI_SETSCREENSAVERTIMEOUT, value, ref nullVar, SPIF_SENDWININICHANGE);
+ _ = Win32Imports.SystemParametersInfoW(
+ SYSTEM_PARAMETERS_INFO_ACTION.SPI_SETSCREENSAVETIMEOUT,
+ unchecked((uint) value),
+ SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS.SPIF_SENDWININICHANGE);
}
}
}
diff --git a/src/BizHawk.Client.EmuHawk/Throttle.cs b/src/BizHawk.Client.EmuHawk/Throttle.cs
index 45557b1ee0a..b1904ed76fd 100644
--- a/src/BizHawk.Client.EmuHawk/Throttle.cs
+++ b/src/BizHawk.Client.EmuHawk/Throttle.cs
@@ -4,6 +4,8 @@
using BizHawk.Client.Common;
using BizHawk.Common;
+using Windows.Win32;
+
//this throttle is nitsuja's fine-tuned techniques from desmume
namespace BizHawk.Client.EmuHawk
diff --git a/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs b/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs
index 707e23d2b1f..a27fa76712e 100644
--- a/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs
@@ -34,6 +34,9 @@
using BizHawk.Emulation.Common;
using BizHawk.Common;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+
namespace BizHawk.Client.EmuHawk
{
public unsafe partial class SNESGraphicsDebugger : ToolFormBase, IToolFormAutoConfig
@@ -872,8 +875,8 @@ private void Freeze()
if (!OSTailoredCode.IsUnixHost)
{
- // WM_SETREDRAW false
- WmImports.SendMessageW(groupFreeze.Handle, 11, (IntPtr)0, IntPtr.Zero);
+ WPARAM falseVal = new(0);
+ WmImports.SendMessageW(new(groupFreeze.Handle), Win32Imports.WM_SETREDRAW, falseVal, default);
}
var tp = tabctrlDetails.SelectedTab;
@@ -894,8 +897,8 @@ private void Freeze()
if (!OSTailoredCode.IsUnixHost)
{
- // WM_SETREDRAW true
- WmImports.SendMessageW(groupFreeze.Handle, 11, (IntPtr)1, IntPtr.Zero);
+ WPARAM trueVal = new(1);
+ WmImports.SendMessageW(new(groupFreeze.Handle), Win32Imports.WM_SETREDRAW, trueVal, default);
}
groupFreeze.Refresh();
diff --git a/src/BizHawk.Common/BizHawk.Common.csproj b/src/BizHawk.Common/BizHawk.Common.csproj
index a110093bce4..f2980ce426a 100644
--- a/src/BizHawk.Common/BizHawk.Common.csproj
+++ b/src/BizHawk.Common/BizHawk.Common.csproj
@@ -13,10 +13,7 @@
-
-
-
-
+
diff --git a/src/BizHawk.Common/Extensions/PathExtensions.cs b/src/BizHawk.Common/Extensions/PathExtensions.cs
index 5a032bc1773..cc79630da91 100644
--- a/src/BizHawk.Common/Extensions/PathExtensions.cs
+++ b/src/BizHawk.Common/Extensions/PathExtensions.cs
@@ -2,6 +2,8 @@
using BizHawk.Common.StringExtensions;
+using Windows.Win32;
+
namespace BizHawk.Common.PathExtensions
{
public static class PathExtensions
diff --git a/src/BizHawk.Common/MemoryBlock/MemoryBlockWindowsPal.cs b/src/BizHawk.Common/MemoryBlock/MemoryBlockWindowsPal.cs
index 4ba9a1c4cc1..3786f051a48 100644
--- a/src/BizHawk.Common/MemoryBlock/MemoryBlockWindowsPal.cs
+++ b/src/BizHawk.Common/MemoryBlock/MemoryBlockWindowsPal.cs
@@ -1,5 +1,7 @@
-using static BizHawk.Common.MemoryApiImports;
+using Windows.Win32.System.Memory;
+
using static BizHawk.Common.MemoryBlock;
+using static Windows.Win32.Win32Imports;
namespace BizHawk.Common
{
@@ -11,7 +13,10 @@ internal sealed class MemoryBlockWindowsPal : IMemoryBlockPal
public MemoryBlockWindowsPal(ulong size)
{
var ptr = (ulong)VirtualAlloc(
- UIntPtr.Zero, Z.UU(size), AllocationType.MEM_RESERVE | AllocationType.MEM_COMMIT, MemoryProtection.NOACCESS);
+ UIntPtr.Zero,
+ Z.UU(size),
+ VIRTUAL_ALLOCATION_TYPE.MEM_RESERVE | VIRTUAL_ALLOCATION_TYPE.MEM_COMMIT,
+ PAGE_PROTECTION_FLAGS.PAGE_NOACCESS);
if (ptr == 0)
{
@@ -29,12 +34,12 @@ public void Protect(ulong start, ulong size, Protection prot)
}
}
- private static MemoryProtection GetKernelMemoryProtectionValue(Protection prot) => prot switch
+ private static PAGE_PROTECTION_FLAGS GetKernelMemoryProtectionValue(Protection prot) => prot switch
{
- Protection.None => MemoryProtection.NOACCESS,
- Protection.R => MemoryProtection.READONLY,
- Protection.RW => MemoryProtection.READWRITE,
- Protection.RX => MemoryProtection.EXECUTE_READ,
+ Protection.None => PAGE_PROTECTION_FLAGS.PAGE_NOACCESS,
+ Protection.R => PAGE_PROTECTION_FLAGS.PAGE_READONLY,
+ Protection.RW => PAGE_PROTECTION_FLAGS.PAGE_READWRITE,
+ Protection.RX => PAGE_PROTECTION_FLAGS.PAGE_EXECUTE_READ,
_ => throw new InvalidOperationException(nameof(prot)),
};
@@ -45,7 +50,7 @@ public void Dispose()
return;
}
- VirtualFree(Z.UU(Start), UIntPtr.Zero, FreeType.Release);
+ VirtualFree(Z.UU(Start), UIntPtr.Zero, VIRTUAL_FREE_TYPE.MEM_RELEASE);
_disposed = true;
}
}
diff --git a/src/BizHawk.Common/OSTailoredCode.cs b/src/BizHawk.Common/OSTailoredCode.cs
index f5c4f2e2ea6..abda14b9055 100644
--- a/src/BizHawk.Common/OSTailoredCode.cs
+++ b/src/BizHawk.Common/OSTailoredCode.cs
@@ -3,7 +3,12 @@
using BizHawk.Common.StringExtensions;
-using static BizHawk.Common.LoaderApiImports;
+using Microsoft.Win32.SafeHandles;
+
+using Windows.Win32;
+using Windows.Win32.System.Diagnostics.Debug;
+
+using static Windows.Win32.Win32Imports;
namespace BizHawk.Common
{
@@ -210,9 +215,24 @@ public string GetErrorMessage()
private class WindowsLLManager : ILinkedLibManager
{
- public int FreeByPtr(IntPtr hModule) => FreeLibrary(hModule) ? 0 : 1;
+ private sealed class DummySafeHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ public DummySafeHandle(IntPtr hModule)
+ : base(ownsHandle: true)
+ => SetHandle(hModule);
+
+ protected override bool ReleaseHandle()
+ => true;
+ }
- public IntPtr GetProcAddrOrZero(IntPtr hModule, string procName) => GetProcAddress(hModule, procName);
+ public int FreeByPtr(IntPtr hModule)
+ => FreeLibrary(new(hModule)) ? 0 : 1;
+
+ public unsafe IntPtr GetProcAddrOrZero(IntPtr hModule, string procName)
+ {
+ DummySafeHandle wrapper = new(hModule);
+ return GetProcAddress(wrapper, procName);
+ }
public IntPtr GetProcAddrOrThrow(IntPtr hModule, string procName)
{
@@ -220,7 +240,10 @@ public IntPtr GetProcAddrOrThrow(IntPtr hModule, string procName)
return ret != IntPtr.Zero ? ret : throw new InvalidOperationException($"got null pointer from {nameof(GetProcAddress)} trying to find symbol {procName}, {GetErrorMessage()}");
}
- public IntPtr LoadOrZero(string dllToLoad) => LoadLibraryW(dllToLoad);
+ public unsafe IntPtr LoadOrZero(string dllToLoad)
+ {
+ fixed (char* ptr = dllToLoad) return LoadLibraryW(ptr);
+ }
public IntPtr LoadOrThrow(string dllToLoad)
{
@@ -231,10 +254,16 @@ public IntPtr LoadOrThrow(string dllToLoad)
public unsafe string GetErrorMessage()
{
var errCode = Win32Imports.GetLastError();
- var buffer = stackalloc char[1024];
- const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
- var sz = Win32Imports.FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, errCode, 0, buffer, 1024, IntPtr.Zero);
- return $"error code: 0x{errCode:X8}, error message: {new string(buffer, 0, sz)}";
+ Span buffer = stackalloc char[1024];
+ var sz = Win32Imports.FormatMessageW(
+ FORMAT_MESSAGE_OPTIONS.FORMAT_MESSAGE_FROM_SYSTEM,
+ lpSource: default,
+ dwMessageId: errCode,
+ dwLanguageId: 0,
+ buffer,
+ nSize: 1024,
+ Arguments: default);
+ return $"error code: 0x{errCode:X8}, error message: {buffer.Slice(start: 0, length: (int) sz).ToString()}";
}
}
diff --git a/src/BizHawk.Common/ShellLinkExtensions.cs b/src/BizHawk.Common/ShellLinkExtensions.cs
new file mode 100644
index 00000000000..0da007d5a68
--- /dev/null
+++ b/src/BizHawk.Common/ShellLinkExtensions.cs
@@ -0,0 +1,19 @@
+using Windows.Win32.Storage.FileSystem;
+using Windows.Win32.UI.Shell;
+
+namespace Windows.Win32
+{
+ public static class ShellLinkExtensions
+ {
+ ///
+ public static string GetPath(this IShellLinkW shellLink)
+ {
+ Span buf = stackalloc char[(int) Win32Imports.MAX_PATH + 1];
+ WIN32_FIND_DATAW pfd = default;
+ shellLink.GetPath(buf, ref pfd, fFlags: default);
+ var i = buf.IndexOf((char) 0);
+ if (i >= 0) buf = buf.Slice(start: 0, length: i);
+ return buf.ToString();
+ }
+ }
+}
diff --git a/src/BizHawk.Common/TempFileManager.cs b/src/BizHawk.Common/TempFileManager.cs
index 3338545282c..395804a954a 100644
--- a/src/BizHawk.Common/TempFileManager.cs
+++ b/src/BizHawk.Common/TempFileManager.cs
@@ -5,6 +5,8 @@
using BizHawk.Common.PathExtensions;
+using Windows.Win32;
+
namespace BizHawk.Common
{
///
diff --git a/src/BizHawk.Common/Win32/AVIWriterImports.cs b/src/BizHawk.Common/Win32/AVIWriterImports.cs
index 377e548fc2e..7ebf683c785 100644
--- a/src/BizHawk.Common/Win32/AVIWriterImports.cs
+++ b/src/BizHawk.Common/Win32/AVIWriterImports.cs
@@ -1,9 +1,6 @@
#nullable disable
#if AVI_SUPPORT
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
namespace BizHawk.Common
{
@@ -15,127 +12,6 @@ public enum OpenFileStyle : uint
OF_WRITE = 0x00000001,
OF_CREATE = 0x00001000,
}
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct AVISTREAMINFOW
- {
- public int fccType;
- public int fccHandler;
- public int dwFlags;
- public int dwCaps;
- public short wPriority;
- public short wLanguage;
- public int dwScale;
- public int dwRate;
- public int dwStart;
- public int dwLength;
- public int dwInitialFrames;
- public int dwSuggestedBufferSize;
- public int dwQuality;
- public int dwSampleSize;
- public RECT rcFrame;
- public int dwEditCount;
- public int dwFormatChangeCount;
- [MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)]
- public string szName;
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct RECT
- {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct BITMAPINFOHEADER
- {
- public uint biSize;
- public int biWidth;
- public int biHeight;
- public ushort biPlanes;
- public ushort biBitCount;
- public uint biCompression;
- public uint biSizeImage;
- public int biXPelsPerMeter;
- public int biYPelsPerMeter;
- public uint biClrUsed;
- public uint biClrImportant;
-
- public void Init()
- => biSize = (uint)Marshal.SizeOf(this);
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct AVICOMPRESSOPTIONS
- {
- public int fccType;
- public int fccHandler;
- public int dwKeyFrameEvery;
- public int dwQuality;
- public int dwBytesPerSecond;
- public int dwFlags;
- public IntPtr lpFormat;
- public int cbFormat;
- public IntPtr lpParms;
- public int cbParms;
- public int dwInterleaveEvery;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct WAVEFORMATEX
- {
- public ushort wFormatTag;
- public ushort nChannels;
- public uint nSamplesPerSec;
- public uint nAvgBytesPerSec;
- public ushort nBlockAlign;
- public ushort wBitsPerSample;
- public ushort cbSize;
-
- public void Init()
- => cbSize = (ushort)Marshal.SizeOf(this);
- }
-
- /// Create a new stream in an existing file and creates an interface to the new stream
- [DllImport("avifil32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static extern int AVIFileCreateStreamW(IntPtr pfile, out IntPtr ppavi, ref AVISTREAMINFOW psi);
-
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern void AVIFileInit();
-
- [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);
-
- /// Release an open AVI stream
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern int AVIFileRelease(IntPtr pfile);
-
- /// Create a compressed stream from an uncompressed stream and a compression filter, and returns the address of a pointer to the compressed stream
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern int AVIMakeCompressedStream(out IntPtr ppsCompressed, IntPtr psSource, ref AVICOMPRESSOPTIONS lpOptions, IntPtr pclsidHandler);
-
- /// Retrieve the save options for a file and returns them in a buffer
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern unsafe int AVISaveOptions(IntPtr hwnd, int flags, int streams, void* ppAvi, void* plpOptions);
-
- ///
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern int AVIStreamRelease(IntPtr pavi);
-
- /// Set the format of a stream at the specified position
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern int AVIStreamSetFormat(IntPtr pavi, int lPos, ref BITMAPINFOHEADER lpFormat, int cbFormat);
-
- ///
- [DllImport("avifil32.dll", ExactSpelling = true)]
- public static extern int AVIStreamSetFormat(IntPtr pavi, int lPos, ref WAVEFORMATEX lpFormat, int cbFormat);
-
- /// Write data to a stream
- [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);
}
}
#endif
diff --git a/src/BizHawk.Common/Win32/CWDHacks.cs b/src/BizHawk.Common/Win32/CWDHacks.cs
index 3409395ebf4..e30707b8d43 100644
--- a/src/BizHawk.Common/Win32/CWDHacks.cs
+++ b/src/BizHawk.Common/Win32/CWDHacks.cs
@@ -1,16 +1,14 @@
using System.Runtime.InteropServices;
+using Windows.Win32;
+
+using static Windows.Win32.Win32Imports;
+
namespace BizHawk.Common
{
/// Gets/Sets the current working directory while bypassing the security checks triggered by the public API ().
public static class CWDHacks
{
- [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, ExactSpelling = true, SetLastError = true)]
- private static extern bool SetCurrentDirectoryW(string lpPathName);
-
public static bool Set(string newCWD)
=> SetCurrentDirectoryW(newCWD);
@@ -23,15 +21,15 @@ static Exception GetExceptionForFailure()
return new InvalidOperationException("GetCurrentDirectoryW returned 0!", ex);
}
- const int STARTING_BUF_SIZE = Win32Imports.MAX_PATH + 1;
- var startingBuffer = stackalloc char[STARTING_BUF_SIZE];
- var ret = GetCurrentDirectoryW(STARTING_BUF_SIZE, startingBuffer);
+ const int STARTING_BUF_SIZE = (int) Win32Imports.MAX_PATH + 1;
+ Span startingBuffer = stackalloc char[STARTING_BUF_SIZE];
+ var ret = GetCurrentDirectoryW(startingBuffer);
switch (ret)
{
case 0:
throw GetExceptionForFailure();
case < STARTING_BUF_SIZE: // ret should be smaller than the buffer, as ret doesn't include null terminator
- return new(startingBuffer, 0, ret);
+ return startingBuffer.Slice(start: 0, length: unchecked((int) ret)).ToString();
}
// since current directory could suddenly grow (due to it being global / modifiable by other threads), a while true loop is used here
@@ -40,18 +38,15 @@ static Exception GetExceptionForFailure()
{
var bufSize = ret;
var buffer = new char[bufSize];
- fixed (char* p = buffer)
+ ret = GetCurrentDirectoryW(buffer);
+ if (ret == 0)
{
- ret = GetCurrentDirectoryW(bufSize, p);
- if (ret == 0)
- {
- throw GetExceptionForFailure();
- }
+ throw GetExceptionForFailure();
+ }
- if (ret < bufSize)
- {
- return new(p, 0, ret);
- }
+ if (ret < bufSize)
+ {
+ return new(buffer, startIndex: 0, length: unchecked((int) ret));
}
}
}
diff --git a/src/BizHawk.Common/Win32/CommctrlImports.cs b/src/BizHawk.Common/Win32/CommctrlImports.cs
deleted file mode 100644
index 9eaaaa5bf46..00000000000
--- a/src/BizHawk.Common/Win32/CommctrlImports.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-#nullable disable
-
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
-// ReSharper disable UnusedMember.Global
-
-namespace BizHawk.Common
-{
- public static class CommctrlImports
- {
- 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 HDITEMW
- {
- public Mask mask;
- public int cxy;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string pszText;
- public IntPtr hbm;
- public int cchTextMax;
- public Format fmt;
- public IntPtr lParam;
-
- // _WIN32_IE >= 0x0300
- public int iImage;
- public int iOrder;
-
- // _WIN32_IE >= 0x0500
- public uint type;
- public IntPtr pvFilter;
-
- // _WIN32_WINNT >= 0x0600
- public uint state;
-
- [Flags]
- public enum Mask : uint
- {
- Format = 0x4,
- }
-
- [Flags]
- public enum Format : int
- {
- SortDown = 0x200,
- SortUp = 0x400,
- }
- }
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr SendMessageW(IntPtr hWnd, uint msg, IntPtr wParam, ref HDITEMW lParam);
- }
-}
\ No newline at end of file
diff --git a/src/BizHawk.Common/Win32/HeapApiImports.cs b/src/BizHawk.Common/Win32/HeapApiImports.cs
deleted file mode 100644
index 8f9d884c25b..00000000000
--- a/src/BizHawk.Common/Win32/HeapApiImports.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
-// ReSharper disable UnusedMember.Global
-
-namespace BizHawk.Common
-{
- public static class HeapApiImports
- {
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr GetProcessHeap();
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = false)]
- public static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, int dwBytes);
-
- /// used in #if false code in AviWriter.CodecToken.DeallocateAVICOMPRESSOPTIONS, don't delete it
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool HeapFree(IntPtr hHeap, uint dwFlags, IntPtr lpMem);
- }
-}
diff --git a/src/BizHawk.Common/Win32/LoaderApiImports.cs b/src/BizHawk.Common/Win32/LoaderApiImports.cs
deleted file mode 100644
index f5913f17282..00000000000
--- a/src/BizHawk.Common/Win32/LoaderApiImports.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Runtime.InteropServices;
-
-// ReSharper disable UnusedMember.Global
-
-namespace BizHawk.Common
-{
- public static class LoaderApiImports
- {
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr GetModuleHandleW(string? lpModuleName);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr LoadLibraryW(string lpLibFileName);
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool FreeLibrary(IntPtr hLibModule);
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr GetProcAddress(IntPtr hModule, IntPtr lpProcName);
- }
-}
diff --git a/src/BizHawk.Common/Win32/MemoryApiImports.cs b/src/BizHawk.Common/Win32/MemoryApiImports.cs
deleted file mode 100644
index 0731a4d93f4..00000000000
--- a/src/BizHawk.Common/Win32/MemoryApiImports.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
-// ReSharper disable UnusedMember.Global
-
-namespace BizHawk.Common
-{
- public static class MemoryApiImports
- {
- [Flags]
- public enum AllocationType : uint
- {
- MEM_COMMIT = 0x00001000,
- MEM_RESERVE = 0x00002000,
- MEM_RESET = 0x00080000,
- MEM_RESET_UNDO = 0x1000000,
- MEM_LARGE_PAGES = 0x20000000,
- MEM_PHYSICAL = 0x00400000,
- MEM_TOP_DOWN = 0x00100000,
- MEM_WRITE_WATCH = 0x00200000,
- }
-
- [Flags]
- public enum MemoryProtection : uint
- {
- EXECUTE = 0x10,
- EXECUTE_READ = 0x20,
- EXECUTE_READWRITE = 0x40,
- EXECUTE_WRITECOPY = 0x80,
- NOACCESS = 0x01,
- READONLY = 0x02,
- READWRITE = 0x04,
- WRITECOPY = 0x08,
- GUARD_Modifierflag = 0x100,
- NOCACHE_Modifierflag = 0x200,
- WRITECOMBINE_Modifierflag = 0x400,
- }
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- public static extern UIntPtr VirtualAlloc(UIntPtr lpAddress, UIntPtr dwSize,
- AllocationType flAllocationType, MemoryProtection flProtect);
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool VirtualProtect(
- UIntPtr lpAddress,
- UIntPtr dwSize,
- MemoryProtection flNewProtect,
- out MemoryProtection lpflOldProtect);
-
- [Flags]
- public enum FreeType : uint
- {
- Decommit = 0x4000,
- Release = 0x8000,
- }
-
- [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool VirtualFree(UIntPtr lpAddress, UIntPtr dwSize, FreeType dwFreeType);
- }
-}
diff --git a/src/BizHawk.Common/Win32/MotWHack.cs b/src/BizHawk.Common/Win32/MotWHack.cs
index 52e2a645b4f..3933f305d65 100644
--- a/src/BizHawk.Common/Win32/MotWHack.cs
+++ b/src/BizHawk.Common/Win32/MotWHack.cs
@@ -1,6 +1,8 @@
+using Windows.Win32;
+
namespace BizHawk.Common
{
- /// This code (and an import for ) is duplicated in each executable project because it needs to be used before loading assemblies.
+ /// This code (and an import for DeleteFileW) is duplicated in each executable project because it needs to be used before loading assemblies.
public static class MotWHack
{
public static void RemoveMOTW(string path)
diff --git a/src/BizHawk.Common/Win32/Ole32Imports.cs b/src/BizHawk.Common/Win32/Ole32Imports.cs
deleted file mode 100644
index 1571a1a03ce..00000000000
--- a/src/BizHawk.Common/Win32/Ole32Imports.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-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 = 0x4000000, // missing from official docs lmao, but confirmed by https://github.com/microsoft/windows-rs/blob/3fd93b0a8064e4c9c2fb6f43da798030124ee9c5/crates/libs/sys/src/Windows/Win32/System/Com/mod.rs#L315
- 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);
- }
-}
diff --git a/src/BizHawk.Common/Win32/RawInputImports.cs b/src/BizHawk.Common/Win32/RawInputImports.cs
index 52175dc7d3c..d6fb1d8274d 100644
--- a/src/BizHawk.Common/Win32/RawInputImports.cs
+++ b/src/BizHawk.Common/Win32/RawInputImports.cs
@@ -1,5 +1,3 @@
-using System.Runtime.InteropServices;
-
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable UnusedMember.Global
@@ -359,156 +357,38 @@ public enum VirtualKey : ushort
VK_NONE = 0xFF,
}
- [StructLayout(LayoutKind.Sequential)]
- public struct RAWINPUTDEVICE
+ public static class HidUsagePage
{
- public HidUsagePage usUsagePage;
- public HidUsageId usUsage;
- public RIDEV dwFlags;
- public IntPtr hwndTarget;
-
- public enum HidUsagePage : ushort
- {
- GENERIC = 1,
- GAME = 5,
- LED = 8,
- BUTTON = 9,
- }
-
- public enum HidUsageId : ushort
- {
- GENERIC_POINTER = 1,
- GENERIC_MOUSE = 2,
- GENERIC_JOYSTICK = 4,
- GENERIC_GAMEPAD = 5,
- GENERIC_KEYBOARD = 6,
- GENERIC_KEYPAD = 7,
- GENERIC_MULTI_AXIS_CONTROLLER = 8,
- }
-
- [Flags]
- public enum RIDEV : int
- {
- REMOVE = 0x00000001,
- EXCLUDE = 0x00000010,
- PAGEONLY = 0x00000020,
- NOLEGACY = PAGEONLY | EXCLUDE,
- INPUTSINK = 0x00000100,
- CAPTUREMOUSE = 0x00000200,
- NOHOTKEYS = CAPTUREMOUSE,
- APPKEYS = 0x00000400,
- EXINPUTSINK = 0x00001000,
- DEVNOTIFY = 0x00002000,
- }
+ public const ushort GENERIC = 1;
+ public const ushort GAME = 5;
+ public const ushort LED = 8;
+ public const ushort BUTTON = 9;
}
- public enum RID : uint
+ public static class HidUsageId
{
- HEADER = 0x10000005,
- INPUT = 0x10000003,
+ public const ushort GENERIC_POINTER = 1;
+ public const ushort GENERIC_MOUSE = 2;
+ public const ushort GENERIC_JOYSTICK = 4;
+ public const ushort GENERIC_GAMEPAD = 5;
+ public const ushort GENERIC_KEYBOARD = 6;
+ public const ushort GENERIC_KEYPAD = 7;
+ public const ushort GENERIC_MULTI_AXIS_CONTROLLER = 8;
}
- [StructLayout(LayoutKind.Sequential)]
- public struct RAWINPUTHEADER
+ public static class RIM_TYPE
{
- public RIM_TYPE dwType;
- public uint dwSize;
- public IntPtr hDevice;
- public IntPtr wParam;
-
- public enum RIM_TYPE : uint
- {
- MOUSE = 0,
- KEYBOARD = 1,
- HID = 2,
- }
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RAWMOUSE
- {
- public MOUSE_FLAGS usFlags;
- public uint ulButtons;
- public uint ulRawButtons;
- public int lLastX;
- public int lLastY;
- public uint ulExtraInformation;
-
- [Flags]
- public enum MOUSE_FLAGS : ushort
- {
- MOVE_RELATIVE = 0,
- MOVE_ABSOLUTE = 1,
- VIRTUAL_DESKTOP = 2,
- ATTRIBUTES_CHANGED = 4,
- MOVE_NOCOALESCE = 8,
- }
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RAWKEYBOARD
- {
- public ushort MakeCode;
- public RI_KEY Flags;
- public ushort Reserved;
- public VirtualKey VKey;
- public uint Message;
- public uint ExtraInformation;
-
- [Flags]
- public enum RI_KEY : ushort
- {
- MAKE = 0,
- BREAK = 1,
- E0 = 2,
- E1 = 4,
- }
+ public const uint MOUSE = 0;
+ public const uint KEYBOARD = 1;
+ public const uint HID = 2;
}
- [StructLayout(LayoutKind.Sequential)]
- public struct RAWHID
+ public static class RI_KEY
{
- public uint dwSizeHid;
- public uint dwCount;
- public byte bRawData;
+ public const ushort MAKE = 0;
+ public const ushort BREAK = 1;
+ public const ushort E0 = 2;
+ public const ushort E1 = 4;
}
-
- [StructLayout(LayoutKind.Explicit)]
- public struct RAWINPUTDATA
- {
- [FieldOffset(0)]
- public RAWMOUSE mouse;
- [FieldOffset(0)]
- public RAWKEYBOARD keyboard;
- [FieldOffset(0)]
- public RAWHID hid;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RAWINPUT
- {
- public RAWINPUTHEADER header;
- public RAWINPUTDATA data;
- }
-
- [DllImport("user32.dll", ExactSpelling = true)]
- public static extern int GetRawInputData(IntPtr hRawInput, RID uiCommand, IntPtr pData, out int bSize, int cbSizeHeader);
-
- [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", ExactSpelling = true, SetLastError = true)]
- public static extern unsafe int GetRawInputBuffer(RAWINPUT* pData, ref int bSize, int cbSizeHeader);
-
- [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern unsafe bool RegisterRawInputDevices(RAWINPUTDEVICE* pRawInputDevice, uint uiNumDevices, int cbSize);
-
- [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, int cbSize);
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static extern uint MapVirtualKeyW(uint uCode, uint uMapType);
}
}
diff --git a/src/BizHawk.Common/Win32/Shell32Imports.cs b/src/BizHawk.Common/Win32/Shell32Imports.cs
deleted file mode 100644
index 676a08d00b6..00000000000
--- a/src/BizHawk.Common/Win32/Shell32Imports.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-#nullable disable
-
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
-// ReSharper disable UnusedMember.Global
-
-namespace BizHawk.Common
-{
- public static class Shell32Imports
- {
- public const int BFFM_INITIALIZED = 1;
- public const int BFFM_SETSELECTIONW = 0x400 + 103;
-
- [UnmanagedFunctionPointer(CallingConvention.Winapi)]
- public delegate int BFFCALLBACK(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData);
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct BROWSEINFOW
- {
- public IntPtr hwndOwner;
- public IntPtr pidlRoot;
- public IntPtr pszDisplayName;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string lpszTitle;
- public FLAGS ulFlags;
- [MarshalAs(UnmanagedType.FunctionPtr)]
- public BFFCALLBACK lpfn;
- public IntPtr lParam;
- public int iImage;
-
- [Flags]
- public enum FLAGS
- {
- /// BIF_RETURNONLYFSDIRS
- RestrictToFilesystem = 0x0001,
-
- /// BIF_DONTGOBELOWDOMAIN
- RestrictToDomain = 0x0002,
-
- /// BIF_RETURNFSANCESTORS
- RestrictToSubfolders = 0x0008,
-
- /// BIF_EDITBOX
- ShowTextBox = 0x0010,
-
- /// BIF_VALIDATE
- ValidateSelection = 0x0020,
-
- /// BIF_NEWDIALOGSTYLE
- NewDialogStyle = 0x0040,
-
- /// BIF_BROWSEFORCOMPUTER
- BrowseForComputer = 0x1000,
-
- /// BIF_BROWSEFORPRINTER
- BrowseForPrinter = 0x2000,
-
- /// BIF_BROWSEINCLUDEFILES
- BrowseForEverything = 0x4000,
- }
- }
-
- [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static extern IntPtr SHBrowseForFolderW(ref BROWSEINFOW bi);
-
- [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static extern int SHGetPathFromIDListW(IntPtr pidl, char[] pszPath);
-
- [DllImport("shell32.dll", ExactSpelling = true)]
- public static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, out IntPtr ppidl);
-
- [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static extern int SHCreateItemFromParsingName(
- [In] string pszPath,
- [In] IntPtr pbc,
- [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
- out IntPtr ppv);
-
- [DllImport("shell32.dll", ExactSpelling = true)]
- public static extern int SHGetIDListFromObject(IntPtr punk, out IntPtr ppidl);
-
- [DllImport("shell32.dll", EntryPoint = "#16")]
- public static extern IntPtr ILFindLastID(IntPtr pidl);
- }
-}
diff --git a/src/BizHawk.Common/Win32/ShellLinkImports.cs b/src/BizHawk.Common/Win32/ShellLinkImports.cs
deleted file mode 100644
index 797f899b88d..00000000000
--- a/src/BizHawk.Common/Win32/ShellLinkImports.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-#nullable disable
-#pragma warning disable BHI1300 // explicit conversion operators w/ no checked variant
-
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
-// ReSharper disable UnusedMember.Global
-
-namespace BizHawk.Common
-{
- public static class ShellLinkImports
- {
- /// The IShellLink interface allows Shell links to be created, modified, and resolved
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct IShellLinkW
- {
- public static readonly Guid Guid = new("000214F9-0000-0000-C000-000000000046");
-
- [StructLayout(LayoutKind.Sequential)]
- public struct IShellLinkWVtbl
- {
- // IUnknown functions
- public delegate* unmanaged[Stdcall] QueryInterface;
- public delegate* unmanaged[Stdcall] AddRef;
- public delegate* unmanaged[Stdcall] Release;
- // IShellLinkW functions
- public delegate* unmanaged[Stdcall] GetPath;
- public delegate* unmanaged[Stdcall] GetIDList;
- public delegate* unmanaged[Stdcall] SetIDList;
- public delegate* unmanaged[Stdcall] GetDescription;
- public delegate* unmanaged[Stdcall] SetDescription;
- public delegate* unmanaged[Stdcall] GetWorkingDirectory;
- public delegate* unmanaged[Stdcall] SetWorkingDirectory;
- public delegate* unmanaged[Stdcall] GetArguments;
- public delegate* unmanaged[Stdcall] SetArguments;
- public delegate* unmanaged[Stdcall] GetHotkey;
- public delegate* unmanaged[Stdcall] SetHotkey;
- public delegate* unmanaged[Stdcall] GetShowCmd;
- public delegate* unmanaged[Stdcall] SetShowCmd;
- public delegate* unmanaged[Stdcall] GetIconLocation;
- public delegate* unmanaged[Stdcall] SetIconLocation;
- public delegate* unmanaged[Stdcall] SetRelativePath;
- public delegate* unmanaged[Stdcall] Resolve;
- public delegate* unmanaged[Stdcall] SetPath;
- }
-
- public IShellLinkWVtbl* lpVtbl;
-
- public void GetPath(out string pszFile, int cch, uint fFlags)
- {
- var _pszFile = Marshal.AllocCoTaskMem(cch * sizeof(char));
- try
- {
- var hr = lpVtbl->GetPath((IShellLinkW*)Unsafe.AsPointer(ref this), _pszFile, cch, IntPtr.Zero, fFlags);
- Marshal.ThrowExceptionForHR(hr);
- pszFile = Marshal.PtrToStringUni(_pszFile);
- }
- finally
- {
- Marshal.FreeCoTaskMem(_pszFile);
- }
- }
-
-#if false
- public void Resolve(IntPtr hwnd, int fFlags)
- {
- var hr = lpVtbl->Resolve((IShellLinkW*)Unsafe.AsPointer(ref this), hwnd, fFlags);
- Marshal.ThrowExceptionForHR(hr);
- }
-#endif
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct IPersistFile
- {
- public static readonly Guid Guid = new("0000010b-0000-0000-C000-000000000046");
-
- [StructLayout(LayoutKind.Sequential)]
- public struct IPersistFileVtbl
- {
- // IUnknown functions
- public delegate* unmanaged[Stdcall] QueryInterface;
- public delegate* unmanaged[Stdcall] AddRef;
- public delegate* unmanaged[Stdcall] Release;
- // IPersist functions
- public delegate* unmanaged[Stdcall] GetClassID;
- // IPersistFile functions
- public delegate* unmanaged[Stdcall] IsDirty;
- public delegate* unmanaged[Stdcall] Load;
- public delegate* unmanaged[Stdcall] Save;
- public delegate* unmanaged[Stdcall] SaveCompleted;
- public delegate* unmanaged[Stdcall] GetCurFile;
- }
-
- public IPersistFileVtbl* lpVtbl;
-
- public void Load(string pszFileName, uint dwMode)
- {
- var _pszFileName = Marshal.StringToCoTaskMemUni(pszFileName);
- try
- {
- var hr = lpVtbl->Load((IPersistFile*)Unsafe.AsPointer(ref this), _pszFileName, dwMode);
- Marshal.ThrowExceptionForHR(hr);
- }
- finally
- {
- Marshal.FreeCoTaskMem(_pszFileName);
- }
- }
- }
-
- /// CLSID_ShellLink from ShlGuid.h
- public unsafe class ShellLink : IDisposable
- {
- public static readonly Guid Guid = new("00021401-0000-0000-C000-000000000046");
- public static explicit operator IShellLinkW*(ShellLink link) => link.SLI;
- public static explicit operator IPersistFile*(ShellLink link) => link.PFI;
-
- 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 IPersistFile.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;
- }
- }
- }
- }
-}
diff --git a/src/BizHawk.Common/Win32/Win32Imports.cs b/src/BizHawk.Common/Win32/Win32Imports.cs
deleted file mode 100644
index 7bdc80a4961..00000000000
--- a/src/BizHawk.Common/Win32/Win32Imports.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-#nullable disable
-
-using System.IO;
-using System.Runtime.InteropServices;
-
-// ReSharper disable UnusedMember.Global
-
-#pragma warning disable CA1069 // This warning is just dumb
-
-namespace BizHawk.Common
-{
- ///
- /// This is more just an assorted bunch of Win32 functions
- ///
- public static class Win32Imports
- {
- public const int MAX_PATH = 260;
-
- [Flags]
- public enum TPM
- {
- LEFTBUTTON = 0x0000,
- RIGHTBUTTON = 0x0002,
- LEFTALIGN = 0x0000,
- CENTERALIGN = 0x000,
- RIGHTALIGN = 0x000,
- TOPALIGN = 0x0000,
- VCENTERALIGN = 0x0010,
- BOTTOMALIGN = 0x0020,
- HORIZONTAL = 0x0000,
- VERTICAL = 0x0040,
- NONOTIFY = 0x0080,
- RETURNCMD = 0x0100,
- RECURSE = 0x0001,
- HORPOSANIMATION = 0x0400,
- HORNEGANIMATION = 0x0800,
- VERPOSANIMATION = 0x1000,
- VERNEGANIMATION = 0x2000,
- NOANIMATION = 0x4000,
- LAYOUTRTL = 0x8000,
- }
-
- [DllImport("user32.dll", ExactSpelling = true)]
- public static extern IntPtr CreatePopupMenu();
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern bool DeleteFileW(string lpFileName);
-
- [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool DestroyMenu(IntPtr hMenu);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static extern unsafe int FormatMessageW(int flags, IntPtr source, uint messageId, uint languageId, char* outMsg, int size, IntPtr args);
-
- [DllImport("kernel32.dll", ExactSpelling = true)]
- public static extern uint GetLastError();
-
- [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.Unicode, ExactSpelling = true)]
- public static extern bool SystemParametersInfoW(int uAction, int uParam, ref int lpvParam, int flags);
-
- [DllImport("winmm.dll", ExactSpelling = true)]
- public static extern uint timeBeginPeriod(uint uMilliseconds);
-
- [DllImport("user32.dll", ExactSpelling = true)]
- public static extern int TrackPopupMenuEx(IntPtr hmenu, TPM fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm);
-
- [DllImport("kernel32.dll", ExactSpelling = true)]
- public static extern IntPtr GetCurrentProcess();
-
- [DllImport("kernel32.dll", ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsWow64Process(IntPtr hProcess, [MarshalAs(UnmanagedType.Bool)] out bool Wow64Process);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool SetDllDirectoryW(string lpPathName);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern int GetShortPathNameW(string lpszLongPath, char[] lpszShortPath, int cchBuffer);
- }
-}
\ No newline at end of file
diff --git a/src/BizHawk.Common/Win32/Win32ShellContextMenu.cs b/src/BizHawk.Common/Win32/Win32ShellContextMenu.cs
index 18c0183a918..1f0c625b909 100644
--- a/src/BizHawk.Common/Win32/Win32ShellContextMenu.cs
+++ b/src/BizHawk.Common/Win32/Win32ShellContextMenu.cs
@@ -1,168 +1,25 @@
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// ReSharper disable UnusedMember.Local
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Shell;
+using Windows.Win32.UI.Shell.Common;
+using Windows.Win32.UI.WindowsAndMessaging;
namespace BizHawk.Common
{
public unsafe class Win32ShellContextMenu : IDisposable
{
- [StructLayout(LayoutKind.Sequential)]
- private struct IShellItem
- {
- public static readonly Guid Guid = new("43826d1e-e718-42ee-bc55-a1e261c37bfe");
-
- [StructLayout(LayoutKind.Sequential)]
- public struct IShellItemVtbl
- {
- // IUnknown functions
- public delegate* unmanaged[Stdcall] QueryInterface;
- public delegate* unmanaged[Stdcall] AddRef;
- public delegate* unmanaged[Stdcall] Release;
- // IShellItem functions
- public delegate* unmanaged[Stdcall] BindToHandler;
- public delegate* unmanaged[Stdcall] GetParent;
- public delegate* unmanaged[Stdcall] GetDisplayName;
- public delegate* unmanaged[Stdcall] GetAttributes;
- public delegate* unmanaged[Stdcall] Compare;
- }
-
- public IShellItemVtbl* lpVtbl;
-
- public void BindToHandler(IntPtr pbc, Guid bhid, Guid riid, out IntPtr ppv)
- {
- var hr = lpVtbl->BindToHandler((IShellItem*)Unsafe.AsPointer(ref this), pbc, in bhid, in riid, out ppv);
- Marshal.ThrowExceptionForHR(hr);
- }
-
- public void GetParent(out IShellItem* ppsi)
- {
- var hr = lpVtbl->GetParent((IShellItem*)Unsafe.AsPointer(ref this), out ppsi);
- Marshal.ThrowExceptionForHR(hr);
- }
- }
+ private IContextMenu? CMI;
+ private IContextMenu2? CM2I;
- [StructLayout(LayoutKind.Sequential)]
- private struct IShellFolder
- {
- public static readonly Guid Guid = new("000214E6-0000-0000-C000-000000000046");
+ private static readonly Guid GUID_ICONTEXTMENU = new("000214E4-0000-0000-C000-000000000046");
- [StructLayout(LayoutKind.Sequential)]
- public struct IShellFolderVtbl
- {
- // IUnknown functions
- public delegate* unmanaged[Stdcall] QueryInterface;
- public delegate* unmanaged[Stdcall] AddRef;
- public delegate* unmanaged[Stdcall] Release;
- // IShellFolder functions
- public delegate* unmanaged[Stdcall] ParseDisplayName;
- public delegate* unmanaged[Stdcall] EnumObjects;
- public delegate* unmanaged[Stdcall] BindToObject;
- public delegate* unmanaged[Stdcall] BindToStorage;
- public delegate* unmanaged[Stdcall] CompareIDs;
- public delegate* unmanaged[Stdcall] CreateViewObject;
- public delegate* unmanaged[Stdcall] GetAttributesOf;
- public delegate* unmanaged[Stdcall] GetUIObjectOf;
- public delegate* unmanaged[Stdcall] GetDisplayNameOf;
- public delegate* unmanaged[Stdcall] SetNameOf;
- }
+ private static readonly Guid GUID_ICONTEXTMENU2 = new("000214F4-0000-0000-C000-000000000046");
- public IShellFolderVtbl* lpVtbl;
+ private static readonly Guid GUID_ISHELLFOLDER = new("000214E6-0000-0000-C000-000000000046");
- public void GetUIObjectOf(IntPtr hwndOwner, uint cidl, IntPtr* apidl, Guid riid, out IntPtr ppv)
- {
- var hr = lpVtbl->GetUIObjectOf((IShellFolder*)Unsafe.AsPointer(ref this), hwndOwner, cidl, apidl, in riid, null, out ppv);
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct IContextMenu
- {
- public static readonly Guid Guid = new("000214e4-0000-0000-c000-000000000046");
-
- [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)]
- public struct CMINVOKECOMMANDINFO
- {
- public uint cbSize;
- public uint fMask;
- public IntPtr hwnd;
- public IntPtr lpVerb;
- public IntPtr lpParameters;
- public IntPtr lpDirectory;
- public int nShow;
- public uint dwHotKey;
- public IntPtr hIcon;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct IContextMenuVtbl
- {
- // IUnknown functions
- public delegate* unmanaged[Stdcall] QueryInterface;
- public delegate* unmanaged[Stdcall] AddRef;
- public delegate* unmanaged[Stdcall] Release;
- // IContextMenu functions
- public delegate* unmanaged[Stdcall] QueryContextMenu;
- public delegate* unmanaged[Stdcall] InvokeCommand;
- public delegate* unmanaged[Stdcall] GetCommandString;
- }
-
- public IContextMenuVtbl* lpVtbl;
-
- public void QueryContextMenu(IntPtr hmenu, uint indexMenu, uint idCmdFirst, uint idCmdLast, CMF uFlags)
- {
- var hr = lpVtbl->QueryContextMenu((IContextMenu*)Unsafe.AsPointer(ref this), hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct IContextMenu2
- {
- public static readonly Guid Guid = new("000214f4-0000-0000-c000-000000000046");
-
- [StructLayout(LayoutKind.Sequential)]
- public struct IContextMenu2Vtbl
- {
- // IUnknown functions
- public delegate* unmanaged[Stdcall] QueryInterface;
- public delegate* unmanaged[Stdcall] AddRef;
- public delegate* unmanaged[Stdcall] Release;
- // IContextMenu functions
- public delegate* unmanaged[Stdcall] QueryContextMenu;
- public delegate* unmanaged[Stdcall] InvokeCommand;
- public delegate* unmanaged[Stdcall] GetCommandString;
- // IContextMenu2 functions
- public delegate* unmanaged[Stdcall] HandleMenuMsg;
- }
-
- public IContextMenu2Vtbl* lpVtbl;
-
- public void InvokeCommand(IContextMenu.CMINVOKECOMMANDINFO* pici)
- {
- var hr = lpVtbl->InvokeCommand((IContextMenu2*)Unsafe.AsPointer(ref this), pici);
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- private IContextMenu* CMI;
- private IContextMenu2* CM2I;
+ private static readonly Guid GUID_ISHELLITEM = new("43826D1E-E718-42EE-BC55-A1E261C37BFE");
private static readonly Guid SFObject = new("3981e224-f559-11d3-8e3a-00c04f6837d5");
@@ -176,56 +33,57 @@ private Win32ShellContextMenu(string path)
throw new NotSupportedException("Non-file Uri schemes are unsupported");
}
- var hr = Shell32Imports.SHCreateItemFromParsingName(uri.LocalPath, IntPtr.Zero, IShellItem.Guid, out var psi);
+ var hr = Shell32Imports.SHCreateItemFromParsingName(uri.LocalPath, default, in GUID_ISHELLITEM, out var psi);
Marshal.ThrowExceptionForHR(hr);
- var sii = (IShellItem*)psi;
+ var sii = (IShellItem) psi;
- IntPtr pidls;
- IShellItem* psii;
+ ITEMIDLIST* pidls;
+ IShellItem psii;
try
{
hr = Shell32Imports.SHGetIDListFromObject(psi, out var ppidl);
Marshal.ThrowExceptionForHR(hr);
pidls = Shell32Imports.ILFindLastID(ppidl);
- sii->GetParent(out psii);
+ sii.GetParent(out psii);
}
finally
{
- sii->lpVtbl->Release(sii);
+// sii.Release(sii);
}
- IShellFolder* sfi;
+ IShellFolder sfi;
try
{
- psii->BindToHandler(IntPtr.Zero, SFObject, IShellFolder.Guid, out var psf);
- sfi = (IShellFolder*)psf;
+ psii.BindToHandler(default, in SFObject, in GUID_ISHELLFOLDER, out var psf);
+ sfi = (IShellFolder) psf;
}
finally
{
- psii->lpVtbl->Release(psii);
+// psii.Release(psii);
}
- IContextMenu* cmi;
+ IContextMenu cmi;
try
{
- sfi->GetUIObjectOf(IntPtr.Zero, 1, &pidls, IContextMenu.Guid, out var pcm);
- cmi = (IContextMenu*)pcm;
+ sfi.GetUIObjectOf(HWND.Null, cidl: 1, &pidls, in GUID_ICONTEXTMENU, out var pcm);
+ cmi = (IContextMenu) pcm;
}
finally
{
- sfi->lpVtbl->Release(sfi);
+// sfi.Release(sfi);
}
- IContextMenu2* cm2i;
+ IContextMenu2 cm2i;
try
{
- cmi->lpVtbl->QueryInterface(cmi, in IContextMenu2.Guid, out var pcm2);
- cm2i = (IContextMenu2*)pcm2;
+// cmi.QueryInterface(cmi, in GUID_ICONTEXTMENU2, out var pcm2);
+ var pcm2 = cmi;
+ cm2i = (IContextMenu2) pcm2;
}
catch
{
- cmi->lpVtbl->Release(cmi);
+// cmi.Release(cmi);
throw;
}
@@ -237,25 +95,25 @@ public void Dispose()
{
if (CM2I != null)
{
- CM2I->lpVtbl->Release(CM2I);
+// CM2I.Release(CM2I);
CM2I = null;
}
if (CMI != null)
{
- CMI->lpVtbl->Release(CMI);
+// CMI.Release(CMI);
CMI = null;
}
}
private ref struct TempMenu
{
- public IntPtr Handle { get; private set; }
+ public HMENU Handle { get; private set; }
public TempMenu()
{
Handle = Win32Imports.CreatePopupMenu();
- if (Handle == IntPtr.Zero)
+ if (Handle.IsNull)
{
throw new InvalidOperationException($"{nameof(Win32Imports.CreatePopupMenu)} returned NULL!");
}
@@ -263,10 +121,10 @@ public TempMenu()
public void Dispose()
{
- if (Handle != IntPtr.Zero)
+ if (!Handle.IsNull)
{
_ = Win32Imports.DestroyMenu(Handle);
- Handle = IntPtr.Zero;
+ Handle = HMENU.Null;
}
}
}
@@ -277,17 +135,23 @@ public static void ShowContextMenu(string path, IntPtr parentWindow, int x, int
using var menu = new TempMenu();
const int CmdFirst = 0x8000;
- ctxMenu.CMI->QueryContextMenu(menu.Handle, 0, CmdFirst, uint.MaxValue, IContextMenu.CMF.EXPLORE);
-
- var command = Win32Imports.TrackPopupMenuEx(menu.Handle, Win32Imports.TPM.RETURNCMD, x, y, parentWindow, IntPtr.Zero);
+ ctxMenu.CMI!.QueryContextMenu(menu.Handle, 0, CmdFirst, uint.MaxValue, Win32Imports.CMF_EXPLORE);
+
+ var command = Win32Imports.TrackPopupMenuEx(
+ menu.Handle,
+ TPMFLAGS.RETURNCMD,
+ x: x,
+ y: y,
+ new(parentWindow),
+ lptpm: default).Value;
if (command > 0)
{
const int SW_SHOWNORMAL = 1;
- IContextMenu.CMINVOKECOMMANDINFO invoke = default;
- invoke.cbSize = (uint)Marshal.SizeOf();
- invoke.lpVerb = new(command - CmdFirst);
+ CMINVOKECOMMANDINFO invoke = default;
+ invoke.cbSize = (uint)Marshal.SizeOf();
+ invoke.lpVerb = new(unchecked((byte*) (IntPtr) (command - CmdFirst)));
invoke.nShow = SW_SHOWNORMAL;
- ctxMenu.CM2I->InvokeCommand(&invoke);
+ ctxMenu.CM2I!.InvokeCommand(&invoke);
}
}
}
diff --git a/src/BizHawk.Common/Win32/WmImports.cs b/src/BizHawk.Common/Win32/WmImports.cs
index 9ddb1f45898..41245704b39 100644
--- a/src/BizHawk.Common/Win32/WmImports.cs
+++ b/src/BizHawk.Common/Win32/WmImports.cs
@@ -1,99 +1,15 @@
-#nullable disable
+using System.Runtime.InteropServices;
-using System.Runtime.InteropServices;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Global
+using Windows.Win32.UI.WindowsAndMessaging;
namespace BizHawk.Common
{
- public static class WmImports
+ public static class WmImports1
{
- public const uint PM_REMOVE = 0x0001U;
- public static readonly IntPtr HWND_MESSAGE = new(-3);
- public const int GWLP_USERDATA = -21;
-
- public enum ChangeWindowMessageFilterFlags : uint
- {
- Add = 1,
- Remove = 2,
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct MSG
- {
- public IntPtr hwnd;
- public uint message;
- public IntPtr wParam;
- public IntPtr lParam;
- 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.Unicode)]
- public struct WNDCLASSW
- {
- public uint style;
- public WNDPROC lpfnWndProc;
- public int cbClsExtra;
- public int cbWndExtra;
- public IntPtr hInstance;
- public IntPtr hIcon;
- public IntPtr hCursor;
- public IntPtr hbrBackground;
- public string lpszMenuName;
- public string lpszClassName;
- }
-
- [DllImport("user32.dll", ExactSpelling = true)]
- public static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags);
-
- [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.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr DefWindowProcW(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
-
- [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool DestroyWindow(IntPtr hWnd);
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr DispatchMessageW([In] ref MSG lpMsg);
-
- [DllImport("user32.dll", ExactSpelling = true)]
- public static extern IntPtr GetActiveWindow();
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr GetWindowLongPtrW(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll", ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool HideCaret(IntPtr hWnd);
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool PeekMessageW(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
-
- [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.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr RegisterClassW([In] ref WNDCLASSW lpWndClass);
-
- [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.Unicode, ExactSpelling = true, SetLastError = true)]
- public static extern IntPtr SetWindowLongPtrW(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
+ public static extern IntPtr GetWindowLongPtrW(IntPtr hWnd, WINDOW_LONG_PTR_INDEX nIndex);
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool TranslateMessage([In] ref MSG lpMsg);
+ public static extern IntPtr SetWindowLongPtrW(IntPtr hWnd, WINDOW_LONG_PTR_INDEX nIndex, IntPtr dwNewLong);
}
}
diff --git a/src/MainSlnCommon.props b/src/MainSlnCommon.props
index 1ea37b15590..73dc582f8e2 100644
--- a/src/MainSlnCommon.props
+++ b/src/MainSlnCommon.props
@@ -23,6 +23,9 @@
+
+
+