概述1、
文档类CDocument在"文档/
视图"架构的MFC程序中,文档是一个CDocument派生对象,它负责存储应用程序的数据,并把这些信息提供给应用程序的其余部分。CDocument类对文档的建立及归档提供支持并提供了应用程序用于控制其数据的接口,类CDocument的声明如下:////////////////////////////
1、文档类Cdocument
在"文档/视图"架构的MFC程序中,文档是一个Cdocument派生对象,它负责存储应用程序的数据,并把这些信息提供给应用程序的其余部分。Cdocument类对文档的建立及归档提供支持并提供了应用程序用于控制其数据的接口,类Cdocument的声明如下:
/ // class Cdocument is the main document data abstraction class Cdocument : public CCmdTarget { DECLARE_DYNAMIC(Cdocument) public: // Constructors Cdocument();
// Attributes public: const CString& GetTitle() const; virtual voID SetTitle(LPCTSTR lpszTitle); const CString& GetPathname() const; virtual voID SetPathname(LPCTSTR lpszPathname,BOol bAddTomrU = TRUE);
CDocTemplate* GetDocTemplate() const; virtual BOol IsModifIEd(); virtual voID SetModifIEdFlag(BOol bModifIEd = TRUE);
// Operations voID AddVIEw(CVIEw* pVIEw); voID RemoveVIEw(CVIEw* pVIEw); virtual position GetFirstVIEwposition() const; virtual CVIEw* GetNextVIEw(position& rposition) const;
// Update VIEws (simple update - DAG only) voID UpdateallVIEws(CVIEw* pSender,LParaM lHint = 0L, CObject* pHint = NulL);
// OverrIDables // Special notifications virtual voID OnChangedVIEwList(); // after Add or Remove vIEw virtual voID DeleteContents(); // delete doc items etc
// file helpers virtual BOol OnNewdocument(); virtual BOol Onopendocument(LPCTSTR lpszPathname); virtual BOol OnSavedocument(LPCTSTR lpszPathname); virtual voID OnClosedocument(); virtual voID ReportSaveLoadException(LPCTSTR lpszPathname, CException* e,BOol bSaving,UINT nIDPDefault); virtual Cfile* Getfile(LPCTSTR lpszfilename,UINT nopenFlags, CfileException* pError); virtual voID Releasefile(Cfile* pfile,BOol bAbort);
// advanced overrIDables,closing down frame/doc,etc. virtual BOol CanCloseFrame(CFrameWnd* pFrame); virtual BOol SaveModifIEd(); // return TRUE if ok to continue virtual voID PreCloseFrame(CFrameWnd* pFrame);
// Implementation protected: // default implementation CString m_strTitle; CString m_strPathname; CDocTemplate* m_pDocTemplate; CPtrList m_vIEwList; // List of vIEws BOol m_bModifIEd; // changed since last saved
public: BOol m_bautoDelete; // TRUE => delete document when no more vIEws BOol m_bEmbedded; // TRUE => document is being created by olE
#ifdef _DEBUG virtual voID Dump(CDumpContext&) const; virtual voID AssertValID() const; #endif //_DEBUG virtual ~Cdocument();
// implementation helpers virtual BOol DoSave(LPCTSTR lpszPathname,BOol bReplace = TRUE); virtual BOol DofileSave(); virtual voID UpdateFrameCounts(); voID disconnectVIEws(); voID SendInitialUpdate();
// overrIDables for implementation virtual HMENU GetDefaultMenu(); // get menu depending on state virtual HACCEL GetDefaultAccelerator(); virtual voID OnIDle(); virtual voID OnFinalRelease();
virtual BOol OnCmdMsg(UINT nID,int nCode,voID* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo); frIEnd class CDocTemplate;
protected: // file menu commands //{{AFX_MSG(Cdocument) afx_msg voID OnfileClose(); afx_msg voID OnfileSave(); afx_msg voID OnfileSaveAs(); //}}AFX_MSG // mail enabling afx_msg voID OnfileSendMail(); afx_msg voID OnUpdatefileSendMail(CCmdUI* pCmdUI); DECLARE_MESSAGE_MAP() }; |
一个文档可以有多个视图,每一个文档都维护一个与之相关视图的链表(CptrList类型的 m_vIEwList实例)。Cdocument::AddVIEw将一个视图连接到文档上,并将视图的文档指针指向该文档:
voID Cdocument::AddVIEw(CVIEw* pVIEw) { ASSERT_VALID(pVIEw); ASSERT(pVIEw->m_pdocument == NulL); // must not be already attached ASSERT(m_vIEwList.Find(pVIEw,NulL) == NulL); // must not be in List
m_vIEwList.AddTail(pVIEw); ASSERT(pVIEw->m_pdocument == NulL); // must be un-attached pVIEw->m_pdocument = this;
OnChangedVIEwList(); // must be the last thing done to the document } |
Cdocument::RemoveVIEw则完成与Cdocument::AddVIEw相反的工作:
voID Cdocument::RemoveVIEw(CVIEw* pVIEw) { ASSERT_VALID(pVIEw); ASSERT(pVIEw->m_pdocument == this); // must be attached to us
m_vIEwList.RemoveAt(m_vIEwList.Find(pVIEw)); pVIEw->m_pdocument = NulL;
OnChangedVIEwList(); // must be the last thing done to the document } |
从Cdocument::AddVIEw和Cdocument::RemoveVIEw函数可以看出,在与文档关联的视图被移走或新加入时Cdocument::OnChangedVIEwList将被调用:
voID Cdocument::OnChangedVIEwList() { // if no more vIEws on the document,delete ourself // not called if directly closing the document or terminating the app if (m_vIEwList.IsEmpty() && m_bautoDelete) { OnClosedocument(); return; }
// update the frame counts as needed UpdateFrameCounts(); } |
Cdocument::disconnectVIEws将所有的视图都与文档"失连":
voID Cdocument::disconnectVIEws() { while (!m_vIEwList.IsEmpty()) { CVIEw* pVIEw = (CVIEw*)m_vIEwList.Removehead(); ASSERT_VALID(pVIEw); ASSERT_KINDOF(CVIEw,pVIEw); pVIEw->m_pdocument = NulL; } } |
实际上,类Cdocument对视图的管理与类CDocManager对文档模板的管理及CDocTemplate对文档的管理非常类似,少不了的,类Cdocument中可遍历对应的视图(出现GetFirstXXX和GetNextXXX两个函数):
position Cdocument::GetFirstVIEwposition() const { return m_vIEwList.Getheadposition(); }
CVIEw* Cdocument::GetNextVIEw(position& rposition) const { ASSERT(rposition != BEFORE_START_position); // use Cdocument::GetFirstVIEwposition instead ! if (rposition == NulL) return NulL; // nothing left CVIEw* pVIEw = (CVIEw*)m_vIEwList.GetNext(rposition); ASSERT_KINDOF(CVIEw,pVIEw); return pVIEw; } |
Cdocument::Getfile和Cdocument::Releasefile函数完成对参数lpszfilename指定文档的打开与关闭 *** 作:
Cfile* Cdocument::Getfile(LPCTSTR lpszfilename, CfileException* pError) { CMirrorfile* pfile = new CMirrorfile; ASSERT(pfile != NulL); if (!pfile->Open(lpszfilename,nopenFlags,pError)) { delete pfile; pfile = NulL; } return pfile; }
voID Cdocument::Releasefile(Cfile* pfile,BOol bAbort) { ASSERT_KINDOF(Cfile,pfile); if (bAbort) pfile->Abort(); // will not throw an exception else pfile->Close(); delete pfile; } |
Cdocument类的OnNewdocument、Onopendocument、OnSavedocument及OnClosedocument这一组成员函数用于创建、打开、保存或关闭一个文档。在这一组函数中,上面的Cdocument::Getfile和Cdocument::Releasefile两个函数得以调用:
BOol Cdocument::Onopendocument(LPCTSTR lpszPathname) { if (IsModifIEd()) TRACE0("Warning: Onopendocument replaces an unsaved document./n");
CfileException fe; Cfile* pfile = Getfile(lpszPathname, Cfile::modeRead|Cfile::shareDenyWrite,&fe); if (pfile == NulL) { ReportSaveLoadException(lpszPathname,&fe,FALSE,AFX_IDP_Failed_TO_OPEN_DOC); return FALSE; }
DeleteContents(); SetModifIEdFlag(); // dirty during de-serialize
CArchive loadArchive(pfile,CArchive::load | CArchive::bNoFlushOnDelete); loadArchive.m_pdocument = this; loadArchive.m_bForceFlat = FALSE; TRY { CWaitCursor wait; if (pfile->GetLength() != 0) Serialize(loadArchive); // load me loadArchive.Close(); Releasefile(pfile,FALSE); } CATCH_ALL(e) { Releasefile(pfile,TRUE); DeleteContents(); // remove Failed contents
TRY { ReportSaveLoadException(lpszPathname,e,AFX_IDP_Failed_TO_OPEN_DOC); } END_TRY DELETE_EXCEPTION(e); return FALSE; } END_CATCH_ALL
SetModifIEdFlag(FALSE); // start off with unmodifIEd
return TRUE; } |
|
|
总结
以上是内存溢出为你收集整理的深入浅出MFC文档/视图架构之文档(1)全部内容,希望文章能够帮你解决深入浅出MFC文档/视图架构之文档(1)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)