WPF的MetroWindow风格窗口的SaveWindowPosition属性(自动保存前回窗口位置)的原理调查

 

<MetroControls:MetroWindow x:Class="MainWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
        SaveWindowPosition="True"
...>

这里的SaveWindowPosition属性设置为True之后,就可以实现窗口前回最后停留的位置信息的保存和读取。

经过调查发现, MahApps.Metro.Controls里,实现窗口位置读存的函数是LoadWindowState和SaveWindowState。

 

        protected virtual void LoadWindowState()
        {
            if (this._settings == null)
            {
                return;
            }
            this._settings.Reload();
            if (!this._settings.Placement.HasValue || this._settings.Placement.Value.normalPosition.IsEmpty)
            {
                return;
            }
            try
            {
                WINDOWPLACEMENT value = this._settings.Placement.Value;
                value.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
                value.flags = 0;
                value.showCmd = ((value.showCmd == 2) ? 1 : value.showCmd);
                UnsafeNativeMethods.SetWindowPlacement(new WindowInteropHelper(this._window).Handle, ref value);
            }
            catch (Exception innerException)
            {
                throw new MahAppsException("Failed to set the window state from the settings file", innerException);
            }
        }

        protected virtual void SaveWindowState()
        {
            if (this._settings == null)
            {
                return;
            }
            IntPtr handle = new WindowInteropHelper(this._window).Handle;
            WINDOWPLACEMENT wINDOWPLACEMENT = default(WINDOWPLACEMENT);
            wINDOWPLACEMENT.length = Marshal.SizeOf(wINDOWPLACEMENT);
            UnsafeNativeMethods.GetWindowPlacement(handle, ref wINDOWPLACEMENT);
            if (wINDOWPLACEMENT.showCmd != 0 && wINDOWPLACEMENT.length > 0)
            {
                RECT normalPosition;
                if (wINDOWPLACEMENT.showCmd == 1 && UnsafeNativeMethods.GetWindowRect(handle, out normalPosition))
                {
                    wINDOWPLACEMENT.normalPosition = normalPosition;
                }
                if (!wINDOWPLACEMENT.normalPosition.IsEmpty)
                {
                    this._settings.Placement = new WINDOWPLACEMENT?(wINDOWPLACEMENT);
                }
            }
            this._settings.Save();
        }

进一步可以知道,窗口位置信息的获取是使用GetWindowPlacement函数,重新设回前回 位置使用的是SetWindowPlacement函数。可以知道,这两个函数是Windows的API函数。

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

即,WPF的MetroWindow风格窗口的位置自动记忆功能。使用的是GetWindowPlacement和GetWindowRect系统函数取得窗口位置信息并保存,下 

次启动窗口时,取读取前回的位置信息,并用SetWindowPlacement系统函数设置回去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值