友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
深入浅出MFC第2版(PDF格式)-第95部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
CString aStr;
。。。 // read a string from file to aStr
CStroke* pStroke = new aStr;
不行!这是语言版的动态生成;没有任何一个C++ 编译器支持这种能力。那么我能够这
么做吗:
CString aStr;
CStroke* pStroke;
。。。 // read a string from file to aStr
if (aStr == CString(〃CStroke〃)
CStroke* pStroke = new CStroke;
else if (aStr == CSting(〃C1〃)
C1* pC1 = new C1;
else if (aStr == CSting(〃C2〃)
C2* pC2 = new C2;
else if (aStr == CSting(〃C3〃)
C1* pC3 = new C3;
else 。。。
可以,但真是粗糙啊。万一再加上一种新类别呢?万一又加上一种新类别呢?不胜其扰
也!
第3章已经提出动态生成的观念以及实作方式了。主要关键还在于一个「类别型录网」。
这个型录网就是CRuntimeClass 组成的一个串行。每一个想要享有动态生成机能的类别,
都应该在「类别型录网」上登记有案,登记资料包括对象的构造函数的指针。也就是说,
上述那种极不优雅的比对动作,被MFC 巧妙地埋起来了;应用程序可以风姿优雅地,
514
…………………………………………………………Page 577……………………………………………………………
第8章 Document…View 深入探討
单单使用DECLARE_SERIAL 和IMPLEMENT_SERIAL 两个宏,就获得文件读写以及
动态生成两种机制。
我将仿效前面对于写档动作的探索,看看读文件的程序如何。
【 】
File/Open
CScribbleApp 的Message Map 中指定由CWinApp::OnFileOpen()
拦截【File/Open】命令消息
BEGIN_MESSAGE_MAP(CScribbleApp; CWinApp)
BEGIN_MESSAGE_MAP(CScribbleApp; CWinApp)
ON_MAND(ID_APP_ABOUT; OnAppAbout)
ON_MAND(ID_APP_ABOUT; OnAppAbout)
ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew)
ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew)
ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen)
ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen)
ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup)
ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
END_MESSAGE_MAP()
void CWinApp::OnFileOpen()
{
m_pDocManager 是个CDocManager ASSERT(m_pDocManager != NULL);
对象,后者是一个未公开的MFC 4。0 m_pDocManager…》OnFileOpen();
新类别,用来维护一长串的Document }
Template。
void CDocManager::OnFileOpen()
void CDocManager::OnFileOpen()
{
{
// prompt the user (with all document templates)
// prompt the user (with all document templates)
CString newName;
CString newName;
if (!DoPromptFileName (newName; AFX_IDS_OPENFILE;
if (!DoPromptFileName (newName; AFX_IDS_OPENFILE;
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; TRUE; NULL))
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; TRUE; NULL))
return; // open cancelled
return; // open cancelled
AfxGetApp()…》OpenDocumentFile(newName);
AfxGetApp()…》OpenDocumentFile(newName);
// if returns NULL; the user has already been alerted
// if returns NULL; the user has already been alerted
}
}
下页
515
…………………………………………………………Page 578……………………………………………………………
第篇 深入 MFC 程式設計
CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)
CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)
{
{
ASSERT(m_pDocManager != NULL);
ASSERT(m_pDocManager != NULL);
return m_pDocManager…》OpenDocumentFile (lpszFileName);
return m_pDocManager…》OpenDocumentFile (lpszFileName);
}
}
很多原先在CWinApp 中做掉的有关于Document
Template 的工作,如AddDocTemplate、
OpenDocumentFile 和NewDocumentFile,自从
MFC 4。0 之后已隔离出来由CDocManager 负责。
CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName)
{
// find the highest confidence
CDocTemplate* pBestTemplate = NULL;
CDocument* pOpenDocument = NULL;
TCHAR szPath'_MAX_PATH';
。。。 //从「Document Template 串行」中找出最适当之template,
。。。 //放到pBestTemplate 中。
return pBestTemplate…》OpenDocumentFile (szPath);
}
由于CMultiDocTemplate改写了OpenDocumentFile;所以调用
的是CMultiDocTemplate::OpenDocumentFile。
下页
516
…………………………………………………………Page 579……………………………………………………………
第8章 Document…View 深入探討
CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName;
BOOL bMakeVisible)
{
CDocument* pDocument = CreateNewDocument();
。。。
CFrameWnd* pFrame = CreateNewFrame(pDocument; NULL);
。。。
由于CScribbleDoc 改写了OnOpenDocument,
if (lpszPathName == NULL) 所以调用的是CScribbleDoc::OnOpenDocument
{
// create a new document with default document name
。。。
}
else
{
// open an existing document
CWaitCursor wait;
if (!pDocument…》OnOpenDocument (lpszPathName))
{ 源代码请见本章前部之“CDocTemplate管理
。。。
CDocument/CView/CFrameWnd” 一节.
}
pDocument…》SetPathName(lpszPathName);
BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName)
} {BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument (lpszPathName))
if (!CDocument::OnOpenDocument (lpszPathName))
return FALSE;
return FALSE;
InitDocument();
InitDocument();
return TRUE;
return TRUE;
}
}
InitialUpdateFrame(pFrame; pDocument; bMakeVisible);
return pDocument;
}
下页
517
…………………………………………………………Page 580……………………………………………………………
第篇 深入 MFC 程式設計
BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
{
CFileException fe;
CFile* pFile = GetFile(lpszPathName;
CFile::modeRead|CFile::shareDenyWrite; &fe);
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(); 由于 Serialize
CScribbleDoc 改写了
ReleaseFile(pFile; FALSE); 所以调用的是CScribbleDoc::Serialize
}
。。。 void CScribbleDoc::Serialize(CArchive& ar)
} void CScribbleDoc::Serialize(CArchive& ar)
{
{
。。。
。。。
m_strokeList。Serialize (ar);
m_strokeList。Serialize (ar);
}
}
void CObList::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if (ar。IsStoring())
{
。。。
}
else 本例读入 0004
{
DWORD nNewCount = ar。ReadCount();
CObject* newData;
while (nNewCount……)
{
for
ar 》》 newData;
loop
AddTail(newData); operator》》 被多载( overloading )化
}
}
_AFX_INLINE CArchive& AFXAPI operator》》 (CArchive& ar;
}
CObject*& pOb)
{ pOb = ar。ReadObject (NULL); return ar; }
调用 CArchive::ReadObject
下页
518
…………………………………………………………Page 581……………………………………………………………
第8章 Document…View 深入探討
CObject* CArchive::ReadObject(const CRuntimeCl
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!