Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >记住窗口位置、大小和状态[在Win + Arrow对齐时](使用多个显示器)

记住窗口位置、大小和状态[在Win + Arrow对齐时](使用多个显示器)
EN

Stack Overflow用户
提问于 2015-01-08 10:44:58
回答 1查看 2.2K关注 0票数 9

在我们的项目中,我们保存了窗口大小、位置和最小化/最大化设置,这样我们可以在重新打开窗口时以完全相同的位置和大小打开窗口。使用这篇文章底部的Window-Behavior-class,所有这些都运行得很好。

然而,问题是当我们使用Win-按钮+一个箭头时;这会将屏幕与屏幕的一侧对齐,但这并没有正确地保存在行为中。相反,在我使用Win +箭头对齐屏幕之前,它保存了屏幕的位置和大小,这就是它再次打开的位置。

我尝试在SaveWindowState-method中使用窗口的LeftTopActualWidthActualHeight (注意:此方法中的AssociatedObject就是窗口)。但LeftTop似乎相差了大约20-40像素,而且使用ActualWidthActualHeight和当前屏幕宽度/高度(当使用多个显示器时)来保存右侧和左侧屏幕也有点麻烦。

那么,当用户使用Win +箭头对齐窗口然后关闭窗口时,有没有办法在窗口设置中保存正确的位置和大小?

WindowSettingsBehavior

代码语言:javascript
运行
AI代码解释
复制
using System;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Interop;

namespace NatWa.MidOffice.Behaviors
{
    /// <summary>
    /// Persists a Window's Size, Location and WindowState to UserScopeSettings 
    /// </summary>
    public class WindowSettingsBehavior : Behavior<Window>
    {
        [DllImport("user32.dll")]
        static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref Windowplacement lpwndpl);

        [DllImport("user32.dll")]
        static extern bool GetWindowPlacement(IntPtr hWnd, out Windowplacement lpwndpl);

        // ReSharper disable InconsistentNaming
        const int SW_SHOWNORMAL = 1;
        const int SW_SHOWMINIMIZED = 2;
        // ReSharper restore InconsistentNaming

        internal class WindowApplicationSettings : ApplicationSettingsBase
        {
            public WindowApplicationSettings(WindowSettingsBehavior windowSettingsBehavior)
                : base(windowSettingsBehavior.AssociatedObject.GetType().FullName)
            {
            }

            [UserScopedSetting]
            public Windowplacement? Placement
            {
                get
                {
                    if (this["Placement"] != null)
                    {
                        return ((Windowplacement)this["Placement"]);
                    }
                    return null;
                }
                set
                {
                    this["Placement"] = value;
                }
            }
        }

        /// <summary>
        /// Load the Window Size Location and State from the settings object
        /// </summary>
        private void LoadWindowState()
        {
            Settings.Reload();

            if (Settings.Placement == null) return;
            try
            {
                // Load window placement details for previous application session from application settings.
                // If window was closed on a monitor that is now disconnected from the computer,
                // SetWindowPlacement will place the window onto a visible monitor.
                var wp = Settings.Placement.Value;

                wp.length = Marshal.SizeOf(typeof(Windowplacement));
                wp.flags = 0;
                wp.showCmd = (wp.showCmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : wp.showCmd);
                var hwnd = new WindowInteropHelper(AssociatedObject).Handle;
                SetWindowPlacement(hwnd, ref wp);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Failed to load window state:\r\n{0}", ex);
            }
        }

        /// <summary>
        /// Save the Window Size, Location and State to the settings object
        /// </summary>
        private void SaveWindowState()
        {
            Windowplacement wp;
            var hwnd = new WindowInteropHelper(AssociatedObject).Handle;

            GetWindowPlacement(hwnd, out wp);
            Settings.Placement = wp;
            Settings.Save();
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.Closing += WindowClosing;
            AssociatedObject.SourceInitialized += WindowSourceInitialized;
        }

        private void WindowSourceInitialized(object sender, EventArgs e)
        {
            LoadWindowState();
        }

        private void WindowClosing(object sender, CancelEventArgs e)
        {
            SaveWindowState();
            AssociatedObject.Closing -= WindowClosing;
            AssociatedObject.SourceInitialized -= WindowSourceInitialized;
        }

        private WindowApplicationSettings _windowApplicationSettings;

        internal virtual WindowApplicationSettings CreateWindowApplicationSettingsInstance()
        {
            return new WindowApplicationSettings(this);
        }

