在阅读《Visual C++技术内幕》时,对于第一个例子:MyApp,产生了不少困扰——代码敲进去以后,总是无法生成、运行,各种错误。

起初看的是第四版,后来又看了第六版(书名变成了:《Microsoft Visual C++ .NET 技术内幕(第六版)》,仍然是潘爱民先生翻译的,出版社是清华大学出版社)。两本书上的代码都试过了,都没有成功。

使用的IDE是Microsoft Visual Studio 2010 Ultimate简体中文版,以及Microsoft Visual C++ 6.0 Enterprise Edition(sp6)。

到网上搜索了一下,也有同样的问题被提出,虽然时间上比较早——多半是在2001/2006/2007年的。也有人提出的解决方案,并且有人反映没问题,但是也有反映没有解决的,我自己也尝试了,也没有解决。

最后连蒙带猜,终于生成、运行了。。。回过头来,小结一下几点。

第一,建立什么工程。如果用“MFC App Wizard(exe)”,那不管怎么样,工程已建立起来,就已经有了一大堆的文件,而书中并没有说要把这两段代码插入到哪里——换言之,这些代码放在什么地方呢?不知道。于是就想是不是建一个空白的工程,结果不行,按照网上的解决方法修改了工程属性,还是不行。我记得自己也尝试过建立“Win32 应用程序”工程,但是不知道为什么也没有成功。事实上,后来就是建立的“Win32 应用程序”工程(空工程),然后修改属性以后就成功了。——有点可惜,没有发现前面建立“Win32 应用程序”工程的时候有什么问题。

第二,就是建立工程以后,怎么样才能正确让程序生成、运行。关键的一点就是修改工程属性。步骤如下:

【VC6】“project”菜单→settings,General选项卡,在Microsoft Foundation Classes的下拉菜单中选择“Use MFC in a Shared DLL”(原来是“Not Using MFC”),然后点击“OK”即可。

【VS2010】“项目”菜单→project_name属性,在弹出窗口的左边选择“配置属性→常规”,然后在右边“项目默认值→MFC的使用”一栏的下拉菜单中选择“在共享DLL中使用MFC”,然后点击“确定”即可。

这样修改之后,在VC6中就已经可以Build和Run了,出来的结果如下图。 

但是这个时候再VS2010中还是不能运行,代码还有一个小地方要修改下,这就算做是第三点吧。在*.cpp文件中找到“CMyFrame::CMyFrame ()”定义(根据编译或者生成时报出的错误可以直接双击错误提示定位),对常量字符串(常量字符数组)“"MyApp Application"”使用重解释转换(用关键字reinterpret_cast),转换为要求的“LPCTSTR”类型,这样就可以了。

其实这样并没有很好的解决问题,看下图的运行结果就可以知道。 

标题栏上出现了乱码。。。问题肯定是在修改的那个类型转换上,但是怎么样才能不出现这种“副作用”,目前不知道(本人系初学者。。。)。只能说:唉,总算可以运行出结果了。

在正确运行之前,有过如下一些错误提示。

【VC6】

nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex

nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex

Debug/test1.exe : fatal error LNK1120: 2 unresolved externals

Error executing link.exe.

【VS2010】

.../afx.h(24): fatal error C1189: #error :  Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]

error C2664: “CFrameWnd::Create”: 不能将参数 2 从“const char [18]”转换为“LPCTSTR”与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换

附:《Microsoft Visual C++ .NET 技术内幕(第六版)》上有关的源代码 

 
  
  1. // MyApp.h 
  2. // application class 
  3. class CMyApp : public CWinApp 
  4. public
  5.     virtual BOOL InitInstance (); 
  6. }; 
  7.  
  8. // frame window class 
  9. class CMyFrame : public CFrameWnd 
  10. public
  11.     CMyFrame(); 
  12. protected
  13.     // "afx_msg" indicates that the next two functions are part 
  14.     // of the MFC library message dispatch system 
  15.     afx_msg void OnLButtonDown(UINT nFlags,CPoint point); 
  16.     afx_msg void OnPaint(); 
  17.     DECLARE_MESSAGE_MAP() 
  18. }; 
  19.  
  20. // MyApp.cpp 
  21.  
  22. #include <afxwin.h> // MFC library header file declares base classes 
  23. #include "MyApp.h" 
  24.  
  25. CMyApp theApp; // the one and only CMyApp object 
  26.  
  27. BOOL CMyApp::InitInstance() 
  28.     m_pMainWnd = new CMyFrame(); 
  29.     m_pMainWnd->ShowWindow(m_nCmdShow); 
  30.  
  31.     m_pMainWnd->UpdateWindow(); 
  32.     return TRUE; 
  33.  
  34. BEGIN_MESSAGE_MAP (CMyFrame,CFrameWnd) 
  35.     ON_WM_LBUTTONDOWN() 
  36.     ON_WM_PAINT() 
  37. END_MESSAGE_MAP() 
  38.  
  39. CMyFrame::CMyFrame () 
  40.     Create(NULL,reinterpret_cast<LPCTSTR>("MyApp Application")); 
  41.     // Create(NULL, "MyApp Application"); 
  42.  
  43. void CMyFrame::OnLButtonDown (UINT nFlags,CPoint point) 
  44.     TRACE("Entering CMyFrame::OnLButtonDown - %1x, %d, %d\n"
  45.         (long)nFlags,point.x,point.y); 
  46.  
  47. void CMyFrame::OnPaint () 
  48.     CPaintDC dc(this); 
  49.     dc.TextOutW(0,0,"Hello, world!");