首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >记住窗口位置、大小和状态[在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

复制
相关文章
java.lang.IllegalArgumentException 如何解决这个异常
很多人说这个异常是spring版本和jdk版本不一致导致的,其实不然你可以运行一下这一段代码
全栈程序员站长
2022/09/14
1.4K0
java.lang.IllegalArgumentException 如何解决这个异常
SEO 在 SPA 站点中的实践
观察基于 create-react-doc 搭建的文档站点, 发现网页代码光秃秃的一片(见下图)。这显然是单页应用 (SPA) 站点的通病 —— 不利于文档被搜索引擎搜索 (SEO)。
牧云云
2021/03/11
1.9K0
SEO 在 SPA 站点中的实践
异常:java.lang.IllegalArgumentException: Could not resolve placeholder ‘xxx‘ in value “${xxx}“
一开始以为又是下划线的原因,后来才发现,原来应用名和yml配置的文件需要命名一致才行。
Maynor
2021/12/06
2.3K0
错误、异常
tkinter:tkinter是绑定了Python的TKGUI工具集,就是Python包装的Tcl代码,通过内嵌在Python解释器内部的Tcl 解释器实现的,它是Python标准库的一部分,所以使用它进行GUI编程不需要另外安装第三方库的。
py3study
2020/01/16
6.4K0
错误、异常
PHP异常处理之获取错误发生的所在行
通常我们需要将报错的文件名、行号、错误信息、导演追踪信息等记录到日志中,以便调试与修复问题。
Laikee
2022/04/25
1.1K0
Android viewpager嵌套使用photoview异常问题(java.lang.IllegalArgumentException)
最近,做项目时,遇到一个需求,需要像淘宝评论那样,一组图点开,然后可以双指滑动放大,并左右切换换图的功能。自然就想到了使用viewpager+photoview来实现这一功能,但是在实现后,却发现一个bug,就是在使用双手放大图片时,会抛异常,抛的异常是如下:
程思扬
2022/01/10
6650
8000—0004显示设备出现问题_错误0x8007005
问题描述:最近做一个web应用程序需要操作Excel文件,在开发环境下程序测试正常,部署到IIS后程序操作Excel文件,IIS报错,错误出现在创建Excel进程的语句,如下:
全栈程序员站长
2022/09/24
2.8K0
8000—0004显示设备出现问题_错误0x8007005
Shiro异常java.lang.IllegalArgumentException: Odd number of characters解决方案
根本原因:密码匹配不对应 1.首先先检查是否使用了加密,如果使用了加密方式,那么有可能就是你数据库中存储的密码是明文形式的密码,所以两者无法匹配。 因为我在shiro里面对密码 进行了MD5加密,所以这和我们一般的密码匹配还不一样。 首先先检查我们对于shiro的配置文件信息
萌萌哒的瓤瓤
2020/08/26
5.1K2
出现500错误
早上闲来无事,在cpanel后台转悠,看到了hotlink保护,想想是不是设置一下防盗链呢,这个博客开始到现在也没有几张有价值的图片,其实防盗链没所谓的,凑凑热闹设置一下,以前用过cpanel后台的免费空间,设置过hotlink,所以就没在意,设置完关掉了。
空空裤兜
2023/03/03
1.7K0
在Linux系统中安装LAMP出现的错误总结
总结一下用源代码安装LAMP环境中遇到常见的错误,从错误3开始是因为安装php后面带参数,导到没有找到开发包例如:./configure --with-gd  --with-libjpeg会出现如下错误。
星哥玩云
2022/06/28
3.3K0
在Linux系统中安装LAMP出现的错误总结
JavaScript 错误异常
JavaScript 错误异常 错误异常语句 try 语句测试代码块中的错误 catch 语句处理错误 throw 语句允许自定义错误 finally 语句在错误异常语句后,必须执行的代码块 try { adddlert("Hello") ; } catch (err) { document.getElementById("demo").innerHTML = err.message ; } // 结果 : adddlert is not defined JavaScript 将 addd
Mirror王宇阳
2020/11/12
4970
Tomcat的异常 之 java.lang.IllegalArgumentException:Document base *** does not exist or is not a readable
这个异常是经常遇到的异常情况。 Tomcat的异常 之 java.lang.IllegalArgumentException: Document base 有些刚开始使用的Tomcat的朋友会出现的问
cloudskyme
2018/03/20
1.1K0
获取包装异常中真实异常
没有弄清对方的底细,绝不能掏出你的心来——巴尔扎克 重复调用getCause即可 package io.github.vampireachao.stream.core.lambda; /** * LambdaInvokeException * * @author VampireAchao ZVerify * @since 2022/9/4 */ public class LambdaInvokeException extends RuntimeException { /**
阿超
2022/10/31
6560
在Web站点中创建和使用Rss源
Rss是将你Web站点的内容与其他人分享的标准方式。Rss代表着:Really Simple Syndication。它不过是一个标准化的XML标记,用于描述你想要分享的内容。因此Rss是一个在你的内容准备好被其他用户所消费时被广泛接受的格式。一些使用Rss的范例站点有:www.asp.net、weblogs.asp.net 和 www.dotnetbips.com 。Dotnetbips.com 通过 Rss 发布新添内容的列表,这个列表可能会被其他的站长放置在他们的站点或目录中。
张子阳
2018/09/30
6610
在Web站点中创建和使用Rss源
在iOS8上出现<Error>: CGAffineTransformInvert: singular matrix.错误
在iOS8上设置self.whiteLight.transform = CGAffineTransformMakeScale(0, 0);会出现<Error>: CGAffineTransformInvert: singular matrix. 在iOS9不会,在swift上也不会,只有在OC的iOS8会出现 查了一下要解决这个问题就是要把CGAffineTransformMakeScale(0.00001f, 0.00001f)即可,因为CGAffineTransformMakeScale设置为0不会
傅_hc
2018/07/04
7600
运行游戏时出现0xc000007b错误的解决方法[通俗易懂]
出现这个错误,可能是硬件的问题,也可能是软件的问题。但是,由于硬件引起该问题的概率很小,并且除了更换硬件之外没有更好的解决方法,因此本文将详细介绍如何通过软件解决此问题,这也是大家最关心的。由于本文阅读用户众多,大家对于电脑故障解决的熟悉程度也不一样,因此本文致力于用最通俗的语言,提供最简便的解决方法,满足绝大多数用户的需求。如果您是高级用户,也可以查看我的后续文章,查看问题具体原因分析。
全栈程序员站长
2022/07/01
8.9K0
运行游戏时出现0xc000007b错误的解决方法[通俗易懂]
nginx下php环境在ubuntu重启后出现502错误
为了将原本运行在Windows Server 2016 中IIS上的PHP环境(WordPress程序加MySql)迁移到Ubuntu Server下的Nginx上。我考虑先将程序和MySql导入到本地的Ubuntu虚拟机中进行测试,然后重装服务器进行迁移。但是在环境的配置是,发现了一个问题,就是在Ubuntu重启后,本地站点打开php站点phpMyAdmin会出现502错误,通过多次尝试,发现主要可能是一下几个问题,也算是列举下nginx 502错误的解决方法。 ---- Q1:php.ini的memo
李郑
2018/02/28
1.6K0
nginx下php环境在ubuntu重启后出现502错误
Python迭代DataLoader时出现TypeError: Caught TypeError in DataLoader worker process 0.错误。
迭代 DataLoader时出现以下错误,暂时不知道怎么解决,向大家求救,是一个比较稀罕的错误,也分享给大家一个奇葩的问题一起讨论。
全栈程序员站长
2022/08/22
3.9K0
用 WiX Burn 制作托管安装包:出现 0x80070002 错误
使用 WiX 的 Burn 引擎制作自定义托管引导程序的 exe 安装包时,双击生成的安装包没有反应。如果查看日志可以发现有 0x80070002 错误。本文介绍其调查和解决方法。
walterlv
2023/10/23
3330
点击加载更多

相似问题

java.lang.IllegalArgumentException:切入点中的错误在::0形式上未绑定

64

Spring AOP java.lang.IllegalArgumentException:在切入点中正式取消绑定时出错::0

140

Spring :获取异常java.lang.IllegalArgumentException:切入点格式不太好:期待'(‘在字符位置0

10

java.lang.IllegalArgumentException:错误在::0无法找到引用的切入点

13

在切入点中::0正式取消绑定时出错

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

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