【发布时间】:2020-12-31 12:07:08
【问题描述】:
我有一个 WinForms 应用程序。它有一个MainWindowForm(创造性地)命名为Form1,在其中,一个最大化的子Form 命名为fymmapdraw。子窗体是使用以下 VB.NET sn-p 创建的:
fformmapdraw = New fymmapdraw With {
.MdiParent = Form1,
.WindowState = FormWindowState.Maximized
}
fformmapdraw.Show()
我的问题是Form1 最大化和fymmapdraw 在其中最大化,fymmapdraw.Width 在某些情况下报告的值大于屏幕宽度。这是fymmapdraw 中的绘图代码的问题,其中一些捕捉功能错误地捕捉到窗口边框之外。
这似乎与 Aero 风格的桌面有关 - Windows XP 上的宽度是正确的,如果未使用 Aero 风格的桌面主题,则在 Windows 7 上是正确的,但在启用了此类主题的 Windows 7 或 10 上则不正确.
我的屏幕分辨率是 1920x1080。由fymmapdraw 的MouseMove 事件e.X 属性报告的鼠标X 坐标,该属性报告相对于表单本身,范围从0 到1915。这些值是合理的——在两侧丢失了几个像素窗框。
但是,表单的 Me.Width 属性返回 1932 像素,超出屏幕宽度。 Me.Left 返回 -8,Me.Right 返回 1924。
该应用程序相当古老,最初可以追溯到 Windows XP 时代(2006-7)。它目前正在使用 .Net Framework 4.0。 fymmapdraw 将其 FormBorderStyle 设置为 Sizeable,并将其 AutoScaleMode 设置为 Font(尽管它不包含文本控件或类似控件 - 所有绘图均由自定义代码处理)。
有没有办法让 Form.Width 返回“正确”值 - 即可见的真实像素数 - 可能是通过更改表单或应用程序的某些属性?如果没有,表单的另一个属性可以让我获得真正的宽度吗?
下图说明了输出。在左上角,“原始”坐标是由MouseMove 事件报告的坐标,鼠标位于右手边界内。报告的“表单尺寸”为fymmapdraw.Width 和fymmapdraw.Height。小控制栏是不正确捕捉的控制栏 - 它的右侧边缘等于fymmapdraw.Width,但部分位于屏幕外(应该可以看到一个完整的蓝色边框)。
【问题讨论】:
-
当窗口最大化时,其边框(可见或不可见,如 Windows 10 中)会移出屏幕边界。因此,Window 的 Size 总是比 ClientSize 宽 16 个像素(8*2 或 (7+1)*2)。也许您想在 Window 最大化时使用 ClientRectangle 作为参考大小。试试
var windowRect = this.RectangleToScreen(this.ClientRectangle)。当屏幕未缩放 100% 时,DpiAwareness 起作用。也是当前的屏幕布局。请参阅此处的注释:Using SetWindowPos with multiple monitors -
@Jimi - 谢谢,这看起来成功了。一个小的区别是我使用了
ClientSize,因为ClientRectangle看起来它只在控件上定义,而不是在窗体上定义,但它们的行为似乎相似。 -
Form也有Control作为祖先,属性当然可用。
-
我原以为是这样,但 Visual Studio 并未将其显示为可能的自动完成。再次尝试时,结果发现 Visual Studio 仍然拒绝将其显示为可能的自动完成功能,但在手动输入时,它会愉快地自动大写,显示文档字符串,构建程序等。我安装的一个奇怪的怪癖,我敢肯定。