This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using CursorLang.Core.Interop;
|
||||
|
||||
namespace CursorLang.Agent.Interop;
|
||||
|
||||
/// <summary>
|
||||
/// The Win32 pieces a window needs when there is no framework to make one:
|
||||
/// the class, the window itself, the message loop.
|
||||
/// </summary>
|
||||
internal static class WindowNative
|
||||
{
|
||||
/// <summary>The window procedure. Windows keeps the only reference to it.</summary>
|
||||
internal delegate IntPtr WindowProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
internal const int WS_POPUP = unchecked((int)0x80000000);
|
||||
internal const int WS_DISABLED = 0x08000000;
|
||||
|
||||
internal const int WS_EX_LAYERED = 0x00080000;
|
||||
internal const int WS_EX_TOOLWINDOW = 0x00000080;
|
||||
internal const int WS_EX_NOACTIVATE = 0x08000000;
|
||||
internal const int WS_EX_TRANSPARENT = 0x00000020;
|
||||
internal const int WS_EX_TOPMOST = 0x00000008;
|
||||
|
||||
internal const int SW_HIDE = 0;
|
||||
internal const int SW_SHOWNOACTIVATE = 4;
|
||||
|
||||
internal const uint WM_DESTROY = 0x0002;
|
||||
internal const uint WM_PAINT = 0x000F;
|
||||
internal const uint WM_CLOSE = 0x0010;
|
||||
internal const uint WM_QUIT = 0x0012;
|
||||
internal const uint WM_NULL = 0x0000;
|
||||
internal const uint WM_DISPLAYCHANGE = 0x007E;
|
||||
internal const uint WM_DPICHANGED = 0x02E0;
|
||||
internal const uint WM_ENDSESSION = 0x0016;
|
||||
|
||||
/// <summary>WM_APP and up belong to the application; the tray takes WM_APP + 1.</summary>
|
||||
internal const uint WM_APP = 0x8000;
|
||||
|
||||
private const uint LWA_ALPHA = 0x00000002;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a window class. A class already there is not an error: the name is
|
||||
/// unique per window kind, and a second agent in the same process would meet its
|
||||
/// own registration.
|
||||
/// </summary>
|
||||
internal static void RegisterClass(string className, WindowProc windowProc)
|
||||
{
|
||||
var description = new WindowClass
|
||||
{
|
||||
cbSize = Marshal.SizeOf<WindowClass>(),
|
||||
lpfnWndProc = windowProc,
|
||||
hInstance = GetModuleHandle(null),
|
||||
lpszClassName = className,
|
||||
};
|
||||
|
||||
if (RegisterClassEx(ref description) == 0 &&
|
||||
Marshal.GetLastWin32Error() != ErrorClassAlreadyExists)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"RegisterClassExW failed for '{className}': {Marshal.GetLastWin32Error()}");
|
||||
}
|
||||
}
|
||||
|
||||
private const int ErrorClassAlreadyExists = 1410;
|
||||
|
||||
/// <summary>Creates a window of a registered class. It is not shown.</summary>
|
||||
internal static IntPtr CreateWindow(string className, string title, int style, int exStyle)
|
||||
{
|
||||
IntPtr window = CreateWindowEx(
|
||||
exStyle, className, title, style,
|
||||
0, 0, 0, 0,
|
||||
IntPtr.Zero, IntPtr.Zero, GetModuleHandle(null), IntPtr.Zero);
|
||||
|
||||
if (window == IntPtr.Zero)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"CreateWindowExW failed for '{className}': {Marshal.GetLastWin32Error()}");
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/// <summary>The whole opacity of a layered window, 0 to 255.</summary>
|
||||
internal static void SetAlpha(IntPtr window, byte alpha) =>
|
||||
SetLayeredWindowAttributes(window, 0, alpha, LWA_ALPHA);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern ushort RegisterClassEx(ref WindowClass lpwcx);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CreateWindowExW")]
|
||||
private static extern IntPtr CreateWindowEx(int dwExStyle, string 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, EntryPoint = "DefWindowProcW")]
|
||||
internal static extern IntPtr DefWindowProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool DestroyWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool UpdateWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool GetClientRect(IntPtr hWnd, out PopupWindowNative.Rect lpRect);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "PostMessageW")]
|
||||
internal static extern bool PostMessage(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern void PostQuitMessage(int nExitCode);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey, byte bAlpha, uint dwFlags);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr GetModuleHandle(string? lpModuleName);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
private struct WindowClass
|
||||
{
|
||||
public int cbSize;
|
||||
public uint style;
|
||||
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
public WindowProc 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;
|
||||
public IntPtr hIconSm;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user