如何使用 C# 和 WinForm 创建 1 像素宽 window
How to create an 1 pixel wide window using C# and WinForm
我想创建一个在桌面底角显示一个小 window 的应用程序。在启动时,window 应该非常小,理想情况下,宽度只有几个像素。
这是我用来执行此操作的代码:
public partial class DurationT64 : Form
{
private Size fullSize;
private Point fullPos;
private Point compactPos;
public DurationT64()
{
InitializeComponent();
var workingArea = Screen.PrimaryScreen.WorkingArea;
this.MinimumSize = new Size(0, this.Height);
this.MaximumSize = new Size(this.Width, this.Height);
// fullPos: the window location when it is in full size form.
fullPos = new Point(workingArea.Right - this.Width, workingArea.Bottom - this.Height);
this.Location = fullPos;
// fullSize: the size of the windown when it is in full size form.
fullSize = new Size(this.Width, this.Height);
this.Size = fullSize;
// compactPos: the window location when it is in compact size form.
compactPos = new Point(workingArea.Right - 30, fullPos.Y);
this.Width = 1;
this.Location = compactPos;
}
}
如您所见,在此示例中,我打算创建一个宽度仅为 1 像素的 window,靠近主监视器的右边缘放置。
然而,我意识到 window 并没有我预期的那么小。它缩小到 20 像素宽,但不少于此。例如,请参考下面的屏幕截图:
an image shows that the window is wider than it suppose to be
我对这个问题做了一些研究,注意到 Zach Johnson (@zach-johnson) 在 2009 年提出了一个解决方案。这是 link Overcome OS Imposed Windows Form Minimum Size Limit。
但是,link 中提出的其他方法(Zach 提出的拦截 WM_ 消息和@Ace 提出的 SetBoundsCore 方法)对我有用。
任何人都可以给我一些解决这个问题的方法吗?如果可能,最好是完全基于 C#/Winform 且不依赖本机 Win32 window 消息循环的解决方案。
非常感谢!
这很简单,Winforms 确保 window 不能小于系统强加的最小尺寸 window,暴露为 中的 SystemInformation.MinWindowTrackSize property。网。这是一个 "safety" 设置,它确保用户在调整它时不会将 window 设置得太小,从而失去对它的控制。同样的考虑也适用于代码。
绕过这个限制不需要任何魔法,你需要做两件事:
- 将 FormBorderStyle 属性 设置为 None 这样用户就无法调整 window.
的大小
- 在 创建 window 之后设置大小 。 Load事件最好。
关于您现有代码的一些评论:修改 Width/Height/Size 属性时要小心,您在构造函数中做的太多了,它无法正常工作。在构造函数中,它们还不匹配 window 的实际大小。并且在具有高分辨率显示器的现代机器上根本不会接近,自动缩放以匹配视频适配器的 DPI 在今天很重要。您必须推迟到创建 window 并完成缩放,Load 事件是此类代码的合适位置。实际使用 Load 的少数原因之一。
并注意你的 Location 属性 计算不充分,它没有考虑任务栏的位置。它在我的机器上不起作用,我喜欢右边的任务栏。
最小复制:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
}
protected override void OnLoad(EventArgs e) {
this.Width = 1;
base.OnLoad(e);
}
}
请记住,您需要鹰眼才能在屏幕上找到它:)
我想创建一个在桌面底角显示一个小 window 的应用程序。在启动时,window 应该非常小,理想情况下,宽度只有几个像素。
这是我用来执行此操作的代码:
public partial class DurationT64 : Form
{
private Size fullSize;
private Point fullPos;
private Point compactPos;
public DurationT64()
{
InitializeComponent();
var workingArea = Screen.PrimaryScreen.WorkingArea;
this.MinimumSize = new Size(0, this.Height);
this.MaximumSize = new Size(this.Width, this.Height);
// fullPos: the window location when it is in full size form.
fullPos = new Point(workingArea.Right - this.Width, workingArea.Bottom - this.Height);
this.Location = fullPos;
// fullSize: the size of the windown when it is in full size form.
fullSize = new Size(this.Width, this.Height);
this.Size = fullSize;
// compactPos: the window location when it is in compact size form.
compactPos = new Point(workingArea.Right - 30, fullPos.Y);
this.Width = 1;
this.Location = compactPos;
}
}
如您所见,在此示例中,我打算创建一个宽度仅为 1 像素的 window,靠近主监视器的右边缘放置。
然而,我意识到 window 并没有我预期的那么小。它缩小到 20 像素宽,但不少于此。例如,请参考下面的屏幕截图: an image shows that the window is wider than it suppose to be
我对这个问题做了一些研究,注意到 Zach Johnson (@zach-johnson) 在 2009 年提出了一个解决方案。这是 link Overcome OS Imposed Windows Form Minimum Size Limit。
但是,link 中提出的其他方法(Zach 提出的拦截 WM_ 消息和@Ace 提出的 SetBoundsCore 方法)对我有用。
任何人都可以给我一些解决这个问题的方法吗?如果可能,最好是完全基于 C#/Winform 且不依赖本机 Win32 window 消息循环的解决方案。
非常感谢!
这很简单,Winforms 确保 window 不能小于系统强加的最小尺寸 window,暴露为 中的 SystemInformation.MinWindowTrackSize property。网。这是一个 "safety" 设置,它确保用户在调整它时不会将 window 设置得太小,从而失去对它的控制。同样的考虑也适用于代码。
绕过这个限制不需要任何魔法,你需要做两件事:
- 将 FormBorderStyle 属性 设置为 None 这样用户就无法调整 window. 的大小
- 在 创建 window 之后设置大小 。 Load事件最好。
关于您现有代码的一些评论:修改 Width/Height/Size 属性时要小心,您在构造函数中做的太多了,它无法正常工作。在构造函数中,它们还不匹配 window 的实际大小。并且在具有高分辨率显示器的现代机器上根本不会接近,自动缩放以匹配视频适配器的 DPI 在今天很重要。您必须推迟到创建 window 并完成缩放,Load 事件是此类代码的合适位置。实际使用 Load 的少数原因之一。
并注意你的 Location 属性 计算不充分,它没有考虑任务栏的位置。它在我的机器上不起作用,我喜欢右边的任务栏。
最小复制:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
}
protected override void OnLoad(EventArgs e) {
this.Width = 1;
base.OnLoad(e);
}
}
请记住,您需要鹰眼才能在屏幕上找到它:)