按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
比「单」有趣,而且本书范例Scribble 程序也使用CMultiDocTemplate,所以我就以此
为说明对象。
CSingleDocTemplate 只支持一种文件类型,所以它的成员变量是:
461
…………………………………………………………Page 524……………………………………………………………
第篇 深入 MFC 程式設計
class CSingleDocTemplate : public CDocTemplate
{
。。。
protected: // standard implementation
CDocument* m_pOnlyDoc;
};
CMultiDocTemplate 支持多种文件类型,所以它的成员变量是:
class CMultiDocTemplate : public CDocTemplate
{
。。。
protected: // standard implementation
CPtrList m_docList;
};
当使用者选按【File/New 】命令项,根据AppWizard 为我们所做的Message Map ,此一
命令由CWinApp::OnFileNew 接手处理。后者调用CDocManager ::OnFileNew,后者再呼
叫CWinApp::OpenDocumentFile,后者再调用CDocManager ::OpenDocumentFile,后者
再调用CMultiDocTemplate::OpenDocumentFile (这是观察MFC 源代码所得结果):
// in AFXWIN。H
class CDocTemplate : public CCmdTarget
{
。。。
UINT m_nIDResource; // IDR_ for frame/menu/accel as well
CRuntimeClass* m_pDocClass; // class for creating new documents
CRuntimeClass* m_pFrameClass; // class for creating new frames
CRuntimeClass* m_pViewClass; // class for creating new views
CString m_strDocStrings; // 'n' separated names
。。。
}
// in DOCMULTI。CPP
CDocument* CMultiDocTemplate::OpenDocumentFile (LPCTSTR lpszPathName;
BOOL bMakeVisible)
{
CDocument* pDocument = CreateNewDocument ();
。。。
CFrameWnd* pFrame = CreateNewFrame (pDocument; NULL);
。。。
if (lpszPathName == NULL)
{
// create a new document with default document name
462
…………………………………………………………Page 525……………………………………………………………
第8章 Document…View 深入探討
。。。
}
else
{
// open an existing document
。。。
}
InitialUpdateFrame(pFrame; pDocument; bMakeVisible);
return pDocument;
}
顾名思义,我们很容易作出这样的联想:CreateNewDocument 动态产生Document ,
CreateNewFrame 动态产生Document Frame 。的确是这样没错,它们利用CRuntimeClass
的CreateObject 做「动态生成」动作:
// in DOCTEMPL。CPP
CDocument* CDocTemplate::CreateNewDocument ()
{
。。。
CDocument* pDocument = (CDocument*)m_pDocClass…》CreateObject ();
。。。
AddDocument(pDocument);
return pDocument;
}
CFrameWnd* CDocTemplate::CreateNewFrame (CDocument* pDoc; CFrameWnd* pOther)
{
// create a frame wired to the specified document
CCreateContext context;
context。m_pCurrentFrame = pOther;
context。m_pCurrentDoc = pDoc;
context。m_pNewViewClass = m_pViewClass;
context。m_pNewDocTemplate = this;
。。。
CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass…》CreateObject ();
。。。
// create new from resource
pFrame…》LoadFrame (m_nIDResource;
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE; // default frame styles
NULL; &context)
。。。
return pFrame;
}
在CreateNewFrame 函数中, 不仅Frame 被动态生成出来了,其对应窗口也以
463
…………………………………………………………Page 526……………………………………………………………
第篇 深入 MFC 程式設計
LoadFrame 产生出来了。但有两件事情令人不解。第一,我们没有看到View 的动态生
成动作;第二,出现一个奇怪的家伙CCreateContext,而前一个不解似乎能够着落到这
个奇怪家伙的身上,因为CDocTemplate::m_pViewClass 被塞到它的一个字段中。
但是线索似乎已经中断,因为我们已经看不到任何可能的调用动作了。等一等!context 被
用作LoadFrame 的最后一个参数,这意味什么?还记得第六章「CFrameWnd::Create 产
生主窗口(并先注册窗口类别)」那一节提过Create 的最后一个参数吗,正是这context 。
那么,是不是Document Frame 窗口产生之际由于WM_CREATE 的发生而刺激了什么动
作?
虽然其结果是正确的,但这样的联想也未免太天马行空了些。我只能说,经验累积出判
断力!是的,WM_CREATE 引发CFrameWnd::OnCreate 被唤起,下面是相关的调用次序
(经观察MFC 源代码而得知):
CFrameWnd::OnCreate
CFrameWnd::OnCreate
CFrameWnd::OnCreateHelper
CFrameWnd::OnCreateHelper
CFrameWnd::OnCreateClient
CFrameWnd::OnCreateClient