在大多數(shù)軟件中,都有“打開”和“保存”這兩個功能,以“記事本為打開功能”為例,其打開對話畫框的界面如下:

其保存對畫框,與打開對話框界面基本一樣,下面也給程序增加這樣的對話框,我們可以使用MFC提供的CFileDialog類來完成;
CFileDialog類封裝了Windows常用的文件對話框。常用的文件對話框提供了一種簡單的與Windows標(biāo)準(zhǔn)相一致的文件打開和文件存盤對話框功能,該類的派生層次如下:

圖1 CFileDialog類的派生層次
從上圖中,可以看出這個類也是對話框的類,顯示對話框可以使用DoModal函數(shù)來完成;
要使用CFileDialog,需要先用CFileDialog構(gòu)造函數(shù)構(gòu)造一個對象,其構(gòu)造函數(shù)如下:
CFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWord dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );參數(shù):bOpenFileDialg
如果為TRUE, 則創(chuàng)建文件打開對話框;如果為FALSE,則構(gòu)造一個File Save As(另存為)對話框。 lpszDefExt
缺省文件擴(kuò)展名,如果用戶在文件名編輯框中不包含擴(kuò)展名,則lpszDefExt定義的擴(kuò)展名自動加到文件名后。如果為NULL,則不添加擴(kuò)展名。 lpszFileName
初始顯示于文件名編輯框中的文件名,如果為NULL,則不顯示初始文件名。 dwFlags
一個或多個標(biāo)志的組合,使你可定制對話框。如果你改變m_ofn.Flags結(jié)構(gòu)成員,在改變中用OR操作保持缺省行為完整。 lpszFilter
一列字符串對,指定可以應(yīng)用到文件的過濾器。如果指定過濾器,僅被選擇的文件顯示于文件列表框中。pParentWnd
指向文件對話框?qū)ο蟮母复翱诨驌碛姓叽翱凇?
其中l(wèi)pszFilter是個很重要的一個參數(shù),想要完成文件過濾顯示功能,需要對這個參數(shù)進(jìn)行賦值;
其格式說明如下:
雙字符串的第一個字符串描述過濾器,第二個串表明使用的文件擴(kuò)展名,多重擴(kuò)展可用“;”來指定。字符串由兩個“|”字符結(jié)尾;
如果lpszFilter不是以默認(rèn)構(gòu)造形式賦值,而是通過m_ofn.lpszFilter形式賦值,我們需要將過濾器字符串中的“|”替換成”/0“;
形如:
char szFilter[] ="Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||";TCHAR szFilters[] = "C++ source file(*.h;*,hpp;*.cpp)/0*.h;*.hpp;*.cpp/0"/ "Text File(*.txt)/0*.txt/0"/ "All Typle(*.*)/0*.*/0" / "Lua source file(*.lua)/0*.lua/0"/ "/0";如果想對對話框作更多定制,我們可通過成員數(shù)據(jù)m_ofn對對話框進(jìn)行更多賦值,該參數(shù)是Windows OPENFILENAME結(jié)構(gòu),更多信息參加msdn介紹:
typedef struct tagOFN { DWORD lStructSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpstrFilter; //過濾器字符串 LPTSTR lpstrCustomFilter; DWORD nMaxCustFilter; DWORD nFilterIndex; LPTSTR lpstrFile; //文件名字 DWORD nMaxFile; LPTSTR lpstrFileTitle; DWORD nMaxFileTitle; LPCTSTR lpstrInitialDir; LPCTSTR lpstrTitle; //文件對話框名字 DWORD Flags; WORD nFileOffset; WORD nFileExtension; LPCTSTR lpstrDefExt; //默認(rèn)文件擴(kuò)展名 ...} OPENFILENAME, *LPOPENFILENAME;實例
我們在CFile文件操作示例博文基礎(chǔ)上修改其中的OnWriteFile和OnReadFile函數(shù),可以完成對話框的保持和打開功能,具體代碼如下:
OnReadFile函數(shù)實現(xiàn):
/*****************************************************************函數(shù)名稱: 打開對話框*功 能:*作 者:Jin*日 期:2017年2月5日****************************************************************/void CFileView::OnReadFile(){ // TODO: 在此添加命令處理程序代碼 char szFilters[] = "C++ source file(*.h;*,hpp;*.cpp)/0*.h;*.hpp;*.cpp/0"/ "Text File(*.txt)/0*.txt/0"/ "All Typle(*.*)/0*.*/0" / "Lua source file(*.lua)/0*.lua/0"/ "/0"; CFileDialog OpenDlg(TRUE); OpenDlg.m_ofn.lpstrTitle = "Open File"; OpenDlg.m_ofn.lpstrFilter = szFilters; if (IDOK == OpenDlg.DoModal()) { CFile File; CFileException e; //構(gòu)造文件,同時增加異常處理 if(!File.Open(OpenDlg.GetPathName(), CFile::modeRead,&e)) { CString strErr; strErr.Format(_T("File could not be opened %d/n"), e.m_cause); MessageBox(strErr); } //創(chuàng)建指定大小的Buffer DWORD dwFileLenth = (DWORD)File.GetLength(); //初始化buffer, 增加一個/0空間 char *pBuf = new char[dwFileLenth + 1]; memset(pBuf, 0, dwFileLenth + 1); if (pBuf != NULL) { //讀取文件內(nèi)容 File.Read(pBuf,dwFileLenth); File.Close(); //顯示文件內(nèi)容 MessageBox(pBuf); //刪除bufer,避免內(nèi)存泄漏 delete[] pBuf; pBuf = NULL; } }}OnWriteFile函數(shù)實現(xiàn):
/*****************************************************************函數(shù)名稱:保存對話框*功 能:*作 者:Jin*日 期:2017年2月5日****************************************************************/void CFileView::OnWriteFile(){ //格式:過濾器描述符(顯示作用)+ /0 + 文件擴(kuò)展名稱(過濾作用) //多個擴(kuò)展名稱之間用(;)分隔,兩個過濾字符串之間以/0分隔 //最后的過濾器需要以兩個/0/0結(jié)尾 char szFilters[] = "C++ source file(*.h;*,hpp;*.cpp)/0*.h;*.hpp;*.cpp/0"/ "Text File(*.txt)/0*.txt/0"/ "All Typle(*.*)/0*.*/0" / "Lua source file(*.lua)/0*.lua/0"/ "/0"; //當(dāng)過濾器或者默認(rèn)構(gòu)造參數(shù)賦值較少情況下, //使用構(gòu)造函數(shù)修改對話框初始狀態(tài)可能更好,這過濾器較多 CFileDialog FileDlg(FALSE, "txt", _T("Test")); FileDlg.m_ofn.lpstrTitle = "Save File"; FileDlg.m_ofn.lpstrFilter = szFilters; //通過以下兩個參數(shù)修改對話框初始狀態(tài),程序奔潰,使用默認(rèn)構(gòu)造形式正常 //環(huán)境:VS2008編譯器+Wind7系統(tǒng) //FileDlg.m_ofn.lpstrDefExt = "txt"; //FileDlg.m_ofn.lpstrFile = "test"; if (IDOK == FileDlg.DoModal()) { CFile File(FileDlg.GetPathName(),CFile::modeCreate|CFile::modeReadWrite); char szBufData[100] = {"hello word!"}; //寫入文件內(nèi)容,不包含/0 File.Write(szBufData, strlen(szBufData)); //立即寫入,不緩沖 File.Flush(); //文件操作結(jié)束關(guān)閉 File.Close(); }}保存文件:
打開文件:
成員函數(shù)
CFileDialog類的成員數(shù)據(jù)成員
| m_ofn | Windows OPENFILENAME結(jié)構(gòu),提供對基本文件對話框參數(shù)的訪問 |
| CFileDialog | 構(gòu)造一個CFileDialog對象操作 |
| DoModal | 顯示對話框并使用戶可以進(jìn)行選擇 |
| GetPathName | 返回選定文件的完整路徑 |
| GetFileName | 返回選定文件的文件名 |
| GetFileExt | 返回選定文件的擴(kuò)展文件名 |
| GetFileTitle | 返回選定文件的標(biāo)題 |
| GetNextPathName | 返回下一個選定文件的完整路徑 |
| GetReadOnlyPref | 返回選定文件的只讀狀態(tài) |
| GetStartPosition | 返回文件名列表的第一個元素位置 |
| OnShareViolation | 發(fā)生共享沖突時調(diào)用 |
| OnFileNameOK | 確認(rèn)鍵入對話框中的文件名 |
| OnLBSelChangedNotify | 當(dāng)列表框選擇改變時調(diào)用 |
| OnInitDone | 處理WM_NOTIFY CDN_INITDONE消息 |
| OnFileNameChange | 處理WM_NOTIFY CDN_SELCHANGE消息 |
| OnFolderChange | 處理WM_NOTIFY CDN_FOLDERCHANGE消息 |
| OnTypeChange | 處理WM_NOTIFY CDN_TYPECHANGE消息 |
新聞熱點
疑難解答