亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 13.3.2 mfc框架對serialize函數的調用過程.txt

?? 網上第一本以TXT格式的VC++深入詳解孫鑫的書.全文全以TXT格式,并每一章節都分了目錄,清晰易讀
?? TXT
字號:
13.3.2 MFC框架對Serialize函數的調用過程
另外,在Graphic程序運行后,當單擊【文件_保存】和【文件_打開】菜單項時都會出現一個對話
框。但是在CGraphicDoc類中并沒有看到相應的菜單命令響應函數,因此我們可以推斷這些命令響應
函數一定也是在MFC框架內部實現的。我們可以跟蹤【文件_打開】命令的消息響應函數,同時查看
MFC框架對CGraphicDoc類的Serialize函數的調用過程。
同樣,在Microsoft提供的MFC源文件: APPDLG.CPP中,可以看到OnFileOpen也是CWinApp的一個成員
函數。井且按照上面查看CWinApp類的OnFileNew函數定義的方法一樣,可以發現這個OnFileOpen函
數的聲明前面有 afx_msg標識符,說明這個函數確實是菜單命令消息響應函數。該函數的實現代碼
如例 13-13所示。 
例 13-13 

void CWinApp: :OnFileOpen() 
{ 
ASSERT(m_pDocManager != NULL); 
m_pDocManager->OnFileOpen(); 
可以看到, CWinApp類的 OnFileOpen函數接著調用了文檔管理器的 OnFileOpen函數,該函數的定
義位于 MFC源文件: DOCMGR. CPP文件中,定義代碼如例 13-14所示。 
例3-14 
void CDocManager: :OnFileOpen() . 
// prompt the user (with all document templates) 
CString newName ; 
if (!DoPromptFileName(newName, AFX_IDS_OPENFILE, OFN_HIDEREADONLY OFN_FILEMUSTEXIST, TRUE , NULL)) 
return ; 
// open cancelled 
AfxGetApp()->OpenDocumentFile(newName) ; 
// if returns NULL , the user has already been 
alerted 
可以看到,在 CDocManager類的 OnFileOpen函數中調用了一個函數: DoPrompt FileName,從其函
數名大概可以猜到這是一個顯示"文件打開/保存"對話框的函數(讀者先在此函數調用處設置一個斷
點)。該函數的實現代碼如例 13-15所示。
例 13-15 

BOOL CDocManager : : DoPromptFileName (CString& fileName , UINT nIDSTitle, DWORD lFlags , 
BOOL bOpenFileDialog, CDocTemplate* pTemplate) { CFileDialog dlgFile(bOpenFileDialog); 
CString title; 
VERIFY(title . LoadString(nIDSTitle)) ; 

dlgFile.m_ofn.Flags 1= lFlags ; 
CString strFilter; 
CString strDefault; 
if (pTemplate != NULL) 
{ 
ASSERT_ VALID(pTemplate) ; 
_AfxAppendFilterSuffix(strFilter, dlgFile . m一ofn, pTemplate , &str Default) ; 
else 
11 do for all doc template 
POSITION pos = m_templateList.GetHeadPosition(); 
BOOL bFirst = TRUE ; 
while (pos != NULL) 
{ CDocTemplate* pTemplate = (CDocTemplate*) m_templateList. GetNext 
500 I如...... 


(pos) ; _Af xAppendFilterSuffix(strF工 lter, dlgFile.m_ofn, pTemplate, bFirst ? 
&strDefault : NULL); bFirst = FALSE; 
. 
1/ append the "*.*" all files filter 
CString allFilter; 

VER工 FY(allFilter.LoadString(AFX_IDS_ALLFILTER)); 
strFilter += al工 Filter; 
strFilter += (TCHAR)'\0'; // next string please 
strFilter += _T("*.*"); 
strFilter += (TCHAR) , \0' ; / / last str工ng 
dlgFile.m_ofn.nMaxCustFilter++; 

dlgFile.m一ofn.lpstrFilter = strFilter; dlgFile.m_ofn.lpstrTitle = title; 
dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH); 
int nResult = dlgFile.DoModal(); 
fileName.ReleaseBuffer(); 
return nResult工 DOK;

可以看到,在 CDocManager類的 DoPromptFileName函數中構造了一個 CFileDialog對象: dlgFile.
由此我們可以知道原來 MFC框架也是利用 CFileDialog這個類來顯示"文件打開"對話框的。
讓我們回到上述如例 13-14所示 CDocManager類的 OnFileOpen函數,可以看到,接下來,該函數調
用 AfxGetApp函數獲得應用程序 (CWinApp)類對象指針,并利用此指針調用 CWinApp對象的
OpenDocumentFile函數。我們在此行代碼處也設置一個斷點。而 CWinApp類的 OpenDocumentFile
定義位于 AppUl.cpp文件中,代碼如例 13-16所示。
例 13-16 

CDocument* CWinApp: :OpenDocumentFile(LPCTSTR lpszFileName) 
{ 
ASSERT(m-pDocManager != NULL); 
return m-pDocManager->OpenDocumentFile(lpszFileName); 
可以看到. CWinApp類的 OpenDocumentFile函數實際上就是去調用 CDocManager類的 
OpenDocumentFile函數。后者位于 DOCMGR.CPP文件中,代碼如例 13-17所示。 

CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName) { 
11 find the highest confidence 
POSITION pos = m_templateList . GetHeadPos工 tion() ; 
CDocTemplate ::Confidence bestMatch = CDocTemplate : : noAttempt ; 
CDocTemplate* pBestTemplate = NULL ; 

( CDocument* pOpenDocument =陽LL ; 
TCHAR szPath[_MAX_ PATH] ; 
ASSERT(lstrlen(lpszFileName) < _countof(szPath)) ; 
TCHAR szTernp[_MAX_ PATH] ; 
if (lpszFileNarne[O] , \ 11 

I ) 
++lpszFileName ; 
lstrcpyn(szTemp , lpszFileNarne, _MAX_PATH) ; 
LPTSTR lpszLast = _tcsrchr(szTemp , \ " , ) ; 
if (lpszLast ! = NULL) 

*lpszLast = 0 ; AfxFullPath (szPath , szTemp) ; TCHAR szLinkName[_MAX_PATH] ; if 
(AfxResolveShortcut(AfxGetMainWnd() , szPath, szL工nkNarne, MAX 
PATH) ) lstrcpy(szPath, szLinkName) ; 
while (pos ! = NULL) 
CDocTemplate* pTemplate = (CDocTemplate*)m_ternplateList .GetNext (pos) ; 
ASSERT_KINDOF(CDocTernplate , pTemplate) ; 
CDocTemplate : : Confidence match; 
ASSERT( p OpenDocument NULL) ; 
( rnatch = pTernpl ate->MatchDocType (szPath, pOpenDocument); 
if (match > bestMatch) 

bestMatch = match; 
pBestTernplate = pTernplate ; 

} 
if (match CDocTemplate : : yesAlreadyOpen) break; /1 stop here 
if (pOpenDocument != NULL) 
{ POSITION pos = pOpenDocument->GetFirstViewPosition() ; if (pos ! = NULL) 
{ 
CView* pView =pOpenDocument->GetNextView(pos) ; 11 get first one 
ASSERT_ VALID(pView) ; 
CFrarneWnd* pFrarne = pView->GetParentFrarne() ; 
if (pFrarne != NULL) 
pFrame->ActivateFrame() ; else TRACEO ("Error: Can not find a frame for document to 
activate. 
\n" ) ; 
CFrameWnd* pAppFrame; 
if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()-> m-pMainWnd)) 
{ 

ASSERT_ KINDOF(CFrameWnd, pAppFrame); pAppFrame->ActivateFrame() ; 
} 
else 

TRACEO ( "Error : Can not f工 nda飛riew for document to acti vate . \n ;
u ) 
( return pOpenDocument; 
if (pBestTemplate NULL) 
{ 

AfxMessageBox(AFX_IDP_FA ILED_T。一 OPEN_DOC) ; return NULL; 
@D return pBestTemplate->OpenDocumentFile(szPath); 
讀者先在 CDocManager類的 OpenDocumentFile函數開始處設置一個斷點。然后閱讀此函數的實現代
碼,可以看到,在此函數中定義了一個 CDocument類型的指針變量: pOpenDocument (.位置處的代
碼),并在后面有一個函數調用: MatchDocType (.位置處的代碼),該函數將 pOpenDocument指針變
量作為參數傳遞進去了。我們在此行代碼設置一個斷點。在該代碼的最后利用文檔模板的指針調用 
OpenDocumentFile (.位置處的代碼)。因為本程序是一個單文檔類型的程序,所以這里實際上調用
的是單文檔模板類 ( CSingleDocTemplate )的 OpenDocumentFile函數。該函數的代碼可參見本章
前面的內容,可以看到在該函數中,對 IpszPathName變量進行判斷的 else子句塊下面調用了文檔
對象的 OnOpenDocument函數(上面 CSingleDocTemplate類 OpenDocumentFile函數的 .位置處的代
碼)。這個函數的定義位于 DocCore.cpp文件中,代碼如例 13-18所示。
例 13-18 

BOOL CDocument: :OnOpenDocument(LPCTSTR lpszPathName) 

if (IsModified()) TRACEO ( "Warning : OnOpenDocument replaces an unsaved document . \ n 
11 ) i 
CFileException fe ; ( CFile* pFile = GetFile(lpszPathName , 

" ‘ I 503 
第13 
CFile::rnodeReadICFile::shareDenyWrite, &fe); 
if (pFile NULL) 
{ 

ReportSaveLoadExcept工O且(lpszPathNarne, &fe , FALSE , AFX_IDP_FAILED_TO一OPEN_DOC) ; 
return FALSE; 
DeleteContents() ; 
SetModifiedFlag(); // dirty during de-serialize 

( CArchive loadArchive(pFile , CArchive ::load 	CArchive::bNoFlushOn 
Delete) ; loadArchive.rn-pDocurnent = this; loadArchive . rn_bForceFlat = FALSE; TRY { 
CWaitCursor wait; 
if (pFile->GetLength() != 0) 

③ 	Serialize(loadArchive); // load rne 
loadArchive . Close(); 
ReleaseFile(pFile , FALSE); 

} 
CATCH_ALL(e) 
{ 

ReleaseF工le (pFile , TRUE); 
DeleteContents() ; // rernove fa工led contents 

TRY 

ReportSaveLoadException(lpszPathNarne , e , 
FALSE , AFX_IDP_FAILED_TO_OPEN_DOC); } END TRY DELETE_EXCEPTION(e) ; return FALSE; 
END CATCH ALL 
SetModifiedFlag(FALSE); 	// start off with unrnod工fied
return TRUE; 
這時己經進入到文檔基類 (CDocument)中了。在CDocument類的OnOpenDocument函數中,根據得到的
文件名,構造一個 CFile對象 ce位置處的代碼),然后利用此對象指針構造一個CArchive對象c(.
位置處的代碼),隨后有一個Serialize函數的調用 ce位
置處的代碼〉。可以在此調用處設置一個斷點。
調試運行 Graphic程序,當程序界面出現后,選擇【文件飛打開】菜單項,程序進入 CWinApp類的
OnFileOpen函數,該函數將調用CDocManager類的OnFi1eOpen函數。繼續運行,程序進入CDocManager
類的DoPromptFileName函數,該函數的作用就是彈出一個文件打開(或保存)對話框。繼續運行,程
序就會彈出一個文件打開對話框,從中選擇一個文件,例如 Graphic.txt文件并打開。然后程序調
用 CWinApp類的 OpenDocmentFile函數。繼續運行,程序回到CDocManager類的OpenDocmentFile函
數。繼續運行,程序進入 CSingleD∞Template類的OpenDocumentFile函數。在此函數中,調用文檔
對象的 OnOpenDocument函數。因此,程序進入到CDocument類的OnOpenDocument函數,在該函數中,
首先構造CFile對象,接著構造CArchive對象,之后調用Serialize函數,這是一個虛函數,根據多
態性原則,它調用就是子類: CGraphicDoc類的Serialize函數。繼續運行,就可以看到程序進入了
CGraphicDoc類的Serialize函數。因為此時是從文件加載數據,所以進入該函數中的else分支。繼
續運行程序,即可從彈出的消息框中看到讀取的數據。上述過程如圖 13.14所示。

文件打開菜單命令 
圖 13.14 文件打開菜單命令響應過程 

剛才我們看到一個現象,就是當保存數據后,在不關閉程序窗口的情況下,再次打開同一個文件時,
程序并不會進入Serialize函數中。讀者可以再次調試運行Graphic程序,
先單擊【文件_保存】菜單項,并選擇一個文件,例如Graphic.txt文件保存數據。然后單擊【文件
_打開】菜單項,這時程序會依次進入CWinApp類的OnFileOpen函數、 CDocManager類的OnFileOpen
函數,通過DoPrompFileName函數調用顯示文件打開對話框。選擇我們剛才所保存的文件: 
Graphic.txt,程序進入到 CWinApp類的 OpenDocumentFile函數,然后是CDocManager類的
OpenDocumentFile函數。讀者要注意了,這里非常關鍵!在此函數中,我們單步運行程序,一直運行
到MatchDocType函數調用處。當執行完這個函數調用后,可以發現pOpenDocument這個指針有值了,
也就是說,程序發現這個文件己經與先前的一個文檔對象相關聯了,即獲得了先前的文檔對象指針: 
CGraphicDoc類型的指針(如圖 13.15所示)。因為此時 pOpenDocument指針不為空了,那么 
CDocManager類的 OpenDocumentFile函數將直接返回 pOpenDocument這個文檔類指針(如例 13-17
所示 CDocManager類 OpenDocumentFile函數實現代碼中@位置處的代碼).這個函數的執行就結束
了,它并沒有調用 CSingleDocTemplate類的 OpenDocumentFile函數,也就沒有調用CDocument函數
中的Serialize函數,當然其子類: CGraphicDoc中的Serialize函數也就沒有被調用。這就是上面在
保存數據之后再次打開同一個文件時,看不到讀取的數據消息框的原因。 
圖 13.15 pOpenDocument指針已經指向CGraphicDoc類的對象

讀者可以試驗一下,如果在保存數據之后,再打開另一個文件,這時程序就會彈出消息框,顯示讀
取到的數據,說明這時調用了CGraphicDoc類的Serialize函數。這就說明文檔對象與文件是相關聯
的。一旦換了另一個文件,文檔對象會將它的數據清空,然后將新文件中的數據與這個對象相關聯。
注意在這個過程中,文檔對象是同一個文檔對象。因為對單文檔類型的程序來說,每次只能寫一份
文檔,因此從效率上考慮,沒有必要構造多個文檔對象。但是對多文檔程序來說,每打開一個文件
都會構造一個新的文檔對象。一定要注意,對單文檔來說,文檔對象本身并不會銷毀,它只是將數
據清空,然后再與一個新的
文件相關聯。
上面的調試過程比較復雜,讀者只要記住.(文件保存和【文件打開】萊單項的命令響應畫數都是在
CWinApp類中提供的。CWinApp類有一個成員變量:m_pDocManager. 是指向CDocManager對象的指針,
也就是說, CWinApp負責管理文檔管理器,而后者有 
: m_templateList. 
里文檔模板,而后者又是用來管理文檔類、框架類和視類的,始終讓這三個對象三位一體,一起為
文檔服務。所以在上述調試過程中,我們可以看到都是由 CWinApp對象轉到 CDocManager對象,再
轉到CSingleDocTemplate對象,如果牽扯到CDocument對象,就轉到文檔對象的函數中。讀者只要掌
握了這一線索,不管函數調用如何跳來跳去,都會很清楚地知道它們之間的調用邏輯。 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产91精品一区二区麻豆亚洲| 丝袜a∨在线一区二区三区不卡| 国产一区二区三区免费在线观看| 91精品免费观看| 免费人成在线不卡| 精品日韩av一区二区| 国产一区91精品张津瑜| 中文字幕免费不卡| 99国产精品久久久久久久久久| 亚洲四区在线观看| 欧美精品在欧美一区二区少妇| 日本aⅴ精品一区二区三区 | 色综合网色综合| 亚洲免费三区一区二区| 欧美日韩高清不卡| 九九视频精品免费| 中文字幕亚洲视频| 欧美精品123区| 国产综合久久久久影院| 亚洲视频1区2区| 在线综合视频播放| 成人国产精品免费观看视频| 一区二区三区 在线观看视频| 69堂成人精品免费视频| 国产成人免费av在线| 亚洲国产欧美日韩另类综合| 欧美大片在线观看一区| 91网站最新地址| 久久99精品国产.久久久久| 成人免费在线播放视频| 91.麻豆视频| 国产精品亚洲а∨天堂免在线| 26uuu欧美| 视频在线在亚洲| 99riav久久精品riav| 久久精品在线观看| 久久99热国产| 日韩一区二区在线观看视频| 中文字幕免费观看一区| 狠狠狠色丁香婷婷综合激情| 欧美日韩免费观看一区二区三区 | 91丝袜国产在线播放| 成人免费看视频| 成人教育av在线| 久久亚洲综合色一区二区三区| 在线中文字幕不卡| 国产成人在线影院| 久久激五月天综合精品| 亚洲国产成人av网| 亚洲视频一二三| 国产日韩精品一区二区浪潮av| 91麻豆精品91久久久久同性| 91丝袜高跟美女视频| 国产 欧美在线| 国产一区二区精品在线观看| 日韩—二三区免费观看av| 亚洲免费观看高清完整版在线观看| 欧美精品一区二区三区在线播放| 欧美中文字幕一区二区三区亚洲| 成人免费视频视频在线观看免费| 狠狠色丁香婷综合久久| 免费成人你懂的| 日本大胆欧美人术艺术动态 | 亚洲一区二区视频在线观看| 国产精品私人自拍| 中文文精品字幕一区二区| 久久人人爽爽爽人久久久| 日韩无一区二区| 日韩三级中文字幕| 91精品久久久久久久91蜜桃| 欧美电影影音先锋| 欧美福利电影网| 91精品国产综合久久蜜臀| 91精品免费观看| 日韩欧美在线影院| 精品久久久久久无| 久久久777精品电影网影网 | 欧美aⅴ一区二区三区视频| 午夜日韩在线观看| 日本网站在线观看一区二区三区| 亚洲1区2区3区4区| 日本午夜一本久久久综合| 蜜桃精品在线观看| 国产揄拍国内精品对白| 国产成人午夜片在线观看高清观看| 国产在线精品视频| 成人午夜视频网站| 色视频成人在线观看免| 色琪琪一区二区三区亚洲区| 精品视频在线看| 欧美一区2区视频在线观看| 精品日韩在线观看| 中文字幕的久久| 亚洲精品成a人| 石原莉奈在线亚洲二区| 老司机免费视频一区二区三区| 国产一区二区三区免费播放 | 一本色道久久综合精品竹菊| 精品视频1区2区3区| 91精品国产免费| 亚洲精品一区二区三区四区高清 | 日韩欧美国产综合一区| 久久综合九色欧美综合狠狠| 日本一区二区在线不卡| 亚洲综合一区二区| 经典三级在线一区| 色综合久久综合网| 日韩视频一区二区三区在线播放| 久久久91精品国产一区二区三区| 一区视频在线播放| 免费美女久久99| heyzo一本久久综合| 欧美蜜桃一区二区三区| 久久久久久一二三区| 亚洲卡通动漫在线| 久久97超碰国产精品超碰| kk眼镜猥琐国模调教系列一区二区| 欧美日韩一区成人| 国产日韩欧美精品综合| 日本一区二区视频在线观看| 久久成人18免费观看| 欧美日韩一卡二卡| 国产精品婷婷午夜在线观看| 亚洲成人av中文| 色综合一个色综合亚洲| 欧美精品视频www在线观看 | 欧美一区二区三区免费| 亚洲精品一区二区三区福利| 午夜天堂影视香蕉久久| 国产精品久久久久久久岛一牛影视| 在线播放一区二区三区| 日本一区二区动态图| 日本v片在线高清不卡在线观看| 99久久精品国产观看| 精品福利一二区| 亚洲国产精品久久久久婷婷884| 丁香婷婷深情五月亚洲| 欧美一级在线免费| 亚洲第一福利一区| 91一区在线观看| 亚洲国产精品精华液ab| 看片的网站亚洲| 欧美色图第一页| 亚洲欧美在线视频| 成人一级视频在线观看| 精品999久久久| 日韩电影免费一区| 欧洲精品中文字幕| 亚洲日穴在线视频| 不卡区在线中文字幕| 久久精品亚洲国产奇米99| 美女一区二区视频| 欧美日韩高清在线| 午夜激情综合网| 欧美网站大全在线观看| 亚洲精品写真福利| 成人avav在线| 亚洲欧洲日韩在线| av在线不卡免费看| 国产精品久久久久婷婷二区次| 国产福利91精品| 国产视频一区在线观看| 国产剧情av麻豆香蕉精品| 久久女同互慰一区二区三区| 国产在线精品国自产拍免费| 欧美videos大乳护士334| 久久激情综合网| 欧美va在线播放| 国产一级精品在线| 久久精品视频一区二区三区| 中文字幕国产一区| 欧美伊人精品成人久久综合97| 国产成人精品免费在线| 一区二区三区精密机械公司| 日韩欧美成人一区| 欧美亚洲动漫精品| 色婷婷久久综合| 中文字幕 久热精品 视频在线| 国产一区二区三区在线观看免费视频| 911精品国产一区二区在线| 午夜欧美视频在线观看| 韩国一区二区三区| 国产成人av电影在线| 色婷婷综合久久| 麻豆精品一区二区三区| 亚洲啪啪综合av一区二区三区| 一区二区国产盗摄色噜噜| av成人免费在线观看| 欧美不卡一区二区三区四区| ●精品国产综合乱码久久久久| 中文字幕av不卡| 久久久久久亚洲综合影院红桃 | 日本一区二区三区dvd视频在线| 欧美熟乱第一页| 精品视频一区三区九区| 欧美日韩视频在线第一区| 欧美一级片免费看| 日韩欧美自拍偷拍| 欧美丰满嫩嫩电影| 国产精品成人免费精品自在线观看|