fix bug - popup windows show hiding logic
Pull request / build (pull_request) Successful in 39s

This commit is contained in:
2026-08-12 18:12:08 +05:00
parent 6259dbd6b3
commit 87266e6c13
13 changed files with 503 additions and 442 deletions
+49 -24
View File
@@ -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);