v2rayN创建节点的窗口, 长宽不超过屏幕 / 合入v2rayN主线, 成为Contributors之一

需求

在笔记本的屏幕上, 使用v2rayN时, 有些设置界面太高了, 显示不全.

1080p笔记本缩放到175%后,v2rayN添加服务器窗口显示不全

如果你是个1080p的笔记本, 屏幕13寸, 你再把缩放开到175%, 就会遇到上面的情况了.

Windows缩放与布局里红框标出175%

解决思路

根据当前屏幕的尺寸, 调整窗口的尺寸.


具体实践

安装 Microsoft Visual Studio

在 Microsoft Store 里有

https://apps.microsoft.com/store/detail/XPDCFJDKLZJLP8

安装组件选 .NET 桌面开发

Visual Studio安装程序勾选.NET桌面开发


下载源码

https://github.com/2dust/v2rayN

GitHub上右键Download ZIP,选链接另存为

解压, 进入 v2ray-master 目录, 进入 v2rayN 目录, 打开 .sln 文件.

解压后进入v2rayN目录,打开v2rayN.sln

修改源码

打开 .sln 文件.

找到 AddServerWindow.xaml 文件.

在解决方案资源管理器里找到AddServerWindow.xaml

右键菜单, "查看代码".

右键菜单里红框标出查看代码

找到在代码中长这个样子的地方. class后面的是和文件名一样的AddServerWindow, 下面还有一个public然后跟着同样的AddServerWindow

找到类AddServerWindow和同名的构造函数



添加以下代码

// 设置窗口的尺寸不大于屏幕的尺寸
if (this.Width > SystemParameters.WorkArea.Width)
{
    this.Width = SystemParameters.WorkArea.Width;
}
if (this.Height > SystemParameters.WorkArea.Height)
{
    this.Height = SystemParameters.WorkArea.Height;
}

截图右边那一半是修改前的, 作为对比. 

在构造函数里加入代码,让窗口宽高不超过屏幕工作区

保存, 编译, 开始调试(或执行). 

用菜单也可以, 用快捷键也可以, 用快捷按钮也可以.

用调试菜单或F5编译并开始调试

现在你就可以试试看添加服务器的窗口还会不会显示不全了.

实际上, 还是没有一下子全部显示啦, 不过窗口的标题栏完整显示了, 而且也出现了上下滚动栏, 可以把窗口下半部分"滚"出来. :)

添加服务器窗口出现滚动条,下半部分可以滚出来

用到这里你一定会发现, 其它窗口还有显示不全的问题没有修复, 主窗口也一样.

那么故技重施, 打开这些文件名后面带Window的代码窗口.

其它带Window的窗口也要同样修改

一样找到那样的位置, 把同样的代码添加进去. 然后编译, 执行就可以了.

然后你会发现, 主窗口没有修改效果.


其实除了这些以外, 还要改一个地方.

找到MainWindow, 

主窗口要另外找到MainWindow.xaml

右键菜单 - "查看设计器"

右键MainWindow.xaml,选查看设计器

鼠标移到窗口的最边边上, 点击选中窗口.

鼠标移到窗口最边上,点中窗口本身

如果你点准了, 这个位置会显示这样子的, 特别是类型那里是ReactiveWindow

点准后属性面板的类型显示ReactiveWindow


如果你一直点不准窗口的边框, 你可以放大了再点.    

点不准边框时,把设计器放大到400%再点

上个动图, 说明一下具体操作.

动图演示:在设计器里点中窗口边框

展开"布局", 再点击这个箭头展开更多属性.

属性面板布局里Width为900、Height为700

这两个属性 MinWidth MinHeight, 都设置为 0.

把MinWidth和MinHeight都改成0

你再 保存, 编译, 开始调试 试试?

应该主窗口也解决问题了.

原因是, 当你把MinWidth&MinHeight设置得比较大, 之后再将MaxWidth MaxHeight设置得小于MinWidth MinHeight, 会无效.


========

完


正确答案放在GitHub上

https://github.com/crazypeace/v2rayN


========

题外话

