This commit is contained in:
@@ -5,7 +5,7 @@ using CursorLang.Core.Interop;
|
||||
namespace CursorLang.Agent.Interop;
|
||||
|
||||
/// <summary>
|
||||
/// Plain GDI: a font, a brush, a rounded region and text on a device context.
|
||||
/// Plain GDI: a font, text, and an off-screen bitmap to draw them into.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// GDI rather than GDI+ on purpose. <c>System.Drawing.Common</c> would make the drawing
|
||||
@@ -85,11 +85,41 @@ internal static class GdiNative
|
||||
int iCharSet, int iOutPrecision, int iClipPrecision, int iQuality, int iPitchAndFamily,
|
||||
string pszFaceName);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern IntPtr CreateSolidBrush(uint color);
|
||||
/// <summary>
|
||||
/// A 32-bit surface to draw the popup into before anyone can see it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Top-down — a negative height — so that the first row of <paramref name="bits"/>
|
||||
/// is the top row of the picture and the alpha fixing up afterwards can walk the
|
||||
/// memory straight through.
|
||||
/// </remarks>
|
||||
internal static IntPtr CreateSurface(IntPtr deviceContext, int width, int height, out IntPtr bits)
|
||||
{
|
||||
var header = new BitmapInfoHeader
|
||||
{
|
||||
biSize = Marshal.SizeOf<BitmapInfoHeader>(),
|
||||
biWidth = width,
|
||||
biHeight = -height,
|
||||
biPlanes = 1,
|
||||
biBitCount = 32,
|
||||
biCompression = BI_RGB,
|
||||
};
|
||||
|
||||
return CreateDIBSection(deviceContext, ref header, DIB_RGB_COLORS, out bits, IntPtr.Zero, 0);
|
||||
}
|
||||
|
||||
private const uint BI_RGB = 0;
|
||||
private const uint DIB_RGB_COLORS = 0;
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int w, int h);
|
||||
internal static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern bool DeleteDC(IntPtr hdc);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateDIBSection(IntPtr hdc, ref BitmapInfoHeader header, uint usage,
|
||||
out IntPtr bits, IntPtr section, uint offset);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr h);
|
||||
@@ -103,9 +133,6 @@ internal static class GdiNative
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern uint SetTextColor(IntPtr hdc, uint color);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int FillRect(IntPtr hdc, ref PopupWindowNative.Rect lprc, IntPtr hbr);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DrawTextW")]
|
||||
internal static extern int DrawText(IntPtr hdc, string lpchText, int cchText,
|
||||
ref PopupWindowNative.Rect lprc, uint format);
|
||||
@@ -116,22 +143,19 @@ internal static class GdiNative
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr BeginPaint(IntPtr hWnd, out PaintStruct lpPaint);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool EndPaint(IntPtr hWnd, ref PaintStruct lpPaint);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct PaintStruct
|
||||
private struct BitmapInfoHeader
|
||||
{
|
||||
public IntPtr hdc;
|
||||
public bool fErase;
|
||||
public PopupWindowNative.Rect rcPaint;
|
||||
public bool fRestore;
|
||||
public bool fIncUpdate;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public byte[] rgbReserved;
|
||||
public int biSize;
|
||||
public int biWidth;
|
||||
public int biHeight;
|
||||
public short biPlanes;
|
||||
public short biBitCount;
|
||||
public uint biCompression;
|
||||
public uint biSizeImage;
|
||||
public int biXPelsPerMeter;
|
||||
public int biYPelsPerMeter;
|
||||
public uint biClrUsed;
|
||||
public uint biClrImportant;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ internal static class WindowNative
|
||||
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;
|
||||
@@ -25,19 +24,14 @@ internal static class WindowNative
|
||||
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
|
||||
@@ -80,9 +74,55 @@ internal static class WindowNative
|
||||
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);
|
||||
/// <summary>
|
||||
/// Puts a finished picture into a layered window, together with where it goes and
|
||||
/// how see-through it is.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// One call replaces moving the window, resizing it, painting it and setting its
|
||||
/// opacity, and it works while the window is still hidden. That is the point: the
|
||||
/// content is ready before anyone can see the window, so it can never be shown
|
||||
/// holding the picture of the previous time.
|
||||
/// </remarks>
|
||||
internal static bool SetContent(
|
||||
IntPtr window, PopupWindowNative.Point at, Size size, IntPtr sourceDc, byte alpha)
|
||||
{
|
||||
var source = new PopupWindowNative.Point { X = 0, Y = 0 };
|
||||
var blend = new BlendFunction
|
||||
{
|
||||
BlendOp = AC_SRC_OVER,
|
||||
SourceConstantAlpha = alpha,
|
||||
AlphaFormat = AC_SRC_ALPHA,
|
||||
};
|
||||
|
||||
return UpdateLayeredWindow(
|
||||
window, IntPtr.Zero, ref at, ref size, sourceDc, ref source, 0, ref blend, ULW_ALPHA);
|
||||
}
|
||||
|
||||
private const byte AC_SRC_OVER = 0;
|
||||
private const byte AC_SRC_ALPHA = 1;
|
||||
private const uint ULW_ALPHA = 0x00000002;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct BlendFunction
|
||||
{
|
||||
public byte BlendOp;
|
||||
public byte BlendFlags;
|
||||
public byte SourceConstantAlpha;
|
||||
public byte AlphaFormat;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct Size
|
||||
{
|
||||
public int Width;
|
||||
public int Height;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool UpdateLayeredWindow(IntPtr hWnd, IntPtr hdcDst,
|
||||
ref PopupWindowNative.Point pptDst, ref Size psize, IntPtr hdcSrc,
|
||||
ref PopupWindowNative.Point pptSrc, uint crKey, ref BlendFunction pblend, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern ushort RegisterClassEx(ref WindowClass lpwcx);
|
||||
@@ -104,27 +144,12 @@ internal static class WindowNative
|
||||
[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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user