MFC 对话框边框填充从 VS2010 切换到 2012 或更高版本后发生变化

Dan*_*ely 5 c++ mfc visual-studio-2010 visual-studio-2012

在VS2015中重建一个MFC应用程序后,Windows设置的边框填充从添加到对话框的外部变成了它的内部。由于更改而不是粗边框使对话框变大,对话框大小保持不变,控件可用的空间量减少。

边框填充的默认值在不同版本的 Windows 之间发生了变化。当 Vista 出来使玻璃更引人注目时,它从较小的值(0?)变为 4 像素,并且似乎一直保持到 8.x,只是在 Win10 中回落到 0。(注意,我在工作中没有任何 8/10 机器可用,我要离开谷歌了。)

这意味着控件的空间量在不同的 Windows 版本之间有所不同。因此,似乎不可能在所有版本的操作系统上都有看起来不错的对话框。如果我将它们放置在 V7/8 中默认的 4px 边框上,我最终会在默认 W10 系统的底部/右侧有明显的额外空间。如果我针对 W10 进行优化,我的底部按钮将在 W7/8 上被切断。

这不会发生在干净的测试项目中,所以这与我的应用程序中的特定代码有关。

我附上了一张 0 vs 4 像素边框在 VS2010 或更新版本中构建的应用程序的样子的图片。图像标题为 VS2015;但额外的测试确定该更改是随 V110 运行时 (Visual Studio 2012) 引入的。

对话框大小似乎在MoveWindow()用于将较小对话框定位在主要对话框周围的代码中变得一团糟。

我已经提取了在下面做一个对话框所涉及的代码:

RECT             DlgRect;
double Fx, Fy, Fw, Fh;      // the dialog in the screenshots
double Px, Py, Pw, Ph;      // another dialog 
double ScreenHeight = (double)GetSystemMetrics(SM_CYSCREEN);

g_pRedactedDlg = new CRedactedDlg(NULL);
g_pRedactedDlg->GetClientRect(&DlgRect);
Fw = DlgRect.right + 10;    // 10
Fh = DlgRect.bottom + 20;   // 20

Py = 100; //size and position data for a different 
Ph = 50;  //dialog, calculated in code not shown

Fx = 0.0;
Fy = ((Py + Ph + 5.0 + Fh) > ScreenHeight) ? (ScreenHeight - Fh) : (Py + Ph + 5.0);

g_pRedactedDlg->MoveWindow((int)Fx, (int)Fy, (int)Fw, (int)Fh, TRUE);
Run Code Online (Sandbox Code Playgroud)

根据@snowdude 和@MichaelWalz 的评论,我怀疑所获得GetClientRect()的大小和预期的大小MoveWindow()在处理对话框边框大小的方式上有所不同;但还没有完全追溯,看看当我改变边框大小时会发生什么变化。

在此处输入图片说明

仅供参考 边框填充设置位于:控制面板 - 个性化 - 窗口颜色 - 高级外观设置 - 边框填充。

Dan*_*ely 3

GetWindowRect()和的行为MoveWindow()在 VS2010 和 2012 之间发生了变化。在 2010 年,GetWindowRect()返回没有边框填充的对话框区域,并MoveWindowRect()期望有边框填充的对话框区域;渲染对话框的大小添加了填充。2012 年,对话框区域返回时添加了填充,并且渲染的对话框大小中没有添加任何填充。

MS Connect上报告了这一情况,并追踪到链接器标志。 /SUBSYSTEM:WINDOWS,5.01给出旧的行为,/SUBSYSTEM:WINDOWS,6,00给出新的行为。VS2015s 似乎不允许指定要在此处传递的版本。项目属性-链接器-所有选项-子系统,是一个下拉菜单,对于Windows只有一个选项。

这一重大更改可能是删除Vista 发布时添加的兼容性黑客的结果。

对于我的应用程序,我通过使用GetWindowRect()计算对话框的大小而不是GetClientRect()然后添加硬编码的填充值来修复此问题。

g_pRedactedDlg->GetWindowRect(&DlgRect);
Fw = DlgRect.right - DlgRect.left;
Fh = DlgRect.bottom - DlgRect.top;
Run Code Online (Sandbox Code Playgroud)

这不会产生与旧版本相同的行为,因为硬编码高度偏移在 Windows 7 下太小了 12 像素,并且截断了对话框的底部,如 RC 设计器中所示。在旧版本的 Windows 下,偏移量可能是正确的;MFC 代码库至少可以追溯到 Visual Studio 97/NT4。