diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2019-02-15 03:32:47 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2019-02-15 03:37:32 +0900 |
commit | de84c8e07dd20668108b366c853215217b886b64 (patch) | |
tree | 219d438ff60c6c543946e29b65f1ef5723f87fae | |
parent | 166dc33ddcbd7c0e14a260c30a0be3d7cb11dc95 (diff) | |
download | wf-clock-de84c8e07dd20668108b366c853215217b886b64.tar.gz |
cleanup project, part 2
-rw-r--r-- | WarframeClock/App.xaml.cs | 41 | ||||
-rw-r--r-- | WarframeClock/Clock.cs | 3 | ||||
-rw-r--r-- | WarframeClock/Native.cs | 9 | ||||
-rw-r--r-- | WarframeClock/OverlayWindow.xaml.cs | 76 | ||||
-rw-r--r-- | WarframeClock/WorldState.cs | 20 |
5 files changed, 70 insertions, 79 deletions
diff --git a/WarframeClock/App.xaml.cs b/WarframeClock/App.xaml.cs index 4e6a437..81b9ba0 100644 --- a/WarframeClock/App.xaml.cs +++ b/WarframeClock/App.xaml.cs @@ -10,7 +10,7 @@ namespace WarframeClock /// </summary> public partial class App : Application { - public static readonly string VersionString = "Warframe Clock Overlay 2019-01-22"; + public static readonly string VersionString = "Warframe Clock Overlay 2019-02-14"; public static readonly bool UseWorldStatePhp = true; private Timer worldStateFetchTimer; @@ -20,19 +20,9 @@ namespace WarframeClock { base.OnStartup(e); - try - { - if (UseWorldStatePhp) - StartWorldStateFetch(); - StartNotifyIcon(); - } - catch (Exception ex) - { - Console.WriteLine($"Main: Uncaught exception: {ex.Message}"); - Console.WriteLine(ex.StackTrace); - MessageBox.Show($"Main: Uncaught exception: {ex.Message}\n{ex.StackTrace}"); - Terminate(); - } + if (UseWorldStatePhp) + StartWorldStateFetch(); + StartNotifyIcon(); } private void StartWorldStateFetch() @@ -41,38 +31,40 @@ namespace WarframeClock { try { - var worldState = WorldState.Fetch(); - var cetusSyndicate = worldState.SyndicateMissions.FirstOrDefault(mi => mi.Tag == "CetusSyndicate"); + var worldState = WorldState.Fetch().Result; + var cetusSyndicate = + worldState.SyndicateMissions.FirstOrDefault(mi => mi.Tag == "CetusSyndicate"); if (cetusSyndicate == null) { Console.WriteLine("WorldState: CetusSyndicate missions not found"); return; } + var cetusExpiry = cetusSyndicate.Expiry.Date.NumberLong; Console.WriteLine($"WorldState: CetusSyndicate missions expire at {cetusExpiry}"); Clock.CetusExpiry = cetusExpiry; } catch (Exception ex) { - Console.WriteLine($"WorldState: Failed to fetch or parse worldState.php: {ex.ToString()}"); + Console.WriteLine($"WorldState: Failed to fetch or parse worldState.php: {ex}"); Console.WriteLine(ex.StackTrace); } - }, null, 0, 10 * 60 * 1000 /* 10 minutes */); + }, null, TimeSpan.Zero, TimeSpan.FromMinutes(10)); } private void StartNotifyIcon() { var iconMenu = new System.Windows.Forms.ContextMenu(); - notifyIcon = new System.Windows.Forms.NotifyIcon() + iconMenu.MenuItems.Add(new System.Windows.Forms.MenuItem(VersionString) { Enabled = false }); + iconMenu.MenuItems.Add(new System.Windows.Forms.MenuItem("Quit", (_, __) => Terminate())); + + notifyIcon = new System.Windows.Forms.NotifyIcon { Text = "Warframe Clock", ContextMenu = iconMenu, - Icon = WarframeClock.Properties.Resources.TrayIcon + Icon = WarframeClock.Properties.Resources.TrayIcon, + Visible = true }; - - iconMenu.MenuItems.Add(new System.Windows.Forms.MenuItem(VersionString) { Enabled = false }); - iconMenu.MenuItems.Add(new System.Windows.Forms.MenuItem("Quit", (_, __) => Terminate())); - notifyIcon.Visible = true; } private void Terminate() @@ -80,7 +72,6 @@ namespace WarframeClock notifyIcon.Dispose(); worldStateFetchTimer.Change(Timeout.Infinite, Timeout.Infinite); MainWindow?.Close(); - Environment.Exit(0); } } } diff --git a/WarframeClock/Clock.cs b/WarframeClock/Clock.cs index 956cfaa..cf500b1 100644 --- a/WarframeClock/Clock.cs +++ b/WarframeClock/Clock.cs @@ -35,6 +35,9 @@ namespace WarframeClock return $"Vallis: ☁[→❄️] {GetReadableTimeSpan(dayStart + 1600 - currentTime)}"; } + public static string OverlayString() => + $"{CetusExpiryString()} {VallisExpiryString()}"; + private static double GetCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds / 1000; diff --git a/WarframeClock/Native.cs b/WarframeClock/Native.cs index c83bac9..8fccd5c 100644 --- a/WarframeClock/Native.cs +++ b/WarframeClock/Native.cs @@ -6,17 +6,16 @@ namespace WarframeClock class Native { [DllImport("user32.dll")] - public static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] - public static extern int IsWindow(IntPtr hWnd); - - [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] - public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect); + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect); [StructLayout(LayoutKind.Sequential)] public struct Rect diff --git a/WarframeClock/OverlayWindow.xaml.cs b/WarframeClock/OverlayWindow.xaml.cs index e019dde..520828e 100644 --- a/WarframeClock/OverlayWindow.xaml.cs +++ b/WarframeClock/OverlayWindow.xaml.cs @@ -1,8 +1,8 @@ using System; -using System.Threading; -using System.Threading.Tasks; +using System.Diagnostics; using System.Windows; using System.Windows.Interop; +using System.Windows.Threading; namespace WarframeClock { @@ -11,16 +11,11 @@ namespace WarframeClock /// </summary> public partial class OverlayWindow : Window { - private IntPtr windowHandle; - private IntPtr targetWindowHandle; + private readonly IntPtr windowHandle; + private readonly DispatcherTimer updateTimer; private bool xTopmost; - private Native.Rect parentBounds = new Native.Rect() - { - Top = 0, - Left = 0, - Right = 300, - Bottom = 300, - }; + private IntPtr targetWindowHandle; + private Native.Rect parentBounds; public OverlayWindow() { @@ -28,20 +23,20 @@ namespace WarframeClock windowHandle = new WindowInteropHelper(this).EnsureHandle(); xTopmost = false; - var updateLoop = Task.Factory.StartNew(() => - { - while (true) - { - Dispatcher.BeginInvoke(new Action(() => Update())); - Thread.Sleep(100); - } - }); - System.Windows.Threading.Dispatcher.Run(); + updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(100), DispatcherPriority.Background, + UpdateTimerTick, Dispatcher.CurrentDispatcher); + updateTimer.Start(); } - private void Update() + protected override void OnClosed(EventArgs e) { - if (!GetTargetWindow(out Native.Rect newBounds)) + base.OnClosed(e); + updateTimer.Stop(); + } + + private void UpdateTimerTick(object sender, EventArgs e) + { + if (!GetTargetWindow(out var newBounds)) { if (IsVisible) { @@ -79,9 +74,10 @@ namespace WarframeClock 0x0010 /* SWP_NOACTIVATE */ | 0x0200 /* SWP_NOOWNERZORDER */ | 0x0400 /* SWP_NOSENDCHANGING */; - Native.SetWindowPos(windowHandle, xTopmost ? (IntPtr)(-1) : currentActiveWindow, 0, 0, 0, 0, flags); + Native.SetWindowPos(windowHandle, xTopmost ? (IntPtr) (-1) : currentActiveWindow, 0, 0, 0, 0, flags); } + // Adjust window position if (!IsVisible || parentBounds.Left != newBounds.Left || parentBounds.Right != newBounds.Right || parentBounds.Top != newBounds.Top || parentBounds.Bottom != newBounds.Bottom) @@ -99,8 +95,7 @@ namespace WarframeClock } // Render text - var infoText = $"{Clock.CetusExpiryString()} {Clock.VallisExpiryString()}"; - OverlayLabel.Content = infoText; + OverlayLabel.Content = Clock.OverlayString(); if (!IsVisible) { Logging("Show overlay"); @@ -110,10 +105,9 @@ namespace WarframeClock private bool GetTargetWindow(out Native.Rect bounds) { - if (targetWindowHandle == IntPtr.Zero || Native.IsWindow(targetWindowHandle) == 0) + if (targetWindowHandle == IntPtr.Zero) { - targetWindowHandle = IntPtr.Zero; - foreach (var process in System.Diagnostics.Process.GetProcesses()) + foreach (var process in Process.GetProcesses()) { if (targetWindowHandle == IntPtr.Zero && (process.ProcessName == "Warframe" || process.ProcessName == "Warframe.x64")) @@ -124,7 +118,7 @@ namespace WarframeClock if (targetWindowHandle != IntPtr.Zero) { Logging($"Found a process with name={process.ProcessName}; " + - $"MainWindowHandle={targetWindowHandle}"); + $"MainWindowHandle={targetWindowHandle}"); } } catch (Exception) @@ -132,31 +126,31 @@ namespace WarframeClock // Ignore errors; maybe the process is just exiting. Let's retry during the next cycle. } } + 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 + if (targetWindowHandle == IntPtr.Zero) { // Suppress compile error; caller must not use the value bounds = new Native.Rect(); return false; } + + if (!Native.GetWindowRect(targetWindowHandle, out bounds)) + { + Logging($"GetWindowRect failed; aborting this cycle"); + targetWindowHandle = IntPtr.Zero; + return false; + } + + return true; } private void Logging(string message) { - Console.WriteLine($"ClockOverlay ({windowHandle}): {message}"); + Console.WriteLine($"ClockOverlay: {message}"); } } } diff --git a/WarframeClock/WorldState.cs b/WarframeClock/WorldState.cs index b364660..0b87374 100644 --- a/WarframeClock/WorldState.cs +++ b/WarframeClock/WorldState.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Net.Http; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; +using System.Threading.Tasks; namespace WarframeClock { @@ -35,17 +36,20 @@ namespace WarframeClock public long NumberLong { get; set; } } - public static WorldState Fetch() + public static async Task<WorldState> Fetch() { - var httpClient = new HttpClient(); - var res = httpClient.GetAsync("http://content.warframe.com/dynamic/worldState.php").Result; - if (!res.IsSuccessStatusCode) + using (var httpClient = new HttpClient()) { - throw new Exception("WorldState: Could not fetch worldState.php"); - } + var res = await httpClient.GetAsync("http://content.warframe.com/dynamic/worldState.php"); + if (!res.IsSuccessStatusCode) + { + throw new Exception("WorldState: Could not fetch worldState.php"); + } - var serializer = new DataContractJsonSerializer(typeof(WorldState)); - return (WorldState)serializer.ReadObject(res.Content.ReadAsStreamAsync().Result); + var body = await res.Content.ReadAsStreamAsync(); + var serializer = new DataContractJsonSerializer(typeof(WorldState)); + return (WorldState) serializer.ReadObject(body); + } } } } |