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:
parent
c50a572363
commit
ebe7f68e9d
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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");
|
||||||
@ -238,31 +233,11 @@ public class WindowsInputProvider : InputProvider
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
51
src/Artemis.UI.Windows/User32.cs
Normal file
51
src/Artemis.UI.Windows/User32.cs
Normal 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;
|
||||||
|
}
|
||||||
@ -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);
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user