自从我们从Visual Studio 6切换到Visual Studio 2008以来,我们一直在使用MFC90.dll和msvc [pr] 90.dlls以及私有并排配置中的清单文件,以免担心版本或者将它们安装到系统中.
在SP1之前,这个工作正常(在我们的开发人员机器上仍能正常工作).现在我们已经在SP1之后做了一些测试,从昨天早上起我一直在拉头发.
首先,我们的NSIS安装程序脚本从redist文件夹中提取dll和manifest文件.这些不再正确,因为应用程序仍然链接到RTM版本.
所以我为_BIND_TO_CURRENT_VCLIBS_VERSION=1所有项目添加了define,以便他们在redist文件夹中使用SP1 DLL(或随后的新服务包出来).我花了好几个小时才找到这个.
我已经从编译中检查了中间文件文件夹中生成的清单文件,并正确列出了9.0.30729.1 SP1版本.我有双重和三重检查取决于一台干净的机器:它都链接到本地dll没有错误.
运行应用程序仍会收到以下错误:
应用程序无法正确初始化(0xc0150002).单击"确定"以终止该应用程序.
我在谷歌或微软上所做的任何搜索都没有提出任何与我的具体问题相关的信息(但是这些错误消息可以追溯到2005年).
有没有任何一个与SP1有类似的问题?
选项:
编辑:我尝试重新构建关闭定义(链接到RTM dll),只要RTM dll安装在文件夹中,它就可以工作.如果SP1 dll被删除,则会出现以下错误:
c:\ Program Files\...\...\X.exe
此应用程序无法启动,因为应用程序配置不正确.重新安装应用程序可能会解决此问题.
没有人不得不处理这个问题吗?
编辑:只是为了笑容,我下载并在我的测试机器上运行VS2008SP1的vcredist_x86.exe.它有效.使用SP1 DLL.我的RTM链接应用程序.但不是在SP1之前工作的私有并行分发.
当用户抓住可调整大小的窗口的角落,然后移动它时,窗口首先移动窗口的内容,然后向正在调整大小的窗口发出WM_SIZE.
因此,在我想要控制各种子控件移动的对话框中,我想消除闪烁,用户首先看到Windows操作系统认为窗口看起来像什么(因为,AFAICT,操作系统使用bitblt方法移动在发送WM_SIZE之前窗口内部的东西) - 然后我的对话框才能处理移动其子控件或调整它们等等,之后它必须强制重新绘制内容,这会导致闪烁(在此处最小).
我的主要问题是:有没有办法强迫Windows不要做这个愚蠢的bitblt事情? 在窗口调整大小时移动控件的窗口或者调整其父级调整大小时,它肯定会出错.无论哪种方式,让操作系统进行预涂,只需拧紧工件即可.
我想了一段时间它可能与CS_HREDRAW和CSVREDRAW类标志有关.然而,现实是我不希望操作系统要求我擦除窗口 - 我只是想在没有操作系统的情况下重新绘制我自己的窗口内容(即我希望显示器是它的内容)在用户开始调整大小之前 - 没有来自操作系统的任何bitblit'.而且我不希望操作系统告诉每个控件它需要重绘(除非它恰好是一个实际上被调整后显示或显示的显示.
我真正想要的是:
注意:步骤2和3可以颠倒过来.
当我将DeferSetWindowPos()与标记为WS_CLIPCHILDREN的对话框资源结合使用时,上述三件事似乎正确发生.
如果我可以将上述内容用于内存DC,那么我将获得额外的小好处,然后在WM_SIZE处理程序的末尾只执行一个bitblt.
我已经玩了一段时间了,我无法逃脱两件事:
我仍然无法抑制Windows做"预测bitblt". 答案:请参阅下面的解决方案,该解决方案将覆盖WM_NCCALCSIZE以禁用此行为.
我无法看到如何构建一个对话框,其子控件绘制到双缓冲区.答案:请参阅下面的约翰答案(标记为答案),了解如何让Windows操作系统对对话框进行双重缓冲(注意:根据文档,这不允许任何GetDC()中间的绘制操作).
我的最终解决方案(谢谢所有贡献的人,尤其是John K.):
经过大量的汗水和泪水,我发现以下技术在Aero和XP或Aero禁用时都能完美运行.轻弹不存在(1).
布局代码取决于您 - 它很容易在CodeGuru或CodeProject上找到布局管理器的示例,或者自己动手.
以下是一些代码摘录,可以帮助您完成大部分工作:
LRESULT ResizeManager::WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_ENTERSIZEMOVE:
m_bResizeOrMove = true;
break;
case WM_NCCALCSIZE:
// The WM_NCCALCSIZE idea was given to me by John Knoeller:
// see: http://stackoverflow.com/questions/2165759/how-do-i-force-windows-not-to-redraw-anything-in-my-dialog-when-the-user-is-resiz
//
// The default …Run Code Online (Sandbox Code Playgroud) 在VC++中,我们有数据类型"BOOL",可以假设值为TRUE或FALSE,并且我们有数据类型"bool",它可以假定值为true或false.
它们之间的区别是什么时候应该使用每种数据类型?
我刚刚将这一点包含在我已经运行的代码中,但是我收到了LNK2019错误.粘贴代码后我会粘贴错误.
CAboutDlg类具有:
public:
CStatic m_VersionInfoCtrl;
virtual BOOL OnInitDialog();
};
Run Code Online (Sandbox Code Playgroud)
功能本身:
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CString inFileName = AfxGetApp()->m_pszExeName;
inFileName += ".exe";
void * theVersionInfo;
void * theFixedInfo;
unsigned long aVersionInfoSize = GetFileVersionInfoSize ( inFileName , &aVersionInfoSize);
CString returnString;
if (aVersionInfoSize)
{
theVersionInfo = new char [aVersionInfoSize];
GetFileVersionInfo ( inFileName, 0 , aVersionInfoSize, theVersionInfo) ;
unsigned int aSize = 0;
VerQueryValue( theVersionInfo , "\\" , &theFixedInfo , &aSize);
if (theFixedInfo)
{
VS_FIXEDFILEINFO * aInfo = (VS_FIXEDFILEINFO *) theFixedInfo;
DWORD dwMajorVersionMsb = …Run Code Online (Sandbox Code Playgroud) 我知道乔尔说永远不会这样做,我在大多数情况下同意这一点.我认为有些情况是合理的.
我们有一个大型C++应用程序(大约250,000行代码),它使用MFC前端和Windows服务作为核心组件.我们正在考虑将项目转移到C#.
我们考虑重写的原因是:
有人做过像这样的重写吗?它成功了吗?
编辑:
该项目现在已有近10年的历史了,我们正在努力增加我们想要的新功能,即编写.NET已经内置的重要功能.
以前,我曾经使用MFC的集合类CArray和CMap.过了一会儿,我换了STL容器,并且已经使用了一段时间.虽然我发现STL要好得多,但我无法明确指出它的确切原因.一些推理如:
我可以提出的唯一原因是我可以在容器上使用算法.我在这里缺少任何其他原因 - 是什么让STL容器比MFC容器更好?
我想在用户选择CListCtrl中的行时执行一些代码(报表视图,我不关心其他查看模式).
我如何抓住这个活动?是否有一些我可以映射的消息或像"OnSelectionChanged"这样的方法?
我目前正在研究一个非常大的传统MFC MDI应用程序.它有大量的UI元素 - 可停靠的工具栏,自定义树控件,上下文菜单等.它是一个图像处理应用程序,因此主视图使用DirectX和OpenGL自我渲染.该产品大约有10年的历史,其中一个优先事项是更新它的外观和感觉.
知道微软在提供C++/MFC和.NET之间的互操作性方面做得很好,我认为以递增方式迁移代码库是有意义的.我现在正在努力的是从哪里开始.
一种方法是使用WPF删除MFC框架并尽可能多地重用C++代码.这将让我们最大限度地发挥WPF架构的优势,但这将意味着一个漫长的开发周期,直到我们再次完全正常运行.
另一种方法是用它们的WPF对应物一次替换一个MFC控件.这将允许我们以增量方式工作.我对这种方法的关注是,它意味着托管和非托管代码之间会有很多连接点,我不知道从哪里开始替换主菜单和工具栏等内容.
或者我还有其他选择吗?
任何有关此主题的信息的建议或链接将不胜感激.
更新: DavidK提出了一些很好的问题,所以我添加了这背后的动机.
1)产品的未来发展
该产品仍在积极开发中,并定期添加新功能.我认为尝试慢慢迁移到C#/ WPF会很有意义.凭借我在C#/ WPF方面的有限经验,我发现在C++/MFC中工作效率会提高.
我们用WPF获得的另一件大事就是能够利用多头系统.MFC应用程序仅限于单个顶级框架,因此很难利用多个监视器.
2)员工保留和招聘
找到愿意使用MFC的开发人员越来越难了.对于当前开发人员的职业发展而言,接触新技术也很重要.