从 VS 2k3 到 VS 2k8 - MFC 应用程序无法在发布配置中正确呈现

Posted

技术标签:

【中文标题】从 VS 2k3 到 VS 2k8 - MFC 应用程序无法在发布配置中正确呈现【英文标题】:From VS 2k3 to VS 2k8 - MFC Application not rendering properly in Release config 【发布时间】:2013-08-07 08:59:35 【问题描述】:

编辑问题已解决,见下文


不久前,我们不得不将 MFC 应用程序从 Visual Studio 2003 迁移到 2008。大部分情况下一切正常,除了一个巨大的缺陷:发布版本无法正确显示我们的对话框,而调试版本工作正常。

下面是它应该是什么样子的示例(以及它在调试中的样子): http://img11.hostingpics.net/pics/864144InterfaceOK1OUT.png

(黑色方块是故意在图片上的) 这是发布版本的样子: http://img11.hostingpics.net/pics/813251InterfaceKO1OUT.png

现在,为了解决这个问题,我经历了不同的步骤:

我在 Release 配置中使用 /MDd 构建了运行时库,然后从 VS 中运行它(我知道很脏);它可以工作(好吧,我在关闭时遇到错误,这是可以预料的),但显然远非理想。 我在 Debug 和 Release 可执行文件上运行了 Dependency Walker,并将它们进行了比较:除了 Debug DLL(MSVC[PR]90D 和 MFC90D)之外,它几乎是相同的。我没有发现任何有意义的东西。 我尝试按照 MSDN msdn.microsoft.com/en-us/library/fsk896zz(v=vs.90).aspx 中描述的步骤调试我的 Release 版本,它呈现出一种特殊的行为:在调试 exe 时在 VS 中,对话框正确呈现。但是,使用相同的 .exe 文件并从 VS 中启动会再次显示错误的对话框。

一开始我以为是某个 DLL 不存在或版本错误(哦,提到我们也从 x86 转到 x64 系统,这可能与此相关;不过,该应用程序仍以 32 位开发),但是自从发布调试以来,我不太确定,因为它不使用调试 DLL(在进程资源管理器中验证它)。

我在这里不知所措,而且不是真正的 c++ 精通,所以任何帮助都将不胜感激:)

EDIT 两个对话框实际上包含相同的组件,Release 版本中的那个出现“折叠”,大部分在左上角,好像它不知道将组件放在哪里。

编辑好的,问题解决了:

好吧,那真是太傻了……

问题出在以下代码中:

CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
CRect rect;
pFrame->Create(NULL, formatString(IDR_TITRE), WS_CAPTION | MFS_SYNCACTIVE, rect, 0);

("CMainFrame" 继承自 CMiniFrameWnd)

"CRect 矩形;"在 VS2003 中没问题,甚至在 VS 2008 中的 Debug 版本中似乎也没问题,尽管回想起来我认为它一直都是错误的,因为它没有初始化对象(如此处所述:msdn.microsoft.com/fr-fr /library/9y3502k0(v=vs.90).aspx)。所以由于某种原因,这在 Release 版本中不起作用。

我不得不像这样编辑它:

CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
CRect rect(0,0,0,0);
pFrame->Create(NULL, formatString(IDR_TITRE), WS_CAPTION | MFS_SYNCACTIVE, rect, 0);

框架的尺寸稍后会重新设计,因此我分配给它的值并不重要,但看来我必须分配它们。

完成此操作后,应用程序可以正常运行并显示良好。

感谢 Michael 为我指明了正确的方向,我想要一个更牵强的解决方案。

【问题讨论】:

看起来好像是一个不同的对话框。在第二个中,您有“Afficher une boîte de diaogue pour le bac manuel”,但在第一个中,您有“Imprimante par défaut”。您是否尝试过“全部重建”? 实际上是同一个对话框,在第二张截图中,一切都只是“折叠”了;第二个中显示的复选框只是第一个中黑色的一个(我忘了在第二个中放一个黑框,这可能会令人困惑,我的错误)。 不要在没有敏感信息的情况下放置黑匣子。尝试通过在 OnInitDialog 函数的不同位置调用 GetWindowRect 来找出对话框何时折叠。 对于如此巨大的布局差异没有简单的解释。没有人可以通过屏幕截图调试您的代码。 @MichaelWalz :是的,我承认我对盒子有点矫枉过正,抱歉。我将尝试记录各种 GetWindowRect 并看看它是如何进行的。汉斯:我知道描述有点模糊,但我正在寻找任何指针来缩小解决方案的范围。我会用我得到的信息进行更新。 【参考方案1】:

CFrameWnd::Create 的文档明确指出,您必须提供一个包含所需窗口大小和位置的矩形,或者您必须提供允许 Windows 选择大小和位置的默认矩形 (rectDefault)。

这个默认矩形在 MFC 中是这样定义的:

const AFX_DATADEF CRect CFrameWnd::rectDefault( CW_USEDEFAULT, CW_USEDEFAULT, 0, 0);

CW_USEDEFAULT 在 WinUser.h 中是这样定义的:

#define CW_USEDEFAULT       ((int)0x80000000)

现在我想你可能只是很幸运,你的应用程序可能会失败,这取决于矩形的未初始化值,即使使用 VS2K3。

【讨论】:

感谢您的详细解释。我得到的是调试中的未初始化值与发布中的值不同(正如您所说,VS2K3 也是如此)。很高兴这已经完成了。

以上是关于从 VS 2k3 到 VS 2k8 - MFC 应用程序无法在发布配置中正确呈现的主要内容,如果未能解决你的问题,请参考以下文章

如何修复从 VS2010 升级到 VS2013 的项目中的链接器错误,其中链接器正在寻找不存在的 MFC 库文件?

使用VS2010MFC写C++注册自定义消息ON_MESSAGE()时提示应输入""

VC6 到 VS2013 MFC 运行时错误

VS2012 到 VS2015 迁移

MFC C++/CLI 项目:VS2012 中的 /CLR 开关导致调试问题

将 VS6 MFC 对话框应用程序外观升级到 VS2008