        [Browsable(false)]
        internal WindowApplicationSettings Settings
        {
            get { return _windowApplicationSettings
                ?? (_windowApplicationSettings = CreateWindowApplicationSettingsInstance()); }
        }
    }

    #region Save position classes

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        private int _left;
        private int _top;
        private int _right;
        private int _bottom;

        public Rect(int left, int top, int right, int bottom)
        {
            _left = left;
            _top = top;
            _right = right;
            _bottom = bottom;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is Rect)) return base.Equals(obj);

            var rect = (Rect)obj;
            return rect._bottom == _bottom &&
                   rect._left == _left &&
                   rect._right == _right &&
                   rect._top == _top;
        }

        public override int GetHashCode()
        {
            return _bottom.GetHashCode() ^
                   _left.GetHashCode() ^
                   _right.GetHashCode() ^
                   _top.GetHashCode();
        }

        public static bool operator ==(Rect a, Rect b)
        {
            return a._bottom == b._bottom &&
                   a._left == b._left &&
                   a._right == b._right &&
                   a._top == b._top;
        }

        public static bool operator !=(Rect a, Rect b)
        {
            return !(a == b);
        }

        public int Left
        {
            get { return _left; }
            set { _left = value; }
        }

        public int Top
        {
            get { return _top; }
            set { _top = value; }
        }

        public int Right
        {
            get { return _right; }
            set { _right = value; }
        }

        public int Bottom
        {
            get { return _bottom; }
            set { _bottom = value; }
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Point
    {
        private int _x;
        private int _y;

        public Point(int x, int y)
        {
            _x = x;
            _y = y;
        }

        public int X
        {
            get { return _x; }
            set { _x = value; }
        }

        public int Y
        {
            get { return _y; }
            set { _y = value; }
        }

        public override bool Equals(object obj)
        {
            if (!(obj is Point)) return base.Equals(obj);
            var point = (Point)obj;

            return point._x == _x && point._y == _y;
        }

        public override int GetHashCode()
        {
            return _x.GetHashCode() ^ _y.GetHashCode();
        }

        public static bool operator ==(Point a, Point b)
        {
            return a._x == b._x && a._y == b._y;
        }

        public static bool operator !=(Point a, Point b)
        {
            return !(a == b);
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Windowplacement
    {
        public int length;
        public int flags;
        public int showCmd;
        public Point minPosition;
        public Point maxPosition;
        public Rect normalPosition;
    }

    #endregion
}
EN

回答 1

Stack Overflow用户

发布于 2017-09-06 15:54:13

您是否尝试过使用System.Windows.Window实例而不是p/invoke?我使用两个简单的方法来保存和设置窗口位置使用这个类,它在不同的应用程序,架构,客户端,Windows操作系统,有或没有Aero.

代码语言:javascript
运行
AI代码解释
复制
void SetWindowPosition()
{
    this.Left = Settings.Default.WindowPositionLeft;
    this.Top = Settings.Default.WindowPositionTop;
}
void SaveWindowPosition()
{
    Settings.Default.WindowPositionTop = this.Top;
    Settings.Default.WindowPositionLeft = this.Left;
    Settings.Default.Save();
}

还是我错过了什么?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27838206

复制
相关文章
win10 uwp 设置启动窗口大小 获取窗口大小 设置启动窗口获得窗口大小
ApplicationView.PreferredLaunchWindowingMode 设置UWP窗口全屏
林德熙
2018/09/18
5.4K0
win10 uwp 设置启动窗口大小 获取窗口大小 设置启动窗口获得窗口大小
ApplicationView.PreferredLaunchWindowingMode 设置UWP窗口全屏
林德熙
2019/03/13
4.3K0
win10 uwp 设置启动窗口大小 获取窗口大小
ApplicationView.PreferredLaunchWindowingMode 设置UWP窗口全屏
林德熙
2022/08/09
1.9K0
[Qt]窗口大小、位置及其大小改变引起的事件QResizeEvent
原文链接:https://blog.csdn.net/humanking7/article/details/86108269
祥知道
2020/03/10
11.1K0
Microsoft PowerToys
Microsoft PowerToys是一组实用程序,供高级用户调整和简化Windows体验,以提高工作效率。受Windows 95时代PowerToys项目的启发,此重启为高级用户提供了从Windows 10 shell压缩更高效率并针对单个工作流进行自定义的方法。
云深无际
2020/08/11
2.6K0
Microsoft PowerToys
win10开启Hyper-v 后出现多个虚拟显示器,导致无法使用外接显示器
点击显示器高级设置 查看是几号显示器 然后点击显示器编号,在多显示器设置里选择  将桌面扩展到此显示器 应用即可完成
似水的流年
2019/12/13
3.8K0
win10开启Hyper-v 后出现多个虚拟显示器,导致无法使用外接显示器
电脑软件:推荐一款桌面增强工具AquaSnap
AquaSnap(界面增强软件)是一款功能强大的界面增强软件。这款软件支持屏幕边缘吸附与屏幕分屏即多显示器控制、摇晃窗口置顶与窗口自动拉伸等实用功能。用户使用了这款软件以后就能使电脑桌面排列更加整洁。
小明互联网技术分享社区
2023/10/10
7720
电脑软件:推荐一款桌面增强工具AquaSnap
改变视图的位置和大小
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/53068421
用户1451823
2018/09/13
1.3K0
SetTimer在无窗口和有窗口线程的使用
 今天犯了一个粗心的错误,在无窗口线程中,SetTimer中设置计时器ID,而WM_TIMER消息响应函数中得到的计时器ID却不是之前设置的计时器ID.
雪影
2018/08/02
8650
dotnet 读 WPF 源代码笔记 使用 Win32 方法修改窗口的坐标和大小对窗口依赖属性的影响
咱可以使用 Win32 的 SetWindowPos 修改窗口的坐标和大小,此时 WPF 的窗口的 Left 和 Top 和 Width 和 Height 依赖属性也会受到影响,本文将会告诉大家在啥时候会同步更改 WPF 依赖属性的值,而什么时候不会
林德熙
2021/01/12
8040
win10快捷键大全 win10常用快捷键
win10快捷键大全大家可以来了解一下,今天小编带来了win10常用快捷键,很多朋友喜欢使用快捷键来操作电脑,那么Windows10系统有哪些新的快捷键呢 win10快捷键大全大家可以来了解一下,今天小编带来了win10常用快捷键,很多朋友喜欢使用快捷键来操作电脑,那么Windows10系统有哪些新的快捷键呢 • 贴靠窗口:Win +左/右> Win +上/下>窗口可以变为1/4大小放置在屏幕4个角落 • 切换窗口:Alt + Tab(不是新的,但任务切换界面改进) • 任务视图:Win + Tab(松开
98k
2018/04/12
4.5K0
Flex Air 主窗口和多个子窗口从属显示
项目组的程序需要做一个有主窗口和几个小的子窗口(一些控制板), 需求是:点击主窗口的时候,小的子窗口能保持在主窗口前边。 然后切换到其他软件的窗口的时候,主窗口和子窗口能跟着一起退到后边。 烦啊~~3天时间,已经试了N多方法。 1、重载NativeWindow,加入组件的方式。发现很多控件加不进去~~失败 2、一直处理orderToFrontOf(Main),但子窗口会一直闪烁。失败 3、用alwaysInFront,切换到其他软件的时候,把alwaysInFront设置为false。几乎成功了,但还是很多
用户1258909
2018/07/03
1.4K0
使用Arrow管理数据
Apache Arrow defines a language-independent columnar memory format for flat and hierarchical data, organized for efficient analytic operations on modern hardware like CPUs and GPUs. The Arrow memory format also supports zero-copy reads for lightning-fast data access without serialization overhead.
生信探索
2023/04/04
4770
在windows下详解:大端对齐和小端对齐
计算机的内存最小单位是什么?是BYTE,是字节。 一个大于BYTE的数据类型在内存中存放的时候要有先后顺序。
黑泽君
2018/10/11
3.6K0
android控制view的大小和位置(一)
1.首先,我们已经知道通过addView这个方法可以动态的添加自己新建的一个view,例如activityLayout.addView(new Button());这样就可以添加一个新的button,而且在添加时可以规定新的view的位置和大小,通过RelativeLayout.LayoutParams控制,例如 RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( (int) (100 * metrics.density
forrestlin
2018/05/23
1.5K0
android控制view的大小和位置(二)
上一次我讲的android控制view的大小和位置(一)中,只讲了RelativeLayout动态加载子view的流程,今天我讲讲添加子view的各种规则,如下: 第一类:属性值为true或false     android:layout_centerHrizontal 水平居中     android:layout_centerVertical 垂直居中     android:layout_centerInparent 相对于父元素完全居中     android:layout_alignPar
forrestlin
2018/05/23
8770
idea在一个窗口打开多个项目
使用场景:Spring-cloud框架下的项目一般都有多个子项目,就像我们项目由6个子项目,每个子项目单独更新很麻烦,还有相互之间的依赖,所以就把所有的子项目都放到一个文件夹下,只要更新所有的子项目都会更新,依赖也会更新。这样就很方便管理。
赵哥窟
2022/05/13
4.7K0
idea在一个窗口打开多个项目
软件测试|超好用超简单的GUI库——tkinter(三)
前面我们介绍了tkinter主窗口的一系列操作,本篇文章我们将介绍Label控件,Label(标签)控件,是 Tkinter 中最常使用的一种控件,主要用来显示窗口中的文本或者图像,并且不同的 Lable(标签)允许设置各自不同的背景图片。
霍格沃兹测试开发Muller老师
2023/04/10
1.1K0
Win32 程序在启动时激活前一个启动程序的窗口
发布于 2018-08-05 13:48 更新于 2018-09-01 00:15
walterlv
2018/09/18
9420
点击加载更多

相似问题

可可如何在多个显示器上记住窗口位置?

11

玛雅PySide窗口-记住位置和大小

12

Excel:记住多个窗口的窗口大小

10

javascript弹出窗口记住最后的大小和位置

25

.NET / Windows Forms:记住窗口的大小和位置

110
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档