diff --git a/ClientApp/ClientApp.csproj b/ClientApp/ClientApp.csproj index e60c9f4..c20363f 100644 --- a/ClientApp/ClientApp.csproj +++ b/ClientApp/ClientApp.csproj @@ -8,12 +8,16 @@ + + + Always + Always diff --git a/ClientApp/Images/gradient-geometric-shape-background_78532-374.jpg b/ClientApp/Images/CoolBackground.jpg similarity index 100% rename from ClientApp/Images/gradient-geometric-shape-background_78532-374.jpg rename to ClientApp/Images/CoolBackground.jpg diff --git a/ClientApp/MagicCode/WindowResizer.cs b/ClientApp/MagicCode/WindowResizer.cs new file mode 100644 index 0000000..c997d89 --- /dev/null +++ b/ClientApp/MagicCode/WindowResizer.cs @@ -0,0 +1,212 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Interop; + +namespace ClientApp.MagicCode +{ + /// + /// Fixes the issue with Windows of Style covering the taskbar + /// + public class WindowResizer + { + #region Private Members + + /// + /// The window to handle the resizing for + /// + private Window mWindow; + + #endregion + + #region Dll Imports + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool GetCursorPos(out POINT lpPoint); + + [DllImport("user32.dll")] + static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi); + + [DllImport("user32.dll", SetLastError = true)] + static extern IntPtr MonitorFromPoint(POINT pt, MonitorOptions dwFlags); + + #endregion + + #region Constructor + + /// + /// Default constructor + /// + /// The window to monitor and correctly maximize + /// The callback for the host to adjust the maximum available size if needed + public WindowResizer(Window window) + { + mWindow = window; + + // Listen out for source initialized to setup + mWindow.SourceInitialized += Window_SourceInitialized; + } + + #endregion + + #region Initialize + + /// + /// Initialize and hook into the windows message pump + /// + /// + /// + private void Window_SourceInitialized(object sender, System.EventArgs e) + { + // Get the handle of this window + var handle = (new WindowInteropHelper(mWindow)).Handle; + var handleSource = HwndSource.FromHwnd(handle); + + // If not found, end + if (handleSource == null) + return; + + // Hook into it's Windows messages + handleSource.AddHook(WindowProc); + } + + #endregion + + #region Windows Proc + + /// + /// Listens out for all windows messages for this window + /// + /// + /// + /// + /// + /// + /// + private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + switch (msg) + { + // Handle the GetMinMaxInfo of the Window + case 0x0024:/* WM_GETMINMAXINFO */ + WmGetMinMaxInfo(hwnd, lParam); + handled = true; + break; + } + + return (IntPtr)0; + } + + #endregion + + /// + /// Get the min/max window size for this window + /// Correctly accounting for the taskbar size and position + /// + /// + /// + private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) + { + POINT lMousePosition; + GetCursorPos(out lMousePosition); + + IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY); + MONITORINFO lPrimaryScreenInfo = new MONITORINFO(); + if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false) + { + return; + } + + IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST); + + MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); + + if (lPrimaryScreen.Equals(lCurrentScreen) == true) + { + lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left; + lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top; + lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left; + lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top; + } + else + { + lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left; + lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top; + lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left; + lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top; + } + + // Now we have the max size, allow the host to tweak as needed + Marshal.StructureToPtr(lMmi, lParam, true); + } + } + + #region Dll Helper Structures + + enum MonitorOptions : uint + { + MONITOR_DEFAULTTONULL = 0x00000000, + MONITOR_DEFAULTTOPRIMARY = 0x00000001, + MONITOR_DEFAULTTONEAREST = 0x00000002 + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class MONITORINFO + { + public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); + public Rectangle rcMonitor = new Rectangle(); + public Rectangle rcWork = new Rectangle(); + public int dwFlags = 0; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Rectangle + { + public int Left, Top, Right, Bottom; + + public Rectangle(int left, int top, int right, int bottom) + { + this.Left = left; + this.Top = top; + this.Right = right; + this.Bottom = bottom; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct MINMAXINFO + { + public POINT ptReserved; + public POINT ptMaxSize; + public POINT ptMaxPosition; + public POINT ptMinTrackSize; + public POINT ptMaxTrackSize; + }; + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + /// + /// x coordinate of point. + /// + public int X; + /// + /// y coordinate of point. + /// + public int Y; + + /// + /// Construct a point of coordinates (x,y). + /// + public POINT(int x, int y) + { + this.X = x; + this.Y = y; + } + } + + #endregion +} \ No newline at end of file diff --git a/ClientApp/ViewModels/MainWindowViewModel.cs b/ClientApp/ViewModels/MainWindowViewModel.cs index 0e87c8a..c46eb38 100644 --- a/ClientApp/ViewModels/MainWindowViewModel.cs +++ b/ClientApp/ViewModels/MainWindowViewModel.cs @@ -1,4 +1,5 @@ -using ClientApp.Models; +using ClientApp.MagicCode; +using ClientApp.Models; using ClientApp.Utils; using GalaSoft.MvvmLight.Command; using System; @@ -114,6 +115,8 @@ namespace ClientApp.ViewModels this.MaximizeCommand = new RelayCommand(() => this.mWindow.WindowState ^= WindowState.Maximized); this.CloseCommand = new RelayCommand(() => this.mWindow.Close()); this.MenuCommand = new RelayCommand(() => SystemCommands.ShowSystemMenu(this.mWindow, GetMousePosition())); + + var resizer = new WindowResizer(this.mWindow); } diff --git a/ClientApp/Views/MainWindow.xaml b/ClientApp/Views/MainWindow.xaml index 01a898d..d4acdef 100644 --- a/ClientApp/Views/MainWindow.xaml +++ b/ClientApp/Views/MainWindow.xaml @@ -47,9 +47,7 @@ - - @@ -80,8 +78,13 @@ + + + + + - + - - - + + +