(4) 在MainFrm.h文件的前面添加下列代码,如图10所示的加框部分。
图10 在MainFrm.h中添加的语句
不少人对上述语句不理解:既然使用了包含文件,为什么还要在class CMainFrame前添加"class CViewerView;"等代码?如果用包含文件代替它,行不行?
很多Visual C++书籍对这些问题避而不谈,但实际上这是一个重要的问题。如果不能理解上述代码,我们很可能为无法通过编译而大伤脑筋。这些问题的出现是基于这样的一些事实:在我们用标准C/C++设计
程序时,有一个原则即两个代码文件不能相互包含,而且多次包含还会造成重复定义的错误。为了
解决这个难题,Visual C++使用#pragma once来通知编译器在生成时只包含(打开)一次,也就是说,在第一次#include之后,编译器重新生成时不会再对这些包含文件进行包含(打开)和读取,因此我们看到在用向导创建的所有类的头文件中有#pragma once语句就不会觉得奇怪了。然而正是由于这个语句而造成了在第二次#include后编译器无法正确识别所引用的类。因此,我们在相互包含时还需要加入类似class CViewerView这样的语句来通知编译器这个类是一个实际的调用。
(5) 重新生成解决方案后运行程序,看看有没有出现编译错误,此时提示出SwitchToView1函数中,CViewerView和CWebView类无法构造,因为它们的构造函数是protected。
(6) 分别在ViewerView.h和WebView.h文件中,将构造函数CViewerView()和CWebView()前面的访问方式改成public。再运行程序。
(7) 为CMainFrame类添加一个int类型的成员变量m_nViewID,并将其初值设为1。
(8) 为CMainFrame类添加菜单项ID_VIEW_TEXT的COMMAND和UPDATE_COMMAND_UI的事件映射,并在映射函数添加如图11所示的代码。
图11 ID_VIEW_TEXT的映射函数代码
(9) 为CMainFrame类添加菜单项ID_VIEW_HTML的COMMAND和UPDATE_COMMAND_UI的事件映射,并在映射函数添加如图12所示的代码。
图12 ID_VIEW_HTML的映射函数
代码 (10) 运行程序,结果如前面图2所示。