Support for locking/unlocking and closing other windows

This commit is contained in:
2014-05-06 10:20:34 -04:00
parent 539b2283e7
commit 6a4524b2e2
8 changed files with 226 additions and 35 deletions

View File

@@ -1,4 +1,6 @@
using Hardcodet.Wpf.TaskbarNotification; using Common.Native;
using FloatingStatusWindowLibrary.Properties;
using Hardcodet.Wpf.TaskbarNotification;
using System; using System;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@@ -15,6 +17,9 @@ namespace FloatingStatusWindowLibrary
private readonly MainWindow _mainWindow; private readonly MainWindow _mainWindow;
private readonly TaskbarIcon _taskbarIcon; private readonly TaskbarIcon _taskbarIcon;
private readonly MenuItem _allWindowsMenuItem;
private readonly Separator _allWindowsSeparator;
private readonly MenuItem _lockMenuItem; private readonly MenuItem _lockMenuItem;
private readonly MenuItem _autoStartMenuItem; private readonly MenuItem _autoStartMenuItem;
@@ -27,14 +32,34 @@ namespace FloatingStatusWindowLibrary
var contextMenu = new ContextMenu(); var contextMenu = new ContextMenu();
contextMenu.Opened += HandleContextMenuOpened; 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); contextMenu.Items.Add(optionsMenu);
_lockMenuItem = new MenuItem _lockMenuItem = new MenuItem
{ {
Name = "contextMenuItemLocked", Name = "contextMenuItemLocked",
IsChecked = false, IsChecked = false,
Header = Properties.Resources.ContextMenuLocked Header = Resources.ContextMenuLocked
}; };
_lockMenuItem.Click += HandleLockedMenuItemClicked; _lockMenuItem.Click += HandleLockedMenuItemClicked;
optionsMenu.Items.Add(_lockMenuItem); optionsMenu.Items.Add(_lockMenuItem);
@@ -47,7 +72,7 @@ namespace FloatingStatusWindowLibrary
{ {
Name = "contextMenuItemAutoStart", Name = "contextMenuItemAutoStart",
IsChecked = StartManager.AutoStartEnabled, IsChecked = StartManager.AutoStartEnabled,
Header = Properties.Resources.ContextMenuAutoStart Header = Resources.ContextMenuAutoStart
}; };
_autoStartMenuItem.Click += (sender, args) => StartManager.AutoStartEnabled = !StartManager.AutoStartEnabled; _autoStartMenuItem.Click += (sender, args) => StartManager.AutoStartEnabled = !StartManager.AutoStartEnabled;
@@ -56,10 +81,10 @@ namespace FloatingStatusWindowLibrary
optionsMenu.Items.Add(new Separator()); optionsMenu.Items.Add(new Separator());
var menuItem = new MenuItem menuItem = new MenuItem
{ {
Name = "contextMenuChangeAppearance", Name = "contextMenuChangeAppearance",
Header = Properties.Resources.ContextMenuChangeAppearance Header = Resources.ContextMenuChangeAppearance
}; };
menuItem.Click += HandleChangeAppearancemMenuItemClick; menuItem.Click += HandleChangeAppearancemMenuItemClick;
optionsMenu.Items.Add(menuItem); optionsMenu.Items.Add(menuItem);
@@ -69,7 +94,7 @@ namespace FloatingStatusWindowLibrary
menuItem = new MenuItem menuItem = new MenuItem
{ {
Name = "contextMenuItemExit", Name = "contextMenuItemExit",
Header = Properties.Resources.ContextMenuExit Header = Resources.ContextMenuExit
}; };
menuItem.Click += HandleExitMenuItemClick; menuItem.Click += HandleExitMenuItemClick;
contextMenu.Items.Add(menuItem); contextMenu.Items.Add(menuItem);
@@ -117,6 +142,9 @@ namespace FloatingStatusWindowLibrary
if (_autoStartMenuItem != null) if (_autoStartMenuItem != null)
_autoStartMenuItem.IsChecked = StartManager.AutoStartEnabled; _autoStartMenuItem.IsChecked = StartManager.AutoStartEnabled;
_allWindowsMenuItem.Visibility = WindowManager.GetWindowList().Count == 0 ? Visibility.Collapsed : Visibility.Visible;
_allWindowsSeparator.Visibility = _allWindowsMenuItem.Visibility;
} }
public void SetText(string text) public void SetText(string text)

View File

@@ -73,6 +73,7 @@
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="StartManager.cs" /> <Compile Include="StartManager.cs" />
<Compile Include="WindowManager.cs" />
<Compile Include="WindowSettings.cs" /> <Compile Include="WindowSettings.cs" />
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>

View File