与GPT(https://t.me/gpt_user)的交流过程 

先问了GPT, 得到这样的回答

向GPT询问如何把窗口最大宽高限制在屏幕分辨率内

在代码里找到Window_Loaded函数.

在代码里找到Window_Loaded函数

再参照GPT的回答, 改成这样

按GPT的回答改成读取屏幕宽高并设置MaxWidth和MaxHeight

编译报错

编译报CS0234,System.Windows里没有SystemMetrics

把错误复制, 去问GPT

把报错复制给GPT,它给出screenWidth的写法

把代码修改

改用System.Windows.Forms取屏幕宽高,仍报没有Forms命名空间

还是报错, 说没有Forms这个命名空间.

我又换了几种提问方式, 在一次GPT的回答中提到了 Windows Forms 和 WPF

换种问法后,GPT提到Windows Forms和WPF的区别

于是, 我再次提问, 得到这样的回答

再次提问后,GPT给出用SystemParameters.WorkArea的写法

然后换成这两段代码.

换成这两段代码,用工作区宽高设置MaxWidth和MaxHeight

然后跑起来. 会发现窗口显示是这么个样子.

跑起来后窗口仍显示不全,但拖出来看高度其实已经调整了

当你把窗口拖出来看, 会发现其实窗口的高度其实是调整了的, 也是符合我们的设想的.


那么问题就在于窗口显示出来的整个过程.

首先是窗口要 初始化, 这时窗口被设置为一个大的形状.

然后是窗口 显示出来, 这时窗口是一个大的形状, 那么为了默认显示在屏幕正中间, 窗口的上下都会各有一部分显示在屏幕之外.

    窗口显示在屏幕正中间, 在编程世界中的意思是, 窗口的上下边到屏幕上下边的距离相等, 窗口的左右边到屏幕的左右边的距离相等.

    窗口上下边超过了屏幕, 那么负数也是要相等. :)

显示完之后, 再调用Window_Loaded函数. 在这个函数的过程中, 我们修改了窗口的宽度和高度, 但是窗口的 位置 没有改变. 

    窗口的 位置 没有改变, 在编程世界中的意思是, 窗口的左上角这个顶点的位置没有改变. 

所以我们可以看到窗口的下边沿/边框/Border "缩起来"了很多.


解决方案一种就是在设置窗口形状以后, 判断如果左上角在屏幕以外时, 设置左上角的位置到屏幕内.

红框代码:窗口Top小于0时把它置为0
if (this.Top < 0)
{
    this.Top = 0;
}

还有一种方案就是把调整窗口的形状提前到窗口初始化过程时. 就像本篇博文最前面讲的那样.


==========

update

到上面为止修改的方案在你自己的一个屏幕的场景下应该没问题, 但是在多个屏幕的情况下, 比如你是笔记本外接了一个大显示器, 会出现问题是:

1. 如果大屏幕是主屏幕, 在小屏幕上面启动程序, 并不能正确设置窗口大小

请见后续

2. 如果小屏幕是主屏幕, 窗口移动到大屏幕上面后, 拖动窗口不能变得更大, 窗口最大化也不能显示更多内容.

原因是我们设置了窗口的最大尺寸. 需要修改为设置窗口的实际尺寸.

// 设置窗口的尺寸不大于屏幕的尺寸
if (this.Width > SystemParameters.WorkArea.Width)
{
    this.Width = SystemParameters.WorkArea.Width;
}
if (this.Height > SystemParameters.WorkArea.Height)
{
    this.Height = SystemParameters.WorkArea.Height;
}


==========

update

合入v2rayN主线, 成为Contributors之一.

这个改动已合入v2rayN主线,贡献者里有crazypeace

人人都可以为开源项目出一份力. 虽然功能简单, 代码量小, 但是你的努力不会被遗忘.


==========

后记

最后谈一下把GPT作为copilot编程的体验.

我觉得GPT吃的东西还不够多, 确实有的时候准确率堪忧. 不过它对于一个面对全新领域的人来说, 可以提供一些此领域内的关键字, 作为入门的踏脚石或者说灵感, 可以再继续问GPT, 或者是去Google, 然后自己进一步消化. 


评论
  1. 回复
    1. 恭喜你做到了!
      编程并不是难以企及的. 只要心中有冲动, 大胆动手. 人人都可以玩代码!

      删除
发表评论