diff --git a/Scripts/GUI/Show-MainWindow.ps1 b/Scripts/GUI/Show-MainWindow.ps1 index 409b02d..c022240 100644 --- a/Scripts/GUI/Show-MainWindow.ps1 +++ b/Scripts/GUI/Show-MainWindow.ps1 @@ -14,16 +14,52 @@ function Show-MainWindow { [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] private struct POINT { public int x, y; } + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern System.IntPtr MonitorFromWindow(System.IntPtr hwnd, uint dwFlags); + + [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] + private static extern bool GetMonitorInfo(System.IntPtr hMonitor, ref MONITORINFO lpmi); + + [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] + private struct RECT { + public int Left, Top, Right, Bottom; + } + + [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Auto)] + private struct MONITORINFO { + public int cbSize; + public RECT rcMonitor; + public RECT rcWork; + public uint dwFlags; + } + public static System.IntPtr WmGetMinMaxInfoHook( System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) { if (msg == 0x0024) { // WM_GETMINMAXINFO - var wa = System.Windows.Forms.Screen.FromHandle(hwnd).WorkingArea; var mmi = (MINMAXINFO)System.Runtime.InteropServices.Marshal.PtrToStructure( lParam, typeof(MINMAXINFO)); - mmi.ptMaxPosition.x = wa.Left; - mmi.ptMaxPosition.y = wa.Top; - mmi.ptMaxSize.x = wa.Width; - mmi.ptMaxSize.y = wa.Height; + + const uint MONITOR_DEFAULTTONEAREST = 0x00000002; + var monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + var monitorInfo = new MONITORINFO(); + monitorInfo.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(MONITORINFO)); + + if (monitor != System.IntPtr.Zero && GetMonitorInfo(monitor, ref monitorInfo)) { + mmi.ptMaxPosition.x = monitorInfo.rcWork.Left - monitorInfo.rcMonitor.Left; + mmi.ptMaxPosition.y = monitorInfo.rcWork.Top - monitorInfo.rcMonitor.Top; + mmi.ptMaxSize.x = monitorInfo.rcWork.Right - monitorInfo.rcWork.Left; + mmi.ptMaxSize.y = monitorInfo.rcWork.Bottom - monitorInfo.rcWork.Top; + } + else { + var screen = System.Windows.Forms.Screen.FromHandle(hwnd); + var wa = screen.WorkingArea; + var bounds = screen.Bounds; + mmi.ptMaxPosition.x = wa.Left - bounds.Left; + mmi.ptMaxPosition.y = wa.Top - bounds.Top; + mmi.ptMaxSize.x = wa.Width; + mmi.ptMaxSize.y = wa.Height; + } + System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, lParam, true); } return System.IntPtr.Zero; @@ -66,19 +102,28 @@ function Show-MainWindow { $normalWindowShadow = $mainBorder.Effect $initialNormalMaxWidth = 1400.0 + $convertScreenPointToDip = { + param( + [double]$x, + [double]$y + ) + + $source = [System.Windows.PresentationSource]::FromVisual($window) + if ($null -eq $source -or $null -eq $source.CompositionTarget) { + return [System.Windows.Point]::new($x, $y) + } + + return $source.CompositionTarget.TransformFromDevice.Transform([System.Windows.Point]::new($x, $y)) + } + $convertScreenPixelsToDip = { param( [double]$width, [double]$height ) - $source = [System.Windows.PresentationSource]::FromVisual($window) - if ($null -eq $source -or $null -eq $source.CompositionTarget) { - return [System.Windows.Size]::new($width, $height) - } - - $topLeft = $source.CompositionTarget.TransformFromDevice.Transform([System.Windows.Point]::new(0, 0)) - $bottomRight = $source.CompositionTarget.TransformFromDevice.Transform([System.Windows.Point]::new($width, $height)) + $topLeft = & $convertScreenPointToDip 0 0 + $bottomRight = & $convertScreenPointToDip $width $height return [System.Windows.Size]::new($bottomRight.X - $topLeft.X, $bottomRight.Y - $topLeft.Y) } @@ -122,9 +167,10 @@ function Show-MainWindow { return } + $workingAreaTopLeftDip = & $convertScreenPointToDip $screen.WorkingArea.Left $screen.WorkingArea.Top $workingAreaDip = & $convertScreenPixelsToDip $screen.WorkingArea.Width $screen.WorkingArea.Height $window.Width = [Math]::Min($initialNormalMaxWidth, $workingAreaDip.Width) - $window.Left = $screen.WorkingArea.Left + (($workingAreaDip.Width - $window.Width) / 2) + $window.Left = $workingAreaTopLeftDip.X + (($workingAreaDip.Width - $window.Width) / 2) } $window.Add_SourceInitialized({