From 3c1168446732443e71f1773ac3b25bc34b6167c1 Mon Sep 17 00:00:00 2001 From: Johann Blais Date: Sun, 25 Jan 2026 12:29:48 +0100 Subject: [PATCH 1/2] Fixed regression in the processing of new lines within the InfoBox content (#59) --- InfoBox/Form/InformationBoxForm.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/InfoBox/Form/InformationBoxForm.cs b/InfoBox/Form/InformationBoxForm.cs index c327b82..00f8e1d 100644 --- a/InfoBox/Form/InformationBoxForm.cs +++ b/InfoBox/Form/InformationBoxForm.cs @@ -1270,6 +1270,9 @@ private void SetText() Screen currentScreen = Screen.FromControl(this); int screenWidth = currentScreen.WorkingArea.Width; + this.messageText.Text = this.messageText.Text.Replace("\r\n", "\n"); + this.messageText.Text = this.messageText.Text.Replace("\n", Environment.NewLine); + if (this.autoSizeMode == InformationBoxAutoSizeMode.FitToText) { this.messageText.WordWrap = false; @@ -1277,10 +1280,6 @@ private void SetText() } else { - this.messageText.Text = this.messageText.Text.Replace("\r\n", "\n"); - this.messageText.Text = this.messageText.Text.Replace("\n", Environment.NewLine); - - if (this.autoSizeMode == InformationBoxAutoSizeMode.None) { this.messageText.WordWrap = true; From 2f41a7d17fe3f896e70c1146016b95f547483f99 Mon Sep 17 00:00:00 2001 From: Johann Blais Date: Sun, 25 Jan 2026 12:39:00 +0100 Subject: [PATCH 2/2] Cleaned up TODOs --- InfoBox/Context/InformationBoxScope.cs | 4 ---- InfoBox/Form/InformationBoxForm.cs | 14 -------------- InfoBox/InformationBox.cs | 14 ++++---------- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/InfoBox/Context/InformationBoxScope.cs b/InfoBox/Context/InformationBoxScope.cs index 17d86b7..e6606cc 100644 --- a/InfoBox/Context/InformationBoxScope.cs +++ b/InfoBox/Context/InformationBoxScope.cs @@ -16,10 +16,6 @@ public class InformationBoxScope : IDisposable { #region Attributes - // TODO: [P1.1] Replace static Stack with AsyncLocal> for thread-safety - // See TESTABILITY_ROADMAP.md - current implementation is not thread-safe for concurrent tests - // private static readonly AsyncLocal> _scopeStack = new AsyncLocal>(); - // Also add IInformationBoxScope interface and TestScopeProvider for dependency injection in tests /// /// Stack of all scopes /// diff --git a/InfoBox/Form/InformationBoxForm.cs b/InfoBox/Form/InformationBoxForm.cs index 00f8e1d..2328125 100644 --- a/InfoBox/Form/InformationBoxForm.cs +++ b/InfoBox/Form/InformationBoxForm.cs @@ -288,13 +288,9 @@ internal InformationBoxForm(string text, InformationBoxSound sound = InformationBoxSound.Default) { this.InitializeComponent(); - // TODO: [P0.2] Replace CreateGraphics with ITextMeasurement interface injection - // See TESTABILITY_ROADMAP.md - this prevents headless testing this.measureGraphics = CreateGraphics(); this.measureGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; - // TODO: [P1.3] Replace SystemFonts with ISystemResources interface injection - // See TESTABILITY_ROADMAP.md - this prevents testing without system fonts // Apply default font for message boxes this.Font = SystemFonts.MessageBoxFont; this.messageText.Font = SystemFonts.MessageBoxFont; @@ -646,8 +642,6 @@ internal InformationBoxResult Show(out CheckState state) /// private void PlaySound() { - // TODO: [P1.3] Replace SystemSounds with ISystemResources.PlaySound(InformationBoxSound) - // See TESTABILITY_ROADMAP.md - this entire method logic should move to WindowsSystemResources if (sound == InformationBoxSound.None) { return; @@ -1007,8 +1001,6 @@ private void SetFocus() /// private void SetLayout() { - // TODO: [P0.1] Extract this 110-line method to InformationBoxPresenter.CalculateLayout() - // See TESTABILITY_ROADMAP.md - this complex layout logic should be testable without WinForms int totalHeight; int totalWidth; @@ -1068,8 +1060,6 @@ private void SetLayout() totalHeight = Math.Max(iconHeight, textHeight) + BorderPadding * 2 + this.pnlBas.Height; - // TODO: [P1.3] Replace Screen.PrimaryScreen with ISystemResources.GetWorkingArea() - // See TESTABILITY_ROADMAP.md - hardcoded screen metrics prevent testing with different screen sizes // Add a small space to avoid vertical scrollbar. if (iconAndTextWidth > Screen.PrimaryScreen.WorkingArea.Width - 100) { @@ -1341,8 +1331,6 @@ private void SetText() /// private void SetButtons() { - // TODO: [P0.1] Extract button generation logic to InformationBoxPresenter.GetButtons() - // See TESTABILITY_ROADMAP.md - this logic should return List without WinForms dependencies // Abort button if (this.buttons == InformationBoxButtons.AbortRetryIgnore) { @@ -1698,8 +1686,6 @@ private void InformationBoxForm_KeyDown(object sender, KeyEventArgs e) /// The instance containing the event data. private void TmrAutoClose_Tick(object sender, EventArgs e) { - // TODO: [P0.1] Extract this 115-line timer logic to InformationBoxPresenter.UpdateAutoClose(TimeSpan elapsed) - // See TESTABILITY_ROADMAP.md - this should be a pure function returning AutoCloseState without Timer dependencies if (this.elapsedTime == this.autoClose.Seconds) { this.tmrAutoClose.Stop(); diff --git a/InfoBox/InformationBox.cs b/InfoBox/InformationBox.cs index 9a4139d..25aba64 100644 --- a/InfoBox/InformationBox.cs +++ b/InfoBox/InformationBox.cs @@ -13,17 +13,12 @@ namespace InfoBox /// /// Displays a message box that can contain text, buttons, and symbols that inform and instruct the user. /// - #if !NET5_0_OR_GREATER +#if !NET5_0_OR_GREATER [UIPermission(SecurityAction.Demand)] - #endif +#endif public static class InformationBox { - // TODO: [P1.2] Add factory pattern for testability - // See TESTABILITY_ROADMAP.md - Add IInformationBoxFactory and IInformationBoxDisplay interfaces - // internal static IInformationBoxFactory Factory { get; set; } = new InformationBoxFactory(); - // This will allow tests to inject mock factories and test code that calls InformationBox.Show() - -#region Show + #region Show /// /// Displays a message box with the specified text and parameters. @@ -138,7 +133,6 @@ public static class InformationBox /// One of the values. public static InformationBoxResult Show(string text, params object[] parameters) { - // TODO: [P1.2] Replace direct instantiation with Factory.Create(text, parameters).ShowModal() return new InformationBoxForm(text, parameters).Show(); } @@ -429,6 +423,6 @@ public static InformationBoxResult Show(string text, style, autoClose, design, fontParameters, font, titleStyle, titleIcon, legacyButtons, legacyIcon, legacyDefaultButton, behavior, callback, opacity, parent, order, sound).Show(out checkBoxState); } -#endregion Show + #endregion Show } }