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.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)

View File

@@ -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>

View File

@@ -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;
}
}
}

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

View File

@@ -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>

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}
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
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