1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00

Windows - Use user32 APIs to manage windows for input provider and Vulkan

This commit is contained in:
Robert 2023-04-27 10:50:13 +02:00
parent c50a572363
commit ebe7f68e9d
5 changed files with 69 additions and 69 deletions

View File

@ -1,18 +0,0 @@
using System.Linq;
using Artemis.UI.Exceptions;
using Avalonia.Platform;
namespace Artemis.UI.Windows.Extensions;
public static class IWindowImplExtensions
{
public static IPlatformHandle GetHandle(this IWindowImpl window)
{
// This is unfortunate
IPlatformHandle? handle = (IPlatformHandle?) window.GetType().GetProperties().FirstOrDefault(p => p.Name == "Handle")?.GetValue(window);
if (handle == null)
throw new ArtemisUIException("Could not get IWindowImpl internal platform handle, Avalonia API change?");
return handle;
}
}

View File

@ -4,10 +4,7 @@ using System.Runtime.InteropServices;
using System.Timers; using System.Timers;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Windows.Extensions;
using Artemis.UI.Windows.Utilities; using Artemis.UI.Windows.Utilities;
using Avalonia.Controls.Platform;
using Avalonia.Platform;
using Linearstar.Windows.RawInput; using Linearstar.Windows.RawInput;
using Linearstar.Windows.RawInput.Native; using Linearstar.Windows.RawInput.Native;
using Serilog; using Serilog;
@ -19,7 +16,7 @@ public class WindowsInputProvider : InputProvider
private const int GWL_WNDPROC = -4; private const int GWL_WNDPROC = -4;
private const int WM_INPUT = 0x00FF; private const int WM_INPUT = 0x00FF;
private readonly IWindowImpl _window; private readonly nint _hWnd;
private readonly nint _hWndProcHook; private readonly nint _hWndProcHook;
private readonly WndProc? _fnWndProcHook; private readonly WndProc? _fnWndProcHook;
private readonly IInputService _inputService; private readonly IInputService _inputService;
@ -32,7 +29,7 @@ public class WindowsInputProvider : InputProvider
private nint CustomWndProc(nint hWnd, uint msg, nint wParam, nint lParam) private nint CustomWndProc(nint hWnd, uint msg, nint wParam, nint lParam)
{ {
OnWndProcCalled(hWnd, msg, wParam, lParam); OnWndProcCalled(hWnd, msg, wParam, lParam);
return CallWindowProc(_hWndProcHook, hWnd, msg, wParam, lParam); return User32.CallWindowProc(_hWndProcHook, hWnd, msg, wParam, lParam);
} }
public WindowsInputProvider(ILogger logger, IInputService inputService) public WindowsInputProvider(ILogger logger, IInputService inputService)
@ -44,16 +41,14 @@ public class WindowsInputProvider : InputProvider
_taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed; _taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed;
_taskManagerTimer.Start(); _taskManagerTimer.Start();
_window = PlatformManager.CreateWindow(); _hWnd = User32.CreateWindowEx(0, "STATIC", "", 0x80000000, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
_hWndProcHook = User32.GetWindowLongPtr(_hWnd, GWL_WNDPROC);
IPlatformHandle handle = _window.GetHandle();
_hWndProcHook = GetWindowLongPtr(handle.Handle, GWL_WNDPROC);
_fnWndProcHook = CustomWndProc; _fnWndProcHook = CustomWndProc;
nint newLong = Marshal.GetFunctionPointerForDelegate(_fnWndProcHook); nint newLong = Marshal.GetFunctionPointerForDelegate(_fnWndProcHook);
SetWindowLongPtr(handle.Handle, GWL_WNDPROC, newLong); User32.SetWindowLongPtr(_hWnd, GWL_WNDPROC, newLong);
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, handle.Handle); RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, _hWnd);
RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, handle.Handle); RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, _hWnd);
} }
public static Guid Id { get; } = new("6737b204-ffb1-4cd9-8776-9fb851db303a"); public static Guid Id { get; } = new("6737b204-ffb1-4cd9-8776-9fb851db303a");
@ -239,30 +234,10 @@ public class WindowsInputProvider : InputProvider
#region Native #region Native
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern IntPtr CallWindowProc(nint lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Unicode)]
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Unicode)]
private static extern IntPtr SetWindowLongPtr(nint hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
private struct Win32Point
{
public readonly int X;
public readonly int Y;
}
private static Win32Point GetCursorPosition() private static Win32Point GetCursorPosition()
{ {
Win32Point w32Mouse = new(); Win32Point w32Mouse = new();
GetCursorPos(ref w32Mouse); User32.GetCursorPos(ref w32Mouse);
return w32Mouse; return w32Mouse;
} }

View File

@ -1,8 +1,5 @@
using System; using System;
using System.Linq; using System.Linq;
using Artemis.UI.Windows.Extensions;
using Avalonia.Controls.Platform;
using Avalonia.Platform;
using SharpVk; using SharpVk;
using SharpVk.Khronos; using SharpVk.Khronos;
@ -10,12 +7,16 @@ namespace Artemis.UI.Windows.SkiaSharp.Vulkan;
internal sealed class Win32VkContext : VkContext internal sealed class Win32VkContext : VkContext
{ {
private readonly nint _hWnd;
public Win32VkContext() public Win32VkContext()
{ {
Window = PlatformManager.CreateWindow(); // Use WS_CHILD and WS_VISIBLE with WS_VISIBLE set to false
_hWnd = User32.CreateWindowEx(0, "STATIC", "", 0x80000000, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
Instance = Instance.Create(null, new[] {"VK_KHR_surface", "VK_KHR_win32_surface"}); Instance = Instance.Create(null, new[] {"VK_KHR_surface", "VK_KHR_win32_surface"});
PhysicalDevice = Instance.EnumeratePhysicalDevices().First(); PhysicalDevice = Instance.EnumeratePhysicalDevices().First();
Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, Window.GetHandle().Handle); Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, _hWnd);
(GraphicsFamily, PresentFamily) = FindQueueFamilies(); (GraphicsFamily, PresentFamily) = FindQueueFamilies();
@ -45,12 +46,10 @@ internal sealed class Win32VkContext : VkContext
}; };
} }
public IWindowImpl Window { get; }
public override void Dispose() public override void Dispose()
{ {
base.Dispose(); base.Dispose();
Window.Dispose(); User32.DestroyWindow(_hWnd);
} }
private IntPtr Proc(string name, IntPtr instanceHandle, IntPtr deviceHandle) private IntPtr Proc(string name, IntPtr instanceHandle, IntPtr deviceHandle)

View File

@ -0,0 +1,51 @@
using System;
using System.Runtime.InteropServices;
namespace Artemis.UI.Windows;
static class User32
{
[DllImport("user32.dll")]
public static extern IntPtr CreateWindowEx(
uint dwExStyle,
string lpClassName,
string lpWindowName,
uint dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);
[DllImport("user32.dll")]
public static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr CallWindowProc(nint lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Unicode)]
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Unicode)]
public static extern IntPtr SetWindowLongPtr(nint hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(ref Win32Point pt);
}
[StructLayout(LayoutKind.Sequential)]
public struct Win32Point
{
public readonly int X;
public readonly int Y;
}

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Runtime.InteropServices;
namespace Artemis.UI.Windows.Utilities; namespace Artemis.UI.Windows.Utilities;
@ -8,15 +7,9 @@ public static class WindowUtilities
public static int GetActiveProcessId() public static int GetActiveProcessId()
{ {
// Get foreground window handle // Get foreground window handle
IntPtr hWnd = GetForegroundWindow(); IntPtr hWnd = User32.GetForegroundWindow();
GetWindowThreadProcessId(hWnd, out uint processId); User32.GetWindowThreadProcessId(hWnd, out uint processId);
return (int) processId; return (int) processId;
} }
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
} }