友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
深入浅出MFC第2版(PDF格式)-第69部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
之对象实体)的文件动作时,有许多幕后的、不易观察到的机制。让我们从使用者按下
【Save As】菜单项目开始,追踪程序的进行。
508
…………………………………………………………Page 571……………………………………………………………
第8章 Document…View 深入探討
遍寻Scribble 程序,并没有发现曾经在哪里拦截过【Save As】
命令消息,那么必是某个「CCmdTarget 衍生类别」曾经在其
Message Map 中设定过对此消息之处理函数。我猜想
CDocument 最有这个可能:
BEGIN_MESSAGE_MAP(CDocument; CCmdTarget)
BEGIN_MESSAGE_MAP(CDocument; CCmdTarget)
//{{AFX_MSG_MAP(CDocument)
//{{AFX_MSG_MAP(CDocument)
ON_MAND(ID_FILE_CLOSE; OnFileClose)
ON_MAND(ID_FILE_CLOSE; OnFileClose)
ON_MAND(ID_FILE_SAVE; OnFileSave)
ON_MAND(ID_FILE_SAVE; OnFileSave)
ON_MAND(ID_FILE_SAVE_AS; OnFileSaveAs)
ON_MAND(ID_FILE_SAVE_AS; OnFileSaveAs)
//}}AFX_MSG_MAP
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
END_MESSAGE_MAP()
宾果!于是【Save As】引发CDocument::OnFileSaveAs 被调用。
void CDocument::OnFileSaveAs()
void CDocument::OnFileSaveAs()
{
{
if (!DoSave (NULL))
if (!DoSave (NULL))
TRACE0(〃Warning: File save…as failed。n〃);
TRACE0(〃Warning: File save…as failed。n〃);
}
}
BOOL CDocument::DoSave(LPCTSTR lpszPathName; BOOL bReplace)
{
CString newName = lpszPathName;
if (newName。IsEmpty())
{
CDocTemplate* pTemplate = GetDocTemplate();
newName = m_strPathName;
。。。
if (!AfxGetApp()…》DoPromptFileName (newName;
bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY;
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; FALSE; pTemplate))
return FALSE; // don't even attempt to save
}
CWaitCursor wait;
if (!OnSaveDocument (newName))
{ 。。。 }
下页
。。。
}
509
…………………………………………………………Page 572……………………………………………………………
第篇 深入 MFC 程式設計
BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)
{
CFileException fe;
CFile* pFile = NULL;
pFile = GetFile(lpszPathName; CFile::modeCreate |
CFile::modeReadWrite | CFile::shareExclusive; &fe);
CArchive saveArchive(pFile; CArchive::store |
CArchive::bNoFlushOnDelete);
saveArchive。m_pDocument = this;
虽然看起来像是调用CDocument::Serialize;但事实上
saveArchive。m_bForceFlat = FALSE;
因为Serialize是虚拟函数;而CScribbleDoc 已改写
TRY
它,而且目前的this指针是指向CScribbleDoc对象
{
CWaitCursor wait; (别忘了整个追踪路线的起源是Scribble Docment
我会在下一章消息绕行这一主题中解释更详尽一些),
Serialize(saveArchive);
saveArchive。Close(); 所以这里调用的是CScribbleDoc::Serialize函数;哈
ReleaseFile(pFile; FALSE); ,这就是虚拟函数的妙用!
}
。。。
} void CScribbleDoc::Serialize(CArchive& ar)
void CScribbleDoc::Serialize(CArchive& ar)
{
{
。。。
。。。
m_strokeList。Serialize(ar);
m_strokeList。Serialize(ar);
}
}
m_strokeList 是个CObList对象
void CObList::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if (ar。IsStoring())
本例之CObList 对象内有4个元素,所以输出资料0004
{
ar。WriteCount(m_nCount);
for (CNode* pNode = m_pNodeHead;
pNode != NULL; pNode = pNode…》pNext)
for
{
loop CArchive 已针对
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!