From e2236ddc166ce23793849c8e1bf6ce46f199bfc7 Mon Sep 17 00:00:00 2001 From: Chris Kaczor Date: Tue, 24 Feb 2026 17:11:21 -0500 Subject: [PATCH] Improvements - Update to .NET 10 - Set actual window title to window name - Add new way to identify other windows --- Library/FloatingStatusWindow.csproj | 2 +- Library/MainWindow.xaml.cs | 52 +++++++++++++++------------ Library/StartManager.cs | 1 - Library/WindowManager.cs | 39 +++++++++++++------- Library/WindowSettings.cs | 14 ++++---- TestWindow/Properties/AssemblyInfo.cs | 1 - TestWindow/TestWindow.csproj | 3 +- TestWindow/WindowSource1.cs | 24 ++++--------- TestWindow/WindowSource2.cs | 24 ++++--------- TestWindow/WindowSource3.cs | 24 ++++--------- TestWindow/WindowSource4.cs | 24 ++++--------- 11 files changed, 91 insertions(+), 117 deletions(-) diff --git a/Library/FloatingStatusWindow.csproj b/Library/FloatingStatusWindow.csproj index 5d40040..2e0a607 100644 --- a/Library/FloatingStatusWindow.csproj +++ b/Library/FloatingStatusWindow.csproj @@ -1,6 +1,6 @@  - net8.0-windows7.0 + net10.0-windows7.0 Library ChrisKaczor.Wpf.Windows.FloatingStatusWindow ChrisKaczor.Wpf.Windows.FloatingStatusWindow diff --git a/Library/MainWindow.xaml.cs b/Library/MainWindow.xaml.cs index 4bbfc72..9b89e1a 100644 --- a/Library/MainWindow.xaml.cs +++ b/Library/MainWindow.xaml.cs @@ -1,5 +1,4 @@ -using ChrisKaczor.Wpf.Windows; -using System; +using System; using System.Collections.Generic; using System.Windows; using System.Windows.Interop; @@ -20,25 +19,23 @@ internal partial class MainWindow public WindowSettings WindowSettings { get; set; } - private bool _locked; - public bool Locked { - get => _locked; + get; set { - _locked = value; + field = value; - _windowChrome.CaptionHeight = (_locked ? 0 : WindowCaptionHeight); + _windowChrome.CaptionHeight = (field ? 0 : WindowCaptionHeight); - HtmlLabel.Margin = new Thickness(0, (_locked ? 0 : WindowCaptionHeight), 0, 0); + HtmlLabel.Margin = new Thickness(0, (field ? 0 : WindowCaptionHeight), 0, 0); // Show the header border if the window is unlocked - HeaderBorder.Visibility = (_locked ? Visibility.Collapsed : Visibility.Visible); + HeaderBorder.Visibility = (field ? Visibility.Collapsed : Visibility.Visible); // Show and enable the window border if the window is unlocked - BorderFull.BorderBrush = (_locked ? Brushes.Transparent : SystemColors.ActiveCaptionBrush); - BorderFull.IsEnabled = !_locked; + BorderFull.BorderBrush = (field ? Brushes.Transparent : SystemColors.ActiveCaptionBrush); + BorderFull.IsEnabled = !field; LockStateChanged(null, EventArgs.Empty); } @@ -85,26 +82,37 @@ internal partial class MainWindow WindowManager.AllowMessagesThroughFilter(windowHandle); } + private void SetLocked(bool locked) + { + WindowSettings.Locked = locked; + Locked = locked; + } + protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WindowManager.SetLockMessage) { - var lockState = (wParam == 1); + _dispatcher.InvokeAsync(() => SetLocked(wParam == 1)); - _dispatcher.InvokeAsync(() => - { - WindowSettings.Locked = lockState; - Locked = lockState; - }); + handled = true; + return IntPtr.Zero; + } + + if (msg == WindowManager.IdentifyMessage) + { + handled = true; + return msg; + } + + if (msg == WindowManager.CloseMessage) + { + _dispatcher.InvokeAsync(Close); + handled = true; return IntPtr.Zero; } - if (msg != WindowManager.CloseMessage) - return base.WndProc(hwnd, msg, wParam, lParam, ref handled); - - _dispatcher.InvokeAsync(Close); - return IntPtr.Zero; + return base.WndProc(hwnd, msg, wParam, lParam, ref handled); } protected override void OnLocationChanged(EventArgs e) diff --git a/Library/StartManager.cs b/Library/StartManager.cs index 24088c6..9dd4868 100644 --- a/Library/StartManager.cs +++ b/Library/StartManager.cs @@ -1,6 +1,5 @@ using ChrisKaczor.Wpf.Application; using System; -using System.Windows; namespace ChrisKaczor.Wpf.Windows.FloatingStatusWindow; diff --git a/Library/WindowManager.cs b/Library/WindowManager.cs index faf4555..8199c44 100644 --- a/Library/WindowManager.cs +++ b/Library/WindowManager.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; +using System.Threading; namespace ChrisKaczor.Wpf.Windows.FloatingStatusWindow; @@ -19,7 +20,7 @@ public static partial class WindowManager private static partial void EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16, EntryPoint = "RegisterWindowMessageW")] - private static partial uint RegisterWindowMessage(string lpString); + private static partial int RegisterWindowMessage(string lpString); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); @@ -27,26 +28,29 @@ public static partial class WindowManager [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "GetWindowTextLengthW")] private static partial int GetWindowTextLength(IntPtr hWnd); - [LibraryImport("user32.dll", EntryPoint = "SendMessageW")] - private static partial void SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + [LibraryImport("user32.dll", EntryPoint = "SendMessageW", SetLastError = true)] + private static partial IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [LibraryImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - private static partial void ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, ChangeWindowMessageFilterExAction action, IntPtr changeInfo); + private static partial void ChangeWindowMessageFilterEx(IntPtr hWnd, int msg, ChangeWindowMessageFilterExAction action, IntPtr changeInfo); + private const string WindowMessageIdentify = "FloatingStatusWindowLibrary_Identify"; private const string WindowMessageSetLock = "FloatingStatusWindowLibrary_SetLock"; private const string WindowMessageClose = "FloatingStatusWindowLibrary_Close"; - public static uint SetLockMessage { get; set; } - public static uint CloseMessage { get; set; } + public static int IdentifyMessage { get; set; } + public static int SetLockMessage { get; set; } + public static int CloseMessage { get; set; } static WindowManager() { + IdentifyMessage = RegisterWindowMessage(WindowMessageIdentify); SetLockMessage = RegisterWindowMessage(WindowMessageSetLock); CloseMessage = RegisterWindowMessage(WindowMessageClose); } - private static readonly object WindowLocker = new(); + private static readonly Lock WindowLocker = new(); private static List _windowList; private static IntPtr _excludeHandle; @@ -61,7 +65,7 @@ public static partial class WindowManager { lock (WindowLocker) { - _windowList = new List(); + _windowList = []; _excludeHandle = IntPtr.Zero; EnumWindows(EnumWindowProc, IntPtr.Zero); @@ -74,7 +78,7 @@ public static partial class WindowManager { lock (WindowLocker) { - _windowList = new List(); + _windowList = []; _excludeHandle = excludeHandle; EnumWindows(EnumWindowProc, IntPtr.Zero); @@ -94,9 +98,20 @@ public static partial class WindowManager private static bool EnumWindowProc(IntPtr hWnd, IntPtr lParam) { + if (hWnd == _excludeHandle) + return true; + + var identifyResult = SendMessage(hWnd, IdentifyMessage, IntPtr.Zero, IntPtr.Zero); + + if (identifyResult == IdentifyMessage) + { + _windowList.Add(new WindowInformation(hWnd)); + return true; + } + var windowText = GetText(hWnd); - if (windowText == "FloatingStatusWindow" && hWnd != _excludeHandle) + if (windowText == "FloatingStatusWindow") _windowList.Add(new WindowInformation(hWnd)); return true; @@ -107,12 +122,12 @@ public static partial class WindowManager var lockState = locked ? 1 : 0; foreach (var w in GetWindowList()) - SendMessage(w.Handle, SetLockMessage, lockState, IntPtr.Zero); + _ = SendMessage(w.Handle, SetLockMessage, lockState, IntPtr.Zero); } public static void CloseAll() { foreach (var w in GetWindowList()) - SendMessage(w.Handle, CloseMessage, IntPtr.Zero, IntPtr.Zero); + _ = SendMessage(w.Handle, CloseMessage, IntPtr.Zero, IntPtr.Zero); } } \ No newline at end of file diff --git a/Library/WindowSettings.cs b/Library/WindowSettings.cs index 14040ba..19b21e8 100644 --- a/Library/WindowSettings.cs +++ b/Library/WindowSettings.cs @@ -64,6 +64,8 @@ public class WindowSettings : ICloneable internal void Apply() { + Window.Title = Name; + // Configure the text label HtmlLabel.FontFamily = new FontFamily(FontName); HtmlLabel.FontSize = FontSize; @@ -98,9 +100,9 @@ public class WindowSettings : ICloneable return new WindowSettings(); var serializer = new XmlSerializer(typeof(WindowSettings)); - TextReader textReader = new StringReader(settings); - var windowSettings = (WindowSettings)serializer.Deserialize(textReader); - textReader.Close(); + var stringReader = new StringReader(settings); + var windowSettings = (WindowSettings)serializer.Deserialize(stringReader); + stringReader.Close(); return windowSettings; } @@ -110,9 +112,9 @@ public class WindowSettings : ICloneable var builder = new StringBuilder(); var serializer = new XmlSerializer(typeof(WindowSettings)); - TextWriter textWriter = new StringWriter(builder); - serializer.Serialize(textWriter, this); - textWriter.Close(); + var stringWriter = new StringWriter(builder); + serializer.Serialize(stringWriter, this); + stringWriter.Close(); return builder.ToString(); } diff --git a/TestWindow/Properties/AssemblyInfo.cs b/TestWindow/Properties/AssemblyInfo.cs index 08b0ee7..d4b1cf9 100644 --- a/TestWindow/Properties/AssemblyInfo.cs +++ b/TestWindow/Properties/AssemblyInfo.cs @@ -1,6 +1,5 @@ using System.Reflection; using System.Resources; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Windows; diff --git a/TestWindow/TestWindow.csproj b/TestWindow/TestWindow.csproj index a7571ab..318fe3d 100644 --- a/TestWindow/TestWindow.csproj +++ b/TestWindow/TestWindow.csproj @@ -1,6 +1,6 @@  - net8.0-windows7.0 + net10.0-windows7.0 WinExe false true @@ -14,7 +14,6 @@ - \ No newline at end of file diff --git a/TestWindow/WindowSource1.cs b/TestWindow/WindowSource1.cs index f771632..93df2d1 100644 --- a/TestWindow/WindowSource1.cs +++ b/TestWindow/WindowSource1.cs @@ -41,36 +41,24 @@ internal class WindowSource1 : IWindowSource, IDisposable public Guid Id => Guid.Parse("0329D04D-B89B-4FEC-AFD0-4CB972E47FC8"); - public string Name - { - get { return "Test Window 1"; } - } + public string Name => "Test Window 1"; - public System.Drawing.Icon Icon - { - get { return Properties.Resources.ApplicationIcon; } - } + public System.Drawing.Icon Icon => Properties.Resources.ApplicationIcon; - public bool HasSettingsMenu - { - get { return true; } - } + public bool HasSettingsMenu => true; public bool HasAboutMenu => true; public void ShowAbout() { - _floatingStatusWindow.SetText(Assembly.GetEntryAssembly().GetName().Version.ToString()); + _floatingStatusWindow.SetText(Assembly.GetEntryAssembly()?.GetName().Version?.ToString()); } public void ShowSettings() { } - public bool HasRefreshMenu - { - get { return true; } - } + public bool HasRefreshMenu => true; public void Refresh() { @@ -78,7 +66,7 @@ internal class WindowSource1 : IWindowSource, IDisposable public string WindowSettings { - get { return Properties.Settings.Default.WindowSettings1; } + get => Properties.Settings.Default.WindowSettings1; set { Properties.Settings.Default.WindowSettings1 = value; diff --git a/TestWindow/WindowSource2.cs b/TestWindow/WindowSource2.cs index ebefa9c..7de00a8 100644 --- a/TestWindow/WindowSource2.cs +++ b/TestWindow/WindowSource2.cs @@ -41,36 +41,24 @@ internal class WindowSource2 : IWindowSource, IDisposable public Guid Id => Guid.Parse("F42F92BC-D397-497A-8E01-E71D084BEDB6"); - public string Name - { - get { return "Test Window 2"; } - } + public string Name => "Test Window 2"; - public System.Drawing.Icon Icon - { - get { return Properties.Resources.ApplicationIcon; } - } + public System.Drawing.Icon Icon => Properties.Resources.ApplicationIcon; - public bool HasSettingsMenu - { - get { return true; } - } + public bool HasSettingsMenu => true; public bool HasAboutMenu => true; public void ShowAbout() { - _floatingStatusWindow.SetText(Assembly.GetEntryAssembly().GetName().Version.ToString()); + _floatingStatusWindow.SetText(Assembly.GetEntryAssembly()?.GetName().Version?.ToString()); } public void ShowSettings() { } - public bool HasRefreshMenu - { - get { return true; } - } + public bool HasRefreshMenu => true; public void Refresh() { @@ -78,7 +66,7 @@ internal class WindowSource2 : IWindowSource, IDisposable public string WindowSettings { - get { return Properties.Settings.Default.WindowSettings2; } + get => Properties.Settings.Default.WindowSettings2; set { Properties.Settings.Default.WindowSettings2 = value; diff --git a/TestWindow/WindowSource3.cs b/TestWindow/WindowSource3.cs index 26ef1ed..9b600b5 100644 --- a/TestWindow/WindowSource3.cs +++ b/TestWindow/WindowSource3.cs @@ -41,36 +41,24 @@ internal class WindowSource3 : IWindowSource, IDisposable public Guid Id => Guid.Parse("CF7466DF-8980-452B-B2FA-290B26204BF2"); - public string Name - { - get { return "Test Window 3"; } - } + public string Name => "Test Window 3"; - public System.Drawing.Icon Icon - { - get { return Properties.Resources.ApplicationIcon; } - } + public System.Drawing.Icon Icon => Properties.Resources.ApplicationIcon; - public bool HasSettingsMenu - { - get { return true; } - } + public bool HasSettingsMenu => true; public bool HasAboutMenu => true; public void ShowAbout() { - _floatingStatusWindow.SetText(Assembly.GetEntryAssembly().GetName().Version.ToString()); + _floatingStatusWindow.SetText(Assembly.GetEntryAssembly()?.GetName().Version?.ToString()); } public void ShowSettings() { } - public bool HasRefreshMenu - { - get { return true; } - } + public bool HasRefreshMenu => true; public void Refresh() { @@ -78,7 +66,7 @@ internal class WindowSource3 : IWindowSource, IDisposable public string WindowSettings { - get { return Properties.Settings.Default.WindowSettings3; } + get => Properties.Settings.Default.WindowSettings3; set { Properties.Settings.Default.WindowSettings3 = value; diff --git a/TestWindow/WindowSource4.cs b/TestWindow/WindowSource4.cs index fb71c4d..bf06012 100644 --- a/TestWindow/WindowSource4.cs +++ b/TestWindow/WindowSource4.cs @@ -41,36 +41,24 @@ internal class WindowSource4 : IWindowSource, IDisposable public Guid Id => Guid.Parse("0DD89F7E-3AD4-4226-8CBD-B75C8EBEEF32"); - public string Name - { - get { return "Test Window 4"; } - } + public string Name => "Test Window 4"; - public System.Drawing.Icon Icon - { - get { return Properties.Resources.ApplicationIcon; } - } + public System.Drawing.Icon Icon => Properties.Resources.ApplicationIcon; - public bool HasSettingsMenu - { - get { return true; } - } + public bool HasSettingsMenu => true; public bool HasAboutMenu => true; public void ShowAbout() { - _floatingStatusWindow.SetText(Assembly.GetEntryAssembly().GetName().Version.ToString()); + _floatingStatusWindow.SetText(Assembly.GetEntryAssembly()?.GetName().Version?.ToString()); } public void ShowSettings() { } - public bool HasRefreshMenu - { - get { return true; } - } + public bool HasRefreshMenu => true; public void Refresh() { @@ -78,7 +66,7 @@ internal class WindowSource4 : IWindowSource, IDisposable public string WindowSettings { - get { return Properties.Settings.Default.WindowSettings4; } + get => Properties.Settings.Default.WindowSettings4; set { Properties.Settings.Default.WindowSettings4 = value;