diff options
author | Your Name <you@example.com> | 2019-01-22 21:22:21 +0900 |
---|---|---|
committer | Your Name <you@example.com> | 2019-01-23 00:27:57 +0900 |
commit | c7aa963003dcc953750dd29e2d3c6a47d18a113f (patch) | |
tree | d823efc26ce884042c210d8d8e8e566910bbb767 | |
parent | a68959d6989db62aaa5967ef9b272e0f28a48913 (diff) | |
download | wf-clock-c7aa963003dcc953750dd29e2d3c6a47d18a113f.tar.gz |
fix the case the overlay clock not being top-most
-rw-r--r-- | WarframeClock/OverlayWindow.xaml.cs | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/WarframeClock/OverlayWindow.xaml.cs b/WarframeClock/OverlayWindow.xaml.cs index 8ce8f1c..7b71a6e 100644 --- a/WarframeClock/OverlayWindow.xaml.cs +++ b/WarframeClock/OverlayWindow.xaml.cs @@ -8,7 +8,9 @@ namespace WarframeClock { public partial class OverlayWindow : Window { + private IntPtr windowHandle; private IntPtr targetWindowHandle; + private bool xTopmost; private Native.Rect parentBounds = new Native.Rect() { Top = 0, @@ -17,15 +19,11 @@ namespace WarframeClock Bottom = 300, }; - public IntPtr WindowHandle - { - get; private set; - } - public OverlayWindow() { InitializeComponent(); - WindowHandle = new WindowInteropHelper(this).EnsureHandle(); + windowHandle = new WindowInteropHelper(this).EnsureHandle(); + xTopmost = false; } public void Start() @@ -43,16 +41,11 @@ namespace WarframeClock private void Update() { - var handle = WindowHandle; - - GetTargetWindow(); - if (targetWindowHandle == IntPtr.Zero || - Native.GetWindowRect(targetWindowHandle, out Native.Rect newBounds) == 0) + if (!GetTargetWindow(out Native.Rect newBounds)) { - targetWindowHandle = IntPtr.Zero; if (IsVisible) { - Console.WriteLine($"ClockOverlay ({handle}): Hide"); + Logging("Hide overlay; target window disappeared"); Hide(); } return; @@ -62,27 +55,31 @@ namespace WarframeClock // behind the current foreground window otherwise. var currentActiveWindow = Native.GetForegroundWindow(); if (currentActiveWindow != IntPtr.Zero && - (!IsVisible || currentActiveWindow == targetWindowHandle != Topmost)) + (!IsVisible || currentActiveWindow == targetWindowHandle != xTopmost)) { + // Setting Topmost to false brings the overlay to just + // behind the other top-most window -- above the foreground + // window. This is not what we want to do here. + // So, let's use SetWindowPos directly instead. if (currentActiveWindow == targetWindowHandle) { - Console.WriteLine($"ClockOverlay ({handle}): Overlay is now top-most"); - Topmost = true; + Logging("Overlay is now top-most"); + xTopmost = true; } else { - Console.WriteLine($"ClockOverlay ({handle}): Overlay is now non-top-most, " + - $"behind {currentActiveWindow}"); - - // Setting Topmost to false brings the overlay to just - // behind the other top-most window -- above the foreground - // window. This is not what we want to do here. - // Setting Topmost is still needed to update the private - // backing fields. - Topmost = false; - Native.SetWindowPos(handle, currentActiveWindow, 0, 0, 0, 0, - 0x0001 /* SWP_NOSIZE */ | 0x0002 /* SWP_NOMOVE */ | 0x0010 /* SWP_NOACTIVATE */); + Logging($"Overlay is now non-top-most, behind {currentActiveWindow}"); + xTopmost = false; } + + uint flags = + 0x0001 /* SWP_NOSIZE */ | + 0x0002 /* SWP_NOMOVE */ | + 0x0008 /* SWP_NOREDRAW */ | + 0x0010 /* SWP_NOACTIVATE */ | + 0x0200 /* SWP_NOOWNERZORDER */ | + 0x0400 /* SWP_NOSENDCHANGING */; + Native.SetWindowPos(windowHandle, xTopmost ? (IntPtr)(-1) : currentActiveWindow, 0, 0, 0, 0, flags); } if (!IsVisible || @@ -96,9 +93,8 @@ namespace WarframeClock // Do not use window.Left (and so on) because they're DPI-aware. // We don't want that.... - Console.WriteLine($"ClockOverlay ({handle}): Move window to: " + - $"l={parentBounds.Left};t={parentBounds.Top};w={width};h={height}"); - Native.SetWindowPos(handle, IntPtr.Zero, parentBounds.Left, parentBounds.Top, width, height, + Logging($"Move overlay to: l={parentBounds.Left};t={parentBounds.Top};w={width};h={height}"); + Native.SetWindowPos(windowHandle, IntPtr.Zero, parentBounds.Left, parentBounds.Top, width, height, 0x0004 /* SWP_NOZORDER */); } @@ -107,28 +103,27 @@ namespace WarframeClock OverlayLabel.Content = infoText; if (!IsVisible) { - Console.WriteLine($"ClockOverlay ({handle}): Show"); + Logging("Show overlay"); Show(); } } - private void GetTargetWindow() + private bool GetTargetWindow(out Native.Rect bounds) { if (targetWindowHandle == IntPtr.Zero || Native.IsWindow(targetWindowHandle) == 0) { targetWindowHandle = IntPtr.Zero; - - var ary = System.Diagnostics.Process.GetProcesses(); - foreach (var process in ary) + foreach (var process in System.Diagnostics.Process.GetProcesses()) { - if (process.ProcessName == "Warframe" || process.ProcessName == "Warframe.x64") + if (targetWindowHandle == IntPtr.Zero && + (process.ProcessName == "Warframe" || process.ProcessName == "Warframe.x64")) { try { targetWindowHandle = process.MainWindowHandle; if (targetWindowHandle != IntPtr.Zero) { - Console.WriteLine($"ClockOverlay: Found a process with name={process.ProcessName}; " + + Logging($"Found a process with name={process.ProcessName}; " + $"MainWindowHandle={targetWindowHandle}"); } } @@ -140,6 +135,28 @@ namespace WarframeClock process.Dispose(); } } + + if (targetWindowHandle != IntPtr.Zero) + { + if (Native.GetWindowRect(targetWindowHandle, out bounds) == 0) + { + Logging($"GetWindowRect failed; aborting this cycle"); + targetWindowHandle = IntPtr.Zero; + return false; + } + return true; + } + else + { + // Suppress compile error; caller must not use the value + bounds = new Native.Rect(); + return false; + } + } + + private void Logging(string message) + { + Console.WriteLine($"ClockOverlay ({windowHandle}): {message}"); } } } |