mirror of
https://github.com/ckaczor/FloatingStatusWindow.git
synced 2026-01-13 17:22:47 -05:00
Support for locking/unlocking and closing other windows
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using Hardcodet.Wpf.TaskbarNotification;
|
||||
using Common.Native;
|
||||
using FloatingStatusWindowLibrary.Properties;
|
||||
using Hardcodet.Wpf.TaskbarNotification;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -15,6 +17,9 @@ namespace FloatingStatusWindowLibrary
|
||||
private readonly MainWindow _mainWindow;
|
||||
private readonly TaskbarIcon _taskbarIcon;
|
||||
|
||||
private readonly MenuItem _allWindowsMenuItem;
|
||||
private readonly Separator _allWindowsSeparator;
|
||||
|
||||
private readonly MenuItem _lockMenuItem;
|
||||
private readonly MenuItem _autoStartMenuItem;
|
||||
|
||||
@@ -27,14 +32,34 @@ namespace FloatingStatusWindowLibrary
|
||||
var contextMenu = new ContextMenu();
|
||||
contextMenu.Opened += HandleContextMenuOpened;
|
||||
|
||||
var optionsMenu = new MenuItem { Name = "contextMenuItemOptions", Header = "Window" };
|
||||
_allWindowsMenuItem = new MenuItem { Header = Resources.AllWindowsMenu };
|
||||
contextMenu.Items.Add(_allWindowsMenuItem);
|
||||
|
||||
var menuItem = new MenuItem { Header = Resources.ContextMenuLock };
|
||||
menuItem.Click += (sender, args) => WindowManager.SetLockOnAll(true);
|
||||
_allWindowsMenuItem.Items.Add(menuItem);
|
||||
|
||||
menuItem = new MenuItem { Header = Resources.ContextMenuUnlock };
|
||||
menuItem.Click += (sender, args) => WindowManager.SetLockOnAll(false);
|
||||
_allWindowsMenuItem.Items.Add(menuItem);
|
||||
|
||||
_allWindowsMenuItem.Items.Add(new Separator());
|
||||
|
||||
menuItem = new MenuItem { Header = Resources.ContextMenuClose };
|
||||
menuItem.Click += (sender, args) => WindowManager.CloseAll();
|
||||
_allWindowsMenuItem.Items.Add(menuItem);
|
||||
|
||||
_allWindowsSeparator = new Separator();
|
||||
contextMenu.Items.Add(_allWindowsSeparator);
|
||||
|
||||
var optionsMenu = new MenuItem { Name = "contextMenuItemOptions", Header = Resources.WindowMenu };
|
||||
contextMenu.Items.Add(optionsMenu);
|
||||
|
||||
_lockMenuItem = new MenuItem
|
||||
{
|
||||
Name = "contextMenuItemLocked",
|
||||
IsChecked = false,
|
||||
Header = Properties.Resources.ContextMenuLocked
|
||||
Header = Resources.ContextMenuLocked
|
||||
};
|
||||
_lockMenuItem.Click += HandleLockedMenuItemClicked;
|
||||
optionsMenu.Items.Add(_lockMenuItem);
|
||||
@@ -47,7 +72,7 @@ namespace FloatingStatusWindowLibrary
|
||||
{
|
||||
Name = "contextMenuItemAutoStart",
|
||||
IsChecked = StartManager.AutoStartEnabled,
|
||||
Header = Properties.Resources.ContextMenuAutoStart
|
||||
Header = Resources.ContextMenuAutoStart
|
||||
|
||||
};
|
||||
_autoStartMenuItem.Click += (sender, args) => StartManager.AutoStartEnabled = !StartManager.AutoStartEnabled;
|
||||
@@ -56,10 +81,10 @@ namespace FloatingStatusWindowLibrary
|
||||
|
||||
optionsMenu.Items.Add(new Separator());
|
||||
|
||||
var menuItem = new MenuItem
|
||||
menuItem = new MenuItem
|
||||
{
|
||||
Name = "contextMenuChangeAppearance",
|
||||
Header = Properties.Resources.ContextMenuChangeAppearance
|
||||
Header = Resources.ContextMenuChangeAppearance
|
||||
};
|
||||
menuItem.Click += HandleChangeAppearancemMenuItemClick;
|
||||
optionsMenu.Items.Add(menuItem);
|
||||
@@ -69,7 +94,7 @@ namespace FloatingStatusWindowLibrary
|
||||
menuItem = new MenuItem
|
||||
{
|
||||
Name = "contextMenuItemExit",
|
||||
Header = Properties.Resources.ContextMenuExit
|
||||
Header = Resources.ContextMenuExit
|
||||
};
|
||||
menuItem.Click += HandleExitMenuItemClick;
|
||||
contextMenu.Items.Add(menuItem);
|
||||
@@ -117,6 +142,9 @@ namespace FloatingStatusWindowLibrary
|
||||
|
||||
if (_autoStartMenuItem != null)
|
||||
_autoStartMenuItem.IsChecked = StartManager.AutoStartEnabled;
|
||||
|
||||
_allWindowsMenuItem.Visibility = WindowManager.GetWindowList().Count == 0 ? Visibility.Collapsed : Visibility.Visible;
|
||||
_allWindowsSeparator.Visibility = _allWindowsMenuItem.Visibility;
|
||||
}
|
||||
|
||||
public void SetText(string text)
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StartManager.cs" />
|
||||
<Compile Include="WindowManager.cs" />
|
||||
<Compile Include="WindowSettings.cs" />
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using Common.Wpf.Windows;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shell;
|
||||
using Common.Native;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace FloatingStatusWindowLibrary
|
||||
{
|
||||
@@ -13,6 +14,7 @@ namespace FloatingStatusWindowLibrary
|
||||
private const int WindowCaptionHeight = 24;
|
||||
|
||||
private readonly WindowChrome _windowChrome;
|
||||
private readonly Dispatcher _dispatcher;
|
||||
|
||||
private WindowSettings _windowSettings;
|
||||
public WindowSettings WindowSettings
|
||||
@@ -44,6 +46,8 @@ namespace FloatingStatusWindowLibrary
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_dispatcher = Dispatcher.CurrentDispatcher;
|
||||
|
||||
// Create and set the window chrome
|
||||
_windowChrome = new WindowChrome { CaptionHeight = WindowCaptionHeight };
|
||||
WindowChrome.SetWindowChrome(this, _windowChrome);
|
||||
@@ -71,6 +75,30 @@ namespace FloatingStatusWindowLibrary
|
||||
_windowSettings.Apply();
|
||||
}
|
||||
|
||||
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == WindowManager.SetLockMessage)
|
||||
{
|
||||
var lockState = (wParam == (IntPtr) 1);
|
||||
|
||||
_dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
WindowSettings.Locked = lockState;
|
||||
Locked = lockState;
|
||||
});
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (msg == WindowManager.CloseMessage)
|
||||
{
|
||||
_dispatcher.InvokeAsync(Close);
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
|
||||
}
|
||||
|
||||
protected override void OnLocationChanged(EventArgs e)
|
||||
{
|
||||
base.OnLocationChanged(e);
|
||||
@@ -85,36 +113,14 @@ namespace FloatingStatusWindowLibrary
|
||||
_windowSettings.Size = new Size(Width, Height);
|
||||
}
|
||||
|
||||
private List<Rect> _windowList;
|
||||
private IntPtr _windowHandle;
|
||||
protected override List<Rect> OtherWindows
|
||||
protected override List<WindowInformation> OtherWindows
|
||||
{
|
||||
get
|
||||
{
|
||||
_windowList = new List<Rect>();
|
||||
_windowHandle = new WindowInteropHelper(this).Handle;
|
||||
var windowHandle = new WindowInteropHelper(this).Handle;
|
||||
|
||||
Functions.User32.EnumWindows(EnumWindowProc, IntPtr.Zero);
|
||||
|
||||
return _windowList;
|
||||
return WindowManager.GetWindowList(windowHandle);
|
||||
}
|
||||
}
|
||||
|
||||
private bool EnumWindowProc(IntPtr hWnd, IntPtr lParam)
|
||||
{
|
||||
var windowText = Functions.Window.GetText(hWnd);
|
||||
|
||||
if (windowText == "FloatingStatusWindow" && hWnd != _windowHandle)
|
||||
{
|
||||
var windowPlacement = new Structures.WindowPlacement();
|
||||
Functions.User32.GetWindowPlacement(hWnd, ref windowPlacement);
|
||||
|
||||
var p = windowPlacement.NormalPosition;
|
||||
|
||||
_windowList.Add(new Rect(p.X, p.Y, p.Width, p.Height));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,15 @@ namespace FloatingStatusWindowLibrary.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to All Windows.
|
||||
/// </summary>
|
||||
public static string AllWindowsMenu {
|
||||
get {
|
||||
return ResourceManager.GetString("AllWindowsMenu", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bottom.
|
||||
/// </summary>
|
||||
@@ -114,6 +123,15 @@ namespace FloatingStatusWindowLibrary.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Close.
|
||||
/// </summary>
|
||||
public static string ContextMenuClose {
|
||||
get {
|
||||
return ResourceManager.GetString("ContextMenuClose", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Exit.
|
||||
/// </summary>
|
||||
@@ -123,6 +141,15 @@ namespace FloatingStatusWindowLibrary.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Lock.
|
||||
/// </summary>
|
||||
public static string ContextMenuLock {
|
||||
get {
|
||||
return ResourceManager.GetString("ContextMenuLock", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Locked.
|
||||
/// </summary>
|
||||
@@ -132,6 +159,15 @@ namespace FloatingStatusWindowLibrary.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unlock.
|
||||
/// </summary>
|
||||
public static string ContextMenuUnlock {
|
||||
get {
|
||||
return ResourceManager.GetString("ContextMenuUnlock", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Font _name:.
|
||||
/// </summary>
|
||||
@@ -221,5 +257,14 @@ namespace FloatingStatusWindowLibrary.Properties {
|
||||
return ResourceManager.GetString("VerticalAlignment", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Window.
|
||||
/// </summary>
|
||||
public static string WindowMenu {
|
||||
get {
|
||||
return ResourceManager.GetString("WindowMenu", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,9 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AllWindowsMenu" xml:space="preserve">
|
||||
<value>All Windows</value>
|
||||
</data>
|
||||
<data name="Bottom" xml:space="preserve">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
@@ -135,12 +138,21 @@
|
||||
<data name="ContextMenuChangeAppearance" xml:space="preserve">
|
||||
<value>Change Appearance...</value>
|
||||
</data>
|
||||
<data name="ContextMenuClose" xml:space="preserve">
|
||||
<value>Close</value>
|
||||
</data>
|
||||
<data name="ContextMenuExit" xml:space="preserve">
|
||||
<value>Exit</value>
|
||||
</data>
|
||||
<data name="ContextMenuLock" xml:space="preserve">
|
||||
<value>Lock</value>
|
||||
</data>
|
||||
<data name="ContextMenuLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
</data>
|
||||
<data name="ContextMenuUnlock" xml:space="preserve">
|
||||
<value>Unlock</value>
|
||||
</data>
|
||||
<data name="FontName" xml:space="preserve">
|
||||
<value>Font _name:</value>
|
||||
</data>
|
||||
@@ -171,4 +183,7 @@
|
||||
<data name="VerticalAlignment" xml:space="preserve">
|
||||
<value>_Vertical alignment:</value>
|
||||
</data>
|
||||
<data name="WindowMenu" xml:space="preserve">
|
||||
<value>Window</value>
|
||||
</data>
|
||||
</root>
|
||||
77
FloatingStatusWindowLibrary/WindowManager.cs
Normal file
77
FloatingStatusWindowLibrary/WindowManager.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Common.Native;
|
||||
using Common.Wpf.Windows;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FloatingStatusWindowLibrary
|
||||
{
|
||||
public static class WindowManager
|
||||
{
|
||||
private const string WindowMessageSetLock = "FloatingStatusWindowLibrary_SetLock";
|
||||
private const string WindowMessageClose = "FloatingStatusWindowLibrary_Close";
|
||||
|
||||
public static uint SetLockMessage { get; set; }
|
||||
public static uint CloseMessage { get; set; }
|
||||
|
||||
static WindowManager()
|
||||
{
|
||||
SetLockMessage = Functions.User32.RegisterWindowMessage(WindowMessageSetLock);
|
||||
CloseMessage = Functions.User32.RegisterWindowMessage(WindowMessageClose);
|
||||
}
|
||||
|
||||
private static readonly object WindowLocker = new object();
|
||||
|
||||
private static List<WindowInformation> _windowList;
|
||||
private static IntPtr _excludeHandle;
|
||||
|
||||
public static List<WindowInformation> GetWindowList()
|
||||
{
|
||||
lock (WindowLocker)
|
||||
{
|
||||
_windowList = new List<WindowInformation>();
|
||||
_excludeHandle = IntPtr.Zero;
|
||||
|
||||
Functions.User32.EnumWindows(EnumWindowProc, IntPtr.Zero);
|
||||
|
||||
return _windowList;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<WindowInformation> GetWindowList(IntPtr excludeHandle)
|
||||
{
|
||||
lock (WindowLocker)
|
||||
{
|
||||
_windowList = new List<WindowInformation>();
|
||||
_excludeHandle = excludeHandle;
|
||||
|
||||
Functions.User32.EnumWindows(EnumWindowProc, IntPtr.Zero);
|
||||
|
||||
return _windowList;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool EnumWindowProc(IntPtr hWnd, IntPtr lParam)
|
||||
{
|
||||
var windowText = Functions.Window.GetText(hWnd);
|
||||
|
||||
if (windowText == "FloatingStatusWindow" && hWnd != _excludeHandle)
|
||||
_windowList.Add(new WindowInformation(hWnd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void SetLockOnAll(bool locked)
|
||||
{
|
||||
var lockState = locked ? (IntPtr) 1 : (IntPtr) 0;
|
||||
|
||||
foreach (var w in GetWindowList())
|
||||
Functions.User32.SendMessage(w.Handle, SetLockMessage, lockState, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public static void CloseAll()
|
||||
{
|
||||
foreach (var w in GetWindowList())
|
||||
Functions.User32.SendMessage(w.Handle, CloseMessage, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoWRealmStatusWindow", "..\
|
||||
{F023A16C-2F13-4A87-A8B7-22C43C4A58A4} = {F023A16C-2F13-4A87-A8B7-22C43C4A58A4}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FloatingStatusWindowLibrary", "..\FloatingStatusWindowLibrary\FloatingStatusWindowLibrary\FloatingStatusWindowLibrary.csproj", "{F023A16C-2F13-4A87-A8B7-22C43C4A58A4}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FloatingStatusWindowLibrary", "FloatingStatusWindowLibrary\FloatingStatusWindowLibrary.csproj", "{F023A16C-2F13-4A87-A8B7-22C43C4A58A4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Wpf", "..\Common.Wpf\Common.Wpf.csproj", "{0074C983-550E-4094-9E8C-F566FB669297}"
|
||||
EndProject
|
||||
@@ -41,6 +41,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Native", "..\Common.
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenHardwareMonitorLib", "..\..\Public\OpenHardwareMonitor\OpenHardwareMonitorLib.csproj", "{B0397530-545A-471D-BB74-027AE456DF1A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinecraftStatusWindow", "..\MinecraftStatusWindow\MinecraftStatusWindow.csproj", "{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F023A16C-2F13-4A87-A8B7-22C43C4A58A4} = {F023A16C-2F13-4A87-A8B7-22C43C4A58A4}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -139,6 +144,14 @@ Global
|
||||
{B0397530-545A-471D-BB74-027AE456DF1A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B0397530-545A-471D-BB74-027AE456DF1A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B0397530-545A-471D-BB74-027AE456DF1A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D3ADE27E-4645-4C31-B4B2-8A64EF6984B0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
6
StartAll.bat
Normal file
6
StartAll.bat
Normal file
@@ -0,0 +1,6 @@
|
||||
start D:\Code\Personal\WeatherStatusWindow\bin\Debug\WeatherStatusWindow.exe
|
||||
start D:\Code\Personal\WoWRealmStatusWindow\bin\Debug\WoWRealmStatusWindow.exe
|
||||
start D:\Code\Personal\WaveUpgradeMonitorStatusWindow\bin\Debug\WaveUpgradeMonitorStatusWindow.exe
|
||||
start D:\Code\Personal\SystemTemperatureStatusWindow\bin\Debug\SystemTemperatureStatusWindow.exe
|
||||
start D:\Code\Personal\ProcessCpuUsageStatusWindow\bin\Debug\ProcessCpuUsageStatusWindow.exe
|
||||
start D:\Code\Personal\MonitStatusWindow\bin\Debug\MonitStatusWindow.exe
|
||||
Reference in New Issue
Block a user