在辅助监视器上恢复最大化状态

时间:2016-10-24 04:24:42

标签: c# wpf

当我在辅助监视器上最大化窗口时,我遇到了关于窗口恢复状态的问题。 我在非主屏幕上最大化窗口然后关闭。 重新打开窗口时,它也会最大化,但在主屏幕上最大化。 我希望在非主屏幕(关闭时的屏幕显示窗口)上最大化。

如果你知道,请帮助我。

注意:如果窗口状态正常,窗口将恢复正确的屏幕。

我的代码如下:

npm i istanbul-instrumenter-loader@^0.2.0 --save-dev

1 个答案:

答案 0 :(得分:1)

我们在使用标准WPF工具存储和恢复窗口状态和大小的多屏系统上遇到了很多问题,只要屏幕分配就可以了。

我们致力于创建使用本机WinAPI函数的自定义行为。 这是我们行为的(简化)源代码。您可以在应用程序中使用它而不是WPF工具。

您必须更改窗口放置的存储方式。这可以是提供容器,静态Properties.Settings引用或其他内容的依赖项属性。在下面的代码中,使用静态ApplicationSettings引用作为示例。

class WindowPlacementPersistenceBehavior : Behavior<Window>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.SourceInitialized += this.AssociatedObject_SourceInitialized;
        this.AssociatedObject.Closing += this.AssociatedObject_Closing;
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.SourceInitialized -= this.AssociatedObject_SourceInitialized;
        this.AssociatedObject.Closing -= this.AssociatedObject_Closing;
        base.OnDetaching();
    }

    private void AssociatedObject_Closing(object sender, CancelEventArgs e)
    {
        WINDOWPLACEMENT wp;
        NativeMethods.GetWindowPlacement(new WindowInteropHelper(this.AssociatedObject).Handle, out wp);

        // Here you can store the window placement
        ApplicationSettings.WindowPlacement = wp.ToString();
    }

    private void AssociatedObject_SourceInitialized(object sender, EventArgs e)
    {
        // Here you can load the window placement
        WINDOWPLACEMENT wp = WINDOWPLACEMENT.Parse(ApplicationSettings.WindowPlacement);
        if (wp.ShowCmd == NativeMethods.SW_SHOWMINIMIZED)
        {
            // Don't start in the minimized state
            wp.ShowCmd = NativeMethods.SW_SHOWNORMAL;
        }

        try
        {
            NativeMethods.SetWindowPlacement(new WindowInteropHelper(this.AssociatedObject).Handle, ref wp);
        }
        catch
        {
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

        public static RECT Parse(string input)
        {
            RECT result;
            string[] items = input.Split(';');
            result.Left = int.Parse(items[0]);
            result.Top = int.Parse(items[1]);
            result.Right = int.Parse(items[2]);
            result.Bottom = int.Parse(items[3]);
            return result;
        }

        public override string ToString()
        {
            return this.Left + ";" + this.Top + ";" + this.Right + ";" + this.Bottom;
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int X;
        public int Y;

        public static POINT Parse(string input)
        {
            POINT result;
            string[] items = input.Split(';');
            result.X = int.Parse(items[0]);
            result.Y = int.Parse(items[1]);
            return result;
        }

        public override string ToString()
        {
            return this.X + ";" + this.Y;
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    private struct WINDOWPLACEMENT
    {
        public int Length;
        public int Flags;
        public int ShowCmd;
        public POINT MinPosition;
        public POINT MaxPosition;
        public RECT NormalPosition;

        public static WINDOWPLACEMENT Parse(string input)
        {
            WINDOWPLACEMENT result = default(WINDOWPLACEMENT);
            result.Length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
            try
            {
                string[] items = input.Split('/');
                result.Flags = int.Parse(items[0]);
                result.ShowCmd = int.Parse(items[1]);
                result.MinPosition = POINT.Parse(items[2]);
                result.MaxPosition = POINT.Parse(items[3]);
                result.NormalPosition = RECT.Parse(items[4]);
            }
            catch
            {
            }

            return result;
        }

        public override string ToString()
        {
            return this.Flags + "/" + this.ShowCmd + "/" + this.MinPosition.ToString() + "/" + this.MaxPosition.ToString() + "/" + this.NormalPosition.ToString();
        }
    }

    private static class NativeMethods
    {
        public const int SW_SHOWNORMAL = 1;
        public const int SW_SHOWMINIMIZED = 2;

        [DllImport("user32.dll")]
        public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll")]
        public static extern bool GetWindowPlacement(IntPtr hWnd, [Out] out WINDOWPLACEMENT lpwndpl);
    }
}

要使用此行为,只需将其添加到XAML中的窗口:

<Window
    xmlns:v="clr-namespace:YourNameSpace"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Behaviors>
    <v:WindowPlacementPersistenceBehavior />
</i:Interaction.Behaviors>
</Window>