How can I find the position of a maximized window?

前端 未结 7 1545
走了就别回头了
走了就别回头了 2020-12-30 05:23

I need to know the position of a window that is maximized.

WPF Window has Top and Left properties that specifies the window\'s location. However, if you maximize the

7条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-30 05:43

    Here's the solution I came up with based on previous discussion here (thanks!).

    This solution...

    • returns the position of a window in its current state
    • handles all window states (maximized, minimized, restored)
    • does not depend on Windows Forms (but is inspired by it)
    • uses the window handle to reliably determine the correct monitor

    The main method GetAbsolutePosition is implemented here as an extension method. If you have a Window called myWindow, call it like this:

    Point p = myWindow.GetAbsolutePosition();
    

    Here's the complete code:

    using System;
    using System.Windows;
    using System.Windows.Interop;
    using System.Runtime.InteropServices;
    
    static class OSInterop
    {
        [DllImport("user32.dll")]
        public static extern int GetSystemMetrics(int smIndex);
        public const int SM_CMONITORS = 80;
    
        [DllImport("user32.dll")]
        public static extern bool SystemParametersInfo(int nAction, int nParam, ref RECT rc, int nUpdate);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetMonitorInfo(HandleRef hmonitor, [In, Out] MONITORINFOEX info);
    
        [DllImport("user32.dll")]
        public static extern IntPtr MonitorFromWindow(HandleRef handle, int flags);
    
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
            public int width { get { return right - left; } }
            public int height { get { return bottom - top; } }
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        public class MONITORINFOEX
        {
            public int cbSize = Marshal.SizeOf(typeof(MONITORINFOEX));
            public RECT rcMonitor = new RECT();
            public RECT rcWork = new RECT();
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public char[] szDevice = new char[32];
            public int dwFlags;
        }
    }
    
    static class WPFExtensionMethods
    {
        public static Point GetAbsolutePosition(this Window w)
        {
            if (w.WindowState != WindowState.Maximized)
                return new Point(w.Left, w.Top);
    
            Int32Rect r;
            bool multimonSupported = OSInterop.GetSystemMetrics(OSInterop.SM_CMONITORS) != 0;
            if (!multimonSupported)
            {
                OSInterop.RECT rc = new OSInterop.RECT();
                OSInterop.SystemParametersInfo(48, 0, ref rc, 0);
                r = new Int32Rect(rc.left, rc.top, rc.width, rc.height);
            }
            else
            {
                WindowInteropHelper helper = new WindowInteropHelper(w);
                IntPtr hmonitor = OSInterop.MonitorFromWindow(new HandleRef((object)null, helper.EnsureHandle()), 2);
                OSInterop.MONITORINFOEX info = new OSInterop.MONITORINFOEX();
                OSInterop.GetMonitorInfo(new HandleRef((object)null, hmonitor), info);
                r = new Int32Rect(info.rcWork.left, info.rcWork.top, info.rcWork.width, info.rcWork.height);
            }
            return new Point(r.X, r.Y);
        }
    }
    

提交回复
热议问题