如何找到最大化窗口的位置? [英] How can I find the position of a maximized window?

查看:37
本文介绍了如何找到最大化窗口的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道最大化的窗口的位置.

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

WPF 窗口具有指定窗口位置的 Top 和 Left 属性.但是,如果您最大化窗口,这些属性会使窗口的值保持在正常状态.

WPF Window has Top and Left properties that specifies the window's location. However, if you maximize the window these properties keep the values of the window in it's normal state.

如果您在单屏设置上运行,最大化位置自然是 (0,0).但是,如果您有多个屏幕,则不一定如此.如果您在主屏幕上将其最大化,则该窗口将仅具有 (0,0) 位置.

If you´re running on a single-screen setup, the maximized position is naturally (0,0). However, if you have multiple screens that is not necessarily true. The window will only have position (0,0) if you have it maximized on the main screen.

那么...有没有办法找出最大化窗口的位置(最好与 Top 和 Left 属性使用相同的逻辑单元)?

So... is there any way to find out the position of a maximized window (preferably in the same logical units as the Top and Left properties)?

推荐答案

这是我根据之前的讨论提出的解决方案(谢谢!).

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

这个解决方案...

  • 返回窗口在当前状态下的位置
  • 处理所有窗口状态(最大化、最小化、恢复)
  • 不依赖于 Windows 窗体(但受其启发)
  • 使用窗口句柄可靠地确定正确的监视器

主要方法 GetAbsolutePosition 在此处作为扩展方法实现.如果您有一个名为 myWindowWindow,请像这样调用它:

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();

完整代码如下:

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);
    }
}

这篇关于如何找到最大化窗口的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