Visual C++ 6.0开发环境中,我们可以用MFC AppWizard 自动生成一个应用程序
。其中包括了应用类,主边框窗口类,子边框窗口类(MDI 应用程序),文档类
和视 图类。另外,系统还自动生成了一个文档模板类对象,它把文档类,文档边
框窗口类(SDI 中的主边框窗口类或MDI 中的子边框窗口类),视图类联系在一
起,组成一个有机的整体。
在一些专业教材书中,虽然提到了它们之间的关系,但都没有全面系统地予
以介 绍。使得初学 VC 的朋友在各类对象之间相互访问时感到非常困难。笔者经
过一段时间 的总结,现将各类对象之间的关系以及相互之间访问的方法介绍如下:
1。应用类对象 :
应用类对象由应用框架自动生成。虽然在应用类的 cpp 文件中有一个应
用类对象的声明语句,但该对象却无法使用。用户可以通过 CWinApp *
AfxGetApp() 全局函数得到指向应用类对象的指针,由于该函数返回值为
CWinApp * 类型,因此需要进行转换。
用法如下:
假设您的应用类名为:CExampleApp。
CExamlpleApp * p=(CExamlpleApp *)AfxGetApp();
p 即为指向应用类对象的指针。
2。主边框窗口类(CMainFrame):
主边框窗口类对象的生成较为复杂,对于 MDI 应用程序,主边框窗口类对象由应
用类对象在它的 InitInstance()函数中构造生成;对于 SDI 应用程序,主边框窗口类
对象由文档模板类构造生成。
用户可以用下列方式获得指向主边框窗口类对象的指针:
(1).利用全局函数 AfxGetMainWnd().
(2).通过应用类的 GetMainWnd() 成员函数或 m_pMainWnd 成员变量。
(3).对于 MDI 应用程序,还可以通过子边框窗口类的 GetMIDFrame()成员函数
得到。
同理,以上各函数的返回值也是 CFrameWnd * 类型( SDI 应用程序)或
CMDIFrameWnd * 类型( MDI 应用程序),仍需要转换成 CMainFrame * 类型。
注:以下各函数的返回值均需要转换成相应类的指针类型。下面不再敖述。
3. 文档模板类:
文档模板类对象由应用对象在 InitInstance()函数中构造生成。它分为:单文档
模板类(CSingleDocTemplate)和多文档模板类(CMultiDocTemplate),分别对应 SDI应
用程序和 MDI应用程序。二者均由CDocTemplate派生。文档模板类把文档类,文档边框
窗口类(SDI 中的主边框窗口类或MDI 中的子边框窗口类),视图类联系为一个有机的
整体。应用类对象通常只生成一个文档模板类对象 ,不过用户可以自己生成多个文档模
板类对象,从而使SDI 也可以打开多个文档,具有了MDI的特征.所有的文档模板类对象组
成了一个链表,应用类的m_pDocManger 成员变量指向该链表。
用户可以通过应用类的成员函数 GetFirstDocTemplatePosition()和
GetNextDocTemplate(POSITION & pos)来访问该链表:
POSITION pos;
pos=GetFirstDocTemplatePosition();
CDocTemplate * pDocTemplate;
pDocTemplate=GetNextDocTemplate(pos);
pDocTemplate 即是指向第一个文档模板类对象的指针,用户还可以继续调用
GetNextTemplate()得到下一个文档模板类对象.
4。子边框窗口类(CChildFrame):
子边框窗口类是专门针对 MDI 应用程序而言的,它由文档模板类构造生成。对它
的访问可用以下方式实现:
通过主边框窗口类的 CFrameWnd * GetActiveFrame() 得到指向该对象的指针。
5.文档类:
文档类对象由文档模板类构造生成。单文档模板类只能生成一个文档类对象,并
用成员变量 m_pOnlyDoc 指向该对象。多文档模板类可以生成多个文档类对象,另用成
员变量 m_docList 指向文档对象组成的链表。在 SDI 应用程序中,当我们生成多个单
文档模板类对象时,就可以打开多个文档。
用户可以通过多文档模板类对象的成员函数 GetFirstDocPosition() 和
GetNextDoc(POSITION &pos) 来访问文档对象组成的链表:
POSITION pos;
pos=GetFirstDocPosition();
CDocument *pDoc;
pDoc=GetNextDoc(pos);
另外,文档类还可以通过其成员函数 CDocTemplate * GetDocTemplate() 返过来
访问文档模板类对象.
对于当前活动的文档类对象,我们还可以通过以下方式访问:
(1).通过子边框窗口(MDI 应用程序)或主边框窗口(SDI 应用程序)的成员函数
CDocument * GetActiveDocument() 可以得到指向该文档的指针.
(2).另外视图类的成员函数 CDocument * GetDocument()以及成员变量
m_pDocument 也可以得到指向该文档的指针.
6.视图类:
视图类对象是由主边框窗口(SDI 应用程序)或子边框窗口(MDI 应用程序)构造生成
的.因此它的访问方式有以下两种:
(1).对于当前活动的视图类对象可以由主边框窗口(SDI 应用程序)或子边框窗口
(MDI 应用程序)的成员函数 CView * GetAcitveView() 来得到该对象的指针.
(2).另外,还可以通过文档类的成员函数 GetFirstViewPosition() 和
CView * GetNextView() 来访问所有的视图类对象。
其用法与上面文档模板类函数类似。
以上各类的成员变量或成员函数基本上使我们在任何位置都可以访问到应用程序的
每一个角落,但对于频繁性地访问某一固定对象或对运行速度要求较高的场合,我们可以
通过保存该对象的窗口句柄(只限于派生于 CWnd 的类),在需要的时候,通过函数
CWnd::FromHandle(HWND hwnd) 来得到该对象的指针.