Feat: Rookie now flashes in taskbar when FlexibleMessageBox is thrown and window is inactive, Fix: FlexibleMessageBox positioning for inactive/minimized window

Added taskbar flashing to notify users when a task is complete or requires user input (= when FlexibleMessageBox is thrown) while the application is inactive or minimized. Enhanced FlexibleMessageBox to better handle when the application is minimized by centering the dialog on the screen and repositioning it when the form is restored.
This commit is contained in:
jp64k
2026-01-06 17:51:36 +01:00
parent 3d241cc634
commit 77cfb81545

View File

@@ -83,7 +83,18 @@ namespace JR.Utils.GUI.Forms
private const int CS_DROPSHADOW = 0x00020000; private const int CS_DROPSHADOW = 0x00020000;
private const int WM_NCLBUTTONDOWN = 0xA1; private const int WM_NCLBUTTONDOWN = 0xA1;
private const int HT_CAPTION = 0x2; private const int HT_CAPTION = 0x2;
private const int BORDER_RADIUS = 12; private const uint FLASHW_TRAY = 0x00000002;
private const uint FLASHW_TIMERNOFG = 0x0000000C;
[StructLayout(LayoutKind.Sequential)]
private struct FLASHWINFO
{
public uint cbSize;
public IntPtr hwnd;
public uint dwFlags;
public uint uCount;
public uint dwTimeout;
}
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
@@ -91,6 +102,9 @@ namespace JR.Utils.GUI.Forms
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern bool ReleaseCapture(); private static extern bool ReleaseCapture();
[DllImport("user32.dll")]
private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);
protected override CreateParams CreateParams protected override CreateParams CreateParams
{ {
get get
@@ -604,7 +618,7 @@ namespace JR.Utils.GUI.Forms
ownerForm = Form.ActiveForm; ownerForm = Form.ActiveForm;
} }
if (ownerForm != null && ownerForm.Visible) if (ownerForm != null && ownerForm.Visible && ownerForm.WindowState != FormWindowState.Minimized)
{ {
// Center relative to owner window // Center relative to owner window
int x = ownerForm.Left + (ownerForm.Width - flexibleMessageBoxForm.Width) / 2; int x = ownerForm.Left + (ownerForm.Width - flexibleMessageBoxForm.Width) / 2;
@@ -620,7 +634,7 @@ namespace JR.Utils.GUI.Forms
} }
else else
{ {
// No owner found: center on current screen // No owner found or minimized: center on current screen
CenterOnScreen(flexibleMessageBoxForm); CenterOnScreen(flexibleMessageBoxForm);
} }
} }
@@ -848,8 +862,45 @@ namespace JR.Utils.GUI.Forms
int contentWidth = flexibleMessageBoxForm.ClientSize.Width - 16; // 8px padding int contentWidth = flexibleMessageBoxForm.ClientSize.Width - 16; // 8px padding
flexibleMessageBoxForm.titlePanel.Width = contentWidth; flexibleMessageBoxForm.titlePanel.Width = contentWidth;
// Get owner form
Form ownerForm = owner as Form ?? Form.ActiveForm;
bool ownerWasMinimized = ownerForm != null && ownerForm.WindowState == FormWindowState.Minimized;
SetDialogStartPosition(flexibleMessageBoxForm, owner); SetDialogStartPosition(flexibleMessageBoxForm, owner);
// If owner was minimized, reposition dialog when owner is restored
if (ownerWasMinimized && ownerForm != null)
{
EventHandler resizeHandler = null;
resizeHandler = (s, e) =>
{
if (ownerForm.WindowState != FormWindowState.Minimized && flexibleMessageBoxForm.Visible && !flexibleMessageBoxForm.IsDisposed)
{
SetDialogStartPosition(flexibleMessageBoxForm, owner);
ownerForm.Resize -= resizeHandler;
}
};
ownerForm.Resize += resizeHandler;
}
// Flash taskbar if application is inactive or minimized
if (Form.ActiveForm == null || ownerWasMinimized)
{
Form targetForm = ownerForm ?? Application.OpenForms.Cast<Form>().FirstOrDefault(f => f != null && !f.IsDisposed && f != flexibleMessageBoxForm && f.Visible);
if (targetForm != null && !targetForm.IsDisposed)
{
FLASHWINFO info = new FLASHWINFO
{
cbSize = (uint)Marshal.SizeOf(typeof(FLASHWINFO)),
hwnd = targetForm.Handle,
dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG,
uCount = 5,
dwTimeout = 0
};
_ = FlashWindowEx(ref info);
}
}
return flexibleMessageBoxForm.ShowDialog(owner); return flexibleMessageBoxForm.ShowDialog(owner);
} }