Change into LibraryImport

This commit is contained in:
Qusay Diaz
2026-06-29 12:44:09 +08:00
parent 246e09f17e
commit c762df53b3
2 changed files with 127 additions and 104 deletions
+81 -82
View File
@@ -10,116 +10,102 @@ namespace FluentAvalonia.Interop;
internal static unsafe partial class Win32Interop
{
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL GetWindowRect(HWND hWnd, RECT* lpRect);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL GetWindowRect(HWND hWnd, RECT* lpRect);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL GetClientRect(HWND hWnd, RECT* lpRect);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL GetClientRect(HWND hWnd, RECT* lpRect);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL AdjustWindowRectEx(RECT* lpRect, uint dwStyle, BOOL bMenu, uint dwExStyle);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL AdjustWindowRectExForDpi(RECT* lpRect, int dwStyle, BOOL bMenu, int dwExStyle, int dpi);
[DllImport(s_user32, SetLastError = true)]
private static extern int GetSystemMetrics(int smIndex);
// Re-introduced SystemMetrics P/Invokes used by fallbacks
[LibraryImport(s_user32, SetLastError = true)]
private static partial int GetSystemMetrics(int smIndex);
[DllImport(s_user32, SetLastError = true)]
private static extern int GetSystemMetricsForDpi(int nIndex, uint dpi);
[LibraryImport(s_user32, SetLastError = true)]
private static partial int GetSystemMetricsForDpi(int nIndex, uint dpi);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
[DllImport(s_user32, SetLastError = true)]
private static extern BOOL AdjustWindowRectExForDpi(RECT* lpRect, int dwStyle, BOOL bMenu, int dwExStyle, int dpi);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
[DllImport(s_user32, SetLastError = true)]
private static extern bool AdjustWindowRectEx(RECT* lpRect, int dwStyle, bool bMenu, int dwExStyle);
// Non-DPI AdjustWindowRectEx used by fallback
[LibraryImport(s_user32, SetLastError = true)]
private static partial BOOL AdjustWindowRectEx(RECT* lpRect, int dwStyle, BOOL bMenu, int dwExStyle);
[DllImport(s_user32, SetLastError = true)]
public static extern LRESULT DefWindowProcW(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
[LibraryImport(s_user32, SetLastError = true)]
public static partial LRESULT DefWindowProcW(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
[DllImport(s_user32, SetLastError = true)]
public static extern LRESULT CallWindowProcW(nint lpPrevWndProc, HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
[LibraryImport(s_user32, SetLastError = true)]
public static partial LRESULT CallWindowProcW(nint lpPrevWndProc, HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL PostMessage(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL PostMessage(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
[LibraryImport(s_user32, SetLastError = true)]
public static partial HMENU GetSystemMenu(HWND hWnd, BOOL bRevert);
[DllImport(s_user32, SetLastError = true)]
public static extern HMENU GetSystemMenu(HWND hWnd, BOOL bRevert);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL SetMenuItemInfo(HMENU hMenu, uint item, BOOL fByPosition, MENUITEMINFO* lpmii);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL SetMenuItemInfo(HMENU hMenu, uint item, bool fByPosition, MENUITEMINFO* lpmii);
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL SetMenuDefaultItem(HMENU hMenu, uint uItem, uint fByPos);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL SetMenuDefaultItem(HMENU hMenu, uint uItem, uint fByPos);
[DllImport(s_user32, SetLastError = true)]
public static extern BOOL TrackPopupMenu(HMENU hMenu, uint uFlags,
[LibraryImport(s_user32, SetLastError = true)]
public static partial BOOL TrackPopupMenu(HMENU hMenu, uint uFlags,
int x, int y, int nReserved, HWND hWnd, RECT* prcRect);
[DllImport(s_user32)]
public static extern int GetWindowLongW(HWND hWnd, int nIndex);
[LibraryImport(s_user32)]
public static partial int GetWindowLongW(HWND hWnd, int nIndex);
[DllImport(s_user32)]
public static extern int SetWindowLongW(HWND hWnd, int nIndex, int dwNewLong);
[LibraryImport(s_user32)]
public static partial int SetWindowLongW(HWND hWnd, int nIndex, int dwNewLong);
// Below is adapted from TerraFX.Interop.Windows, MIT License
public static delegate*<HWND, int, nint> GetWindowLongPtr => &GetWindowLongPtrW;
// Top-level native entry points for pointer-sized window long APIs (no local/libraryimport inside methods)
[LibraryImport(s_user32, EntryPoint = "GetWindowLongPtrW")]
private static partial nint GetWindowLongPtrW_native(HWND hWnd, int nIndex);
public static int GetSystemMetricsWithFallback(int nIndex, uint dpi)
{
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 14393)) // 1607
return GetSystemMetricsForDpi(nIndex, dpi);
return GetSystemMetrics(nIndex);
}
[LibraryImport(s_user32, EntryPoint = "SetWindowLongPtrW")]
private static partial nint SetWindowLongPtrW_native(HWND hWnd, int nIndex, nint dwNewLong);
public static void AdjustWindowRectExWithFallback(RECT* lpRect, int dwStyle, BOOL bMenu, int dwExStyle, int dpi)
{
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 14393)) // 1607
{
AdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
return;
}
AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
}
// Public wrappers that choose the correct function depending on process bitness
public static nint GetWindowLongPtr(HWND hWnd, int nIndex) => GetWindowLongPtrW(hWnd, nIndex);
public static nint GetWindowLongPtrW(HWND hWnd, int nIndex)
{
if (sizeof(nint) == 4)
{
// 32-bit process -> use GetWindowLong
return GetWindowLongW(hWnd, nIndex);
}
else
{
[DllImport(s_user32, EntryPoint = "GetWindowLongPtrW")]
static extern nint _GetWindowLongPtrW(HWND hWnd, int nIndex);
return _GetWindowLongPtrW(hWnd, nIndex);
// 64-bit process -> call native GetWindowLongPtrW
return GetWindowLongPtrW_native(hWnd, nIndex);
}
}
public static delegate*<HWND, int, nint, nint> SetWindowLongPtr => &SetWindowLongPtrW;
public static nint SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong) => SetWindowLongPtrW(hWnd, nIndex, dwNewLong);
public static nint SetWindowLongPtrW(HWND hWnd, int nIndex, nint dwNewLong)
{
if (sizeof(nint) == 4)
{
// 32-bit process -> use SetWindowLong
return SetWindowLongW(hWnd, nIndex, (int)dwNewLong);
}
else
{
[DllImport(s_user32, EntryPoint = "SetWindowLongPtrW")]
static extern nint _SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong);
return _SetWindowLongPtr(hWnd, nIndex, dwNewLong);
// 64-bit process -> call native SetWindowLongPtrW
return SetWindowLongPtrW_native(hWnd, nIndex, dwNewLong);
}
}
[DllImport(s_dwmapi, SetLastError = true)]
public static extern HRESULT DwmExtendFrameIntoClientArea(HWND hWnd, MARGINS* margins);
[LibraryImport(s_dwmapi, SetLastError = true)]
public static partial HRESULT DwmExtendFrameIntoClientArea(HWND hWnd, MARGINS* margins);
[DllImport(s_ole32, ExactSpelling = true)]
public static extern HRESULT CoCreateInstance(Guid* rclsid, void* pUnkOuter,
[LibraryImport(s_ole32)]
public static partial HRESULT CoCreateInstance(Guid* rclsid, void* pUnkOuter,
int dwClsContext, Guid* riid, void** ppv);
internal unsafe static T CreateInstance<T>(Guid clsid, Guid iid) where T : IUnknown
@@ -134,28 +120,41 @@ internal static unsafe partial class Win32Interop
return MicroComRuntime.QueryInterface<T>(unk);
}
[LibraryImport(s_dwmapi, SetLastError = true)]
public static partial int DwmSetWindowAttribute(nint hWnd, DWMWINDOWATTRIBUTE attr, void* value, int attrSize);
[DllImport(s_dwmapi, SetLastError = true)]
public static extern int DwmSetWindowAttribute(nint hWnd, DWMWINDOWATTRIBUTE attr, void* value, int attrSize);
[LibraryImport(s_user32, SetLastError = true)]
public static unsafe partial int SetWindowCompositionAttribute(IntPtr hwnd, WINDOWCOMPOSITIONATTRIBDATA* data);
[LibraryImport(s_uxtheme, EntryPoint = "#104", SetLastError = true)]
public static partial void fnRefreshImmersiveColorPolicyState();
[DllImport(s_user32, SetLastError = true)]
public static unsafe extern int SetWindowCompositionAttribute(IntPtr hwnd, WINDOWCOMPOSITIONATTRIBDATA* data);
[DllImport(s_uxtheme, EntryPoint = "#104", SetLastError = true)]
public static extern void fnRefreshImmersiveColorPolicyState();
[DllImport(s_uxtheme, EntryPoint = "#135", SetLastError = true)]
public static extern PreferredAppMode fnSetPreferredAppMode(IntPtr hwnd, PreferredAppMode appMode);
[DllImport(s_uxtheme, EntryPoint = "#135")]
public static extern bool fnAllowDarkModeForApp(IntPtr hwnd, bool allow);
[LibraryImport(s_uxtheme, EntryPoint = "#135", SetLastError = true)]
public static partial PreferredAppMode fnSetPreferredAppMode(IntPtr hwnd, PreferredAppMode appMode);
[LibraryImport(s_uxtheme, EntryPoint = "#135")]
public static partial BOOL fnAllowDarkModeForApp(IntPtr hwnd, BOOL allow);
[SecurityCritical]
[DllImport(s_ntdll, SetLastError = true, CharSet = CharSet.Unicode)]
internal static unsafe extern int RtlGetVersion(OSVERSIONINFOEX* versionInfo);
[LibraryImport(s_ntdll, SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
internal static unsafe partial int RtlGetVersion(OSVERSIONINFOEX* versionInfo);
public static int GetSystemMetricsWithFallback(int nIndex, uint dpi)
{
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 14393)) // 1607
return GetSystemMetricsForDpi(nIndex, dpi);
return GetSystemMetrics(nIndex);
}
public static void AdjustWindowRectExWithFallback(RECT* lpRect, int dwStyle, BOOL bMenu, int dwExStyle, int dpi)
{
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 14393)) // 1607
{
AdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
return;
}
AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
}
public static bool ApplyTheme(IntPtr hwnd, bool useDark)
{
@@ -1,20 +1,24 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using FluentAvalonia.Interop.Win32;
using MicroCom.Runtime;
namespace FluentAvalonia.Interop.WinRT;
internal static class WinRTInterop
internal static partial class WinRTInterop
{
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall,
PreserveSig = false)]
internal static extern unsafe IntPtr WindowsCreateString(
[LibraryImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
internal static partial int WindowsCreateString(
[MarshalAs(UnmanagedType.LPWStr)] string sourceString,
int length);
uint length,
out IntPtr hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
internal static extern unsafe char* WindowsGetStringRawBuffer(IntPtr hstring, uint* length);
[LibraryImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
internal static unsafe partial char* WindowsGetStringRawBuffer(IntPtr hstring, uint* length);
internal static unsafe string GetString(IntPtr hString)
{
@@ -23,22 +27,37 @@ internal static class WinRTInterop
return new string(buffer, 0, (int)length);
}
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall,
PreserveSig = false)]
internal static extern unsafe bool WindowsIsStringEmpty(IntPtr @string);
[LibraryImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
internal static unsafe partial BOOL WindowsIsStringEmpty(IntPtr @string);
internal static IntPtr WindowsCreateString(string sourceString)
=> WindowsCreateString(sourceString, sourceString.Length);
{
if (sourceString is null)
throw new ArgumentNullException(nameof(sourceString));
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll",
CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
internal static extern unsafe IntPtr WindowsDeleteString(IntPtr hString);
IntPtr hstring;
int hr = WindowsCreateString(sourceString, (uint)sourceString.Length, out hstring);
if (hr < 0)
throw new InvalidOperationException($"WindowsCreateString failed with HRESULT: 0x{hr:X8}");
return hstring;
}
[LibraryImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
internal static unsafe partial void WindowsDeleteString(IntPtr hString);
internal static T CreateInstance<T>(string fullName) where T : IUnknown
{
var s = WindowsCreateString(fullName);
EnsureRoInitialized();
var pUnk = RoActivateInstance(s);
int hr = RoActivateInstance(s, out var pUnk);
if (hr < 0)
{
WindowsDeleteString(s);
throw new COMException("RoActivateInstance failed", hr);
}
using var unk = MicroComRuntime.CreateProxyFor<IUnknown>(pUnk, true);
WindowsDeleteString(s);
return MicroComRuntime.QueryInterface<T>(unk);
@@ -49,9 +68,11 @@ internal static class WinRTInterop
{
if (_initialized)
return;
RoInitialize(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA ?
int hr = RoInitialize(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA ?
RO_INIT_TYPE.RO_INIT_SINGLETHREADED :
RO_INIT_TYPE.RO_INIT_MULTITHREADED);
if (hr < 0)
throw new InvalidOperationException($"RoInitialize failed with HRESULT: 0x{hr:X8}");
_initialized = true;
}
@@ -61,12 +82,15 @@ internal static class WinRTInterop
RO_INIT_MULTITHREADED = 1, // COM calls objects on any thread.
}
[DllImport("combase.dll", PreserveSig = false)]
private static extern void RoInitialize(RO_INIT_TYPE initType);
[LibraryImport("combase.dll")]
private static partial int RoInitialize(RO_INIT_TYPE initType);
[DllImport("combase.dll", PreserveSig = false)]
private static extern IntPtr RoActivateInstance(IntPtr activatableClassId);
[LibraryImport("combase.dll")]
private static partial int RoActivateInstance(
IntPtr activatableClassId,
out IntPtr instance);
[DllImport("combase.dll", PreserveSig = false)]
private static extern IntPtr RoGetActivationFactory(IntPtr activatableClassId, ref Guid iid);
// Updated signature to return HRESULT and output the activation factory pointer
[LibraryImport("combase.dll")]
private static partial int RoGetActivationFactory(IntPtr activatableClassId, ref Guid iid, out IntPtr factory);
}