如何避免 MDIParent 窗体调整大小



我正在设计一个Windows Form应用程序。我有一个以最大化状态加载的 MDIParent 窗体,并在最大化状态下加载其子窗体。但是,当我打开 OpenFileDialog 或任何数据读取器对象时,MDIParent 会缩小到较小的大小及其所有窗体和控件。

此解决方案打开子表单导致 mdiform 更改大小和收缩不适用于我的情况。

此外,这个解决方案 https://support.microsoft.com/en-nz/help/967173/restoring-a-maximized-or-minimized-mdi-parent-form-causes-its-height-t 对我不起作用。

一些背景:我几乎在所有的WinForm应用程序中都看到了这种行为,但我从未热衷于解决它。当我开始调查它时,我能够缩小到上面突出显示的原因。一些帖子将其描述为 Windows 错误,但只要我的屏幕分辨率开始超过 1024 (VS 2010),它就已经存在了。我希望这不仅仅是一个窗口错误...

我希望它不仅仅是一个窗口错误......

功能,不是错误,但这不是Winforms程序员非常喜欢的功能。 值得注意的是,在过去的几个月里,有几个关于神秘化窗户收缩的问题。我认为它与Win10 Fall Creators版本的发布有关。 它对传统的Win32 api层进行了深刻的更改,并且引起了很大的动荡。

在您的特定情况下,"功能"由 shell 扩展启用。 当您使用 OpenFileDialog 时,它们会被注入到您的流程中。 这样做的人非常非常邪恶,并且做了一些 shell 扩展绝对不能做的事情。 它调用 SetProcessDPIAware()。 值得注意的是,它可能是用WPF编写的,它有一个非常偷偷摸摸的后门来声明自己dpiAware。 只需加载 PresentationCore 程序集就足够了。 但不限于 WPF 代码,任何代码都可以执行此操作,并且可能长时间未检测到。

追查这个邪恶扩展的一种方法是使用SysInternals的AutoRuns实用程序。 它允许您有选择地禁用扩展。 但是还有一个程序员的方式,你可以在VS中调试它。

使用"项目>属性">"调试"选项卡>勾选"启用本机代码调试"复选框。 顺便说一句,在旧的 VS 版本中命名略有不同。 然后调试>新的断点>函数断点。 函数名 =user32!SetProcessDPIAware, 语言 =C。 可以在不执行任何操作的 WPF 应用中执行此操作,以确保正确设置所有内容。 为了完整起见,您还可以为新风格 SetProcessDPIAwareness 添加断点。

按 F5 开始调试并触发 OpenFileDialog.ShowDialog() 调用。 断点现在应该命中,使用 Windows> 调用堆栈>调试来查看堆栈跟踪。 在您的案例中,您通常不会看到任何非常可识别的内容,因为恶意代码存在于您没有 PDB 的 DLL 中。 但是DLL名称和位置(在>Windows>模块的调试中可见)应该有助于识别您需要提交错误的人。 如果您可以没有它,请卸载它。

最后但并非最不重要的一点是,开始创建具有dpiAware功能的Winforms应用程序变得非常重要,因此这样的错误永远不会字节。 首先,将应用声明为 dpiAware,以便禁用 DPI 虚拟化。 加上你需要在代码中执行的任何操作,以确保 UI 设计正确缩放。

最新更新