Maximize WPF Window on the current screen

后端 未结 10 703
谎友^
谎友^ 2021-01-31 07:35

I have a windowless wpf application, whenever I set the window state as maximized it maximizes it on the primary display.

What I would like to do is have it maximize on

10条回答
  •  不知归路
    2021-01-31 08:32

    A question with 7 upvotes deserves the correct answer. :D

    Use this window instead of normal window and then Maxmize/Minimize/normalize will take care of itself.

    using System;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Interop;
    
    public partial class MyWindow : Window
    {
        public MyWindow ()
        {
            this.InitializeComponent();
    
            this.SourceInitialized += this.OnSourceInitialized;
        }
    
        #endregion
    
        #region Methods
    
        private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case 0x0024:
                    WmGetMinMaxInfo(hwnd, lParam);
                    handled = true;
                    break;
            }
            return (IntPtr)0;
        }
    
        private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
        {
            var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
    
            // Adjust the maximized size and position to fit the work area of the correct monitor
            IntPtr monitor = MonitorFromWindow(hwnd, (int)MonitorFromWindowFlags.MONITOR_DEFAULTTONEAREST);
    
            if (monitor != IntPtr.Zero)
            {
                var monitorInfo = new MONITORINFO();
                GetMonitorInfo(monitor, monitorInfo);
                RECT rcWorkArea = monitorInfo.rcWork;
                RECT rcMonitorArea = monitorInfo.rcMonitor;
                mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
                mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
                mmi.ptMaxSize.x = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
                mmi.ptMaxSize.y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top);
            }
    
            Marshal.StructureToPtr(mmi, lParam, true);
        }
    
        private void OnSourceInitialized(object sender, EventArgs e)
        {
            var window = sender as Window;
    
            if (window != null)
            {
                IntPtr handle = (new WindowInteropHelper(window)).Handle;
                HwndSource.FromHwnd(handle).AddHook(WindowProc);
            }
        }
    }
    

    DLL imports and declarations

    [StructLayout(LayoutKind.Sequential)]
    public struct MINMAXINFO
    {
        public POINT ptReserved;
    
        public POINT ptMaxSize;
    
        public POINT ptMaxPosition;
    
        public POINT ptMinTrackSize;
    
        public POINT ptMaxTrackSize;
    } ;
    
    public enum MonitorFromWindowFlags
    {
        MONITOR_DEFAULTTONEAREST = 0x00000002
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public class MONITORINFO
    {
        public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
    
        public RECT rcMonitor;
    
        public RECT rcWork;
    
        public int dwFlags;
    }
    
    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    public struct RECT
    {
        public int Left;
    
        public int Top;
    
        public int Right;
    
        public int Bottom;
    
        public static readonly RECT Empty;
    
        public int Width
        {
            get
            {
                return Math.Abs(this.Right - this.Left);
            } // Abs needed for BIDI OS
        }
    
        public int Height
        {
            get
            {
                return this.Bottom - this.Top;
            }
        }
    
        public RECT(int left, int top, int right, int bottom)
        {
            this.Left = left;
            this.Top = top;
            this.Right = right;
            this.Bottom = bottom;
        }
    
        public RECT(RECT rcSrc)
        {
            this.Left = rcSrc.Left;
            this.Top = rcSrc.Top;
            this.Right = rcSrc.Right;
            this.Bottom = rcSrc.Bottom;
        }
    
        public bool IsEmpty
        {
            get
            {
                // BUGBUG : On Bidi OS (hebrew arabic) left > right
                return this.Left >= this.Right || this.Top >= this.Bottom;
            }
        }
    
        public override string ToString()
        {
            if (this == Empty)
            {
                return "RECT {Empty}";
            }
            return "RECT { left : " + this.Left + " / top : " + this.Top + " / right : " + this.Right + " / bottom : " +
                   this.Bottom + " }";
        }
    
        public override bool Equals(object obj)
        {
            if (!(obj is RECT))
            {
                return false;
            }
            return (this == (RECT)obj);
        }
    
        public override int GetHashCode()
        {
            return this.Left.GetHashCode() + this.Top.GetHashCode() + this.Right.GetHashCode() +
                   this.Bottom.GetHashCode();
        }
    
        public static bool operator ==(RECT rect1, RECT rect2)
        {
            return (rect1.Left == rect2.Left && rect1.Top == rect2.Top && rect1.Right == rect2.Right &&
                    rect1.Bottom == rect2.Bottom);
        }
    
        public static bool operator !=(RECT rect1, RECT rect2)
        {
            return !(rect1 == rect2);
        }
    }
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
    
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
    

提交回复
热议问题