@@ -1,10 +1,11 @@
using System; using Common.Wpf.Windows;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shell; using System.Windows.Shell;
using Common.Native; using System.Windows.Threading;
namespace FloatingStatusWindowLibrary namespace FloatingStatusWindowLibrary
{ {
@@ -13,6 +14,7 @@ namespace FloatingStatusWindowLibrary
private const int WindowCaptionHeight = 24; private const int WindowCaptionHeight = 24;
private readonly WindowChrome _windowChrome; private readonly WindowChrome _windowChrome;
private readonly Dispatcher _dispatcher;
private WindowSettings _windowSettings; private WindowSettings _windowSettings;
public WindowSettings WindowSettings public WindowSettings WindowSettings
@@ -44,6 +46,8 @@ namespace FloatingStatusWindowLibrary
{ {
InitializeComponent(); InitializeComponent();
_dispatcher = Dispatcher.CurrentDispatcher;
// Create and set the window chrome // Create and set the window chrome
_windowChrome = new WindowChrome { CaptionHeight = WindowCaptionHeight }; _windowChrome = new WindowChrome { CaptionHeight = WindowCaptionHeight };
WindowChrome.SetWindowChrome(this, _windowChrome); WindowChrome.SetWindowChrome(this, _windowChrome);
@@ -71,6 +75,30 @@ namespace FloatingStatusWindowLibrary
_windowSettings.Apply(); _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) protected override void OnLocationChanged(EventArgs e)
{ {
base.OnLocationChanged(e); base.OnLocationChanged(e);
@@ -85,36 +113,14 @@ namespace FloatingStatusWindowLibrary
_windowSettings.Size = new Size(Width, Height); _windowSettings.Size = new Size(Width, Height);
} }
private List<Rect> _windowList; protected override List<WindowInformation> OtherWindows
private IntPtr _windowHandle;
protected override List<Rect> OtherWindows
{ {
get get
{ {
_windowList = new List<Rect>(); var windowHandle = new WindowInteropHelper(this).Handle;
_windowHandle = new WindowInteropHelper(this).Handle;
Functions.User32.EnumWindows(EnumWindowProc, IntPtr.Zero); return WindowManager.GetWindowList(windowHandle);
return _windowList;
} }
} }
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;
}
} }
} }

View File

@@ -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> /// <summary>
/// Looks up a localized string similar to Bottom. /// Looks up a localized string similar to Bottom.
/// </summary> /// </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> /// <summary>
/// Looks up a localized string similar to Exit. /// Looks up a localized string similar to Exit.
/// </summary> /// </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> /// <summary>
/// Looks up a localized string similar to Locked. /// Looks up a localized string similar to Locked.
/// </summary> /// </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> /// <summary>
/// Looks up a localized string similar to Font _name:. /// Looks up a localized string similar to Font _name:.
/// </summary> /// </summary>
@@ -221,5 +257,14 @@ namespace FloatingStatusWindowLibrary.Properties {
return ResourceManager.GetString("VerticalAlignment", resourceCulture); 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);
}
}
} }
} }

View File

@@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="AllWindowsMenu" xml:space="preserve">
<value>All Windows</value>
</data>
<data name="Bottom" xml:space="preserve"> <data name="Bottom" xml:space="preserve">
<value>Bottom</value> <value>Bottom</value>
</data> </data>
@@ -135,12 +138,21 @@
<data name="ContextMenuChangeAppearance" xml:space="preserve"> <data name="ContextMenuChangeAppearance" xml:space="preserve">
<value>Change Appearance...</value> <value>Change Appearance...</value>
</data> </data>
<data name="ContextMenuClose" xml:space="preserve">
<value>Close</value>
</data>
<data name="ContextMenuExit" xml:space="preserve"> <data name="ContextMenuExit" xml:space="preserve">
<value>Exit</value> <value>Exit</value>
</data> </data>
<data name="ContextMenuLock" xml:space="preserve">
<value>Lock</value>
</data>
<data name="ContextMenuLocked" xml:space="preserve"> <data name="ContextMenuLocked" xml:space="preserve">
<value>Locked</value> <value>Locked</value>
</data> </data>
<data name="ContextMenuUnlock" xml:space="preserve">
<value>Unlock</value>
</data>
<data name="FontName" xml:space="preserve"> <data name="FontName" xml:space="preserve">
<value>Font _name:</value> <value>Font _name:</value>
</data> </data>
@@ -171,4 +183,7 @@
<data name="VerticalAlignment" xml:space="preserve"> <data name="VerticalAlignment" xml:space="preserve">
<value>_Vertical alignment:</value> <value>_Vertical alignment:</value>
</data> </data>
<data name="WindowMenu" xml:space="preserve">
<value>Window</value>
</data>
</root> </root>

View 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);
}
}
}

View File

@@ -33,7 +33,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoWRealmStatusWindow", "..\
{F023A16C-2F13-4A87-A8B7-22C43C4A58A4} = {F023A16C-2F13-4A87-A8B7-22C43C4A58A4} {F023A16C-2F13-4A87-A8B7-22C43C4A58A4} = {F023A16C-2F13-4A87-A8B7-22C43C4A58A4}
EndProjectSection EndProjectSection
EndProject 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 EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Wpf", "..\Common.Wpf\Common.Wpf.csproj", "{0074C983-550E-4094-9E8C-F566FB669297}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Wpf", "..\Common.Wpf\Common.Wpf.csproj", "{0074C983-550E-4094-9E8C-F566FB669297}"
EndProject EndProject
@@ -41,6 +41,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Native", "..\Common.
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenHardwareMonitorLib", "..\..\Public\OpenHardwareMonitor\OpenHardwareMonitorLib.csproj", "{B0397530-545A-471D-BB74-027AE456DF1A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenHardwareMonitorLib", "..\..\Public\OpenHardwareMonitor\OpenHardwareMonitorLib.csproj", "{B0397530-545A-471D-BB74-027AE456DF1A}"
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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|Any CPU.Build.0 = Release|Any CPU
{B0397530-545A-471D-BB74-027AE456DF1A}.Release|x64.ActiveCfg = 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 {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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

6
StartAll.bat Normal file
View 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