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

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

圖1 CFileDialog類的派生層次
從上圖中,可以看出這個類也是對話框的類,顯示對話框可以使用DoModal函數來完成;
要使用CFileDialog,需要先用CFileDialog構造函數構造一個對象,其構造函數如下:
CFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWord dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );參數:bOpenFileDialg
如果為TRUE, 則創建文件打開對話框;如果為FALSE,則構造一個File Save As(另存為)對話框。 lpszDefExt
缺省文件擴展名,如果用戶在文件名編輯框中不包含擴展名,則lpszDefExt定義的擴展名自動加到文件名后。如果為NULL,則不添加擴展名。 lpszFileName
初始顯示于文件名編輯框中的文件名,如果為NULL,則不顯示初始文件名。 dwFlags
一個或多個標志的組合,使你可定制對話框。如果你改變m_ofn.Flags結構成員,在改變中用OR操作保持缺省行為完整。 lpszFilter
一列字符串對,指定可以應用到文件的過濾器。如果指定過濾器,僅被選擇的文件顯示于文件列表框中。pParentWnd
指向文件對話框對象的父窗口或擁有者窗口。
其中lpszFilter是個很重要的一個參數,想要完成文件過濾顯示功能,需要對這個參數進行賦值;
其格式說明如下:
雙字符串的第一個字符串描述過濾器,第二個串表明使用的文件擴展名,多重擴展可用“;”來指定。字符串由兩個“|”字符結尾;
如果lpszFilter不是以默認構造形式賦值,而是通過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";如果想對對話框作更多定制,我們可通過成員數據m_ofn對對話框進行更多賦值,該參數是Windows OPENFILENAME結構,更多信息參加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; //默認文件擴展名 ...} OPENFILENAME, *LPOPENFILENAME;實例
我們在CFile文件操作示例博文基礎上修改其中的OnWriteFile和OnReadFile函數,可以完成對話框的保持和打開功能,具體代碼如下:
OnReadFile函數實現:
/*****************************************************************函數名稱: 打開對話框*功 能:*作 者: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; //構造文件,同時增加異常處理 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); } //創建指定大小的Buffer DWORD dwFileLenth = (DWORD)File.GetLength(); //初始化buffer, 增加一個/0空間 char *pBuf = new char[dwFileLenth + 1]; memset(pBuf, 0, dwFileLenth + 1); if (pBuf != NULL) { //讀取文件內容 File.Read(pBuf,dwFileLenth); File.Close(); //顯示文件內容 MessageBox(pBuf); //刪除bufer,避免內存泄漏 delete[] pBuf; pBuf = NULL; } }}OnWriteFile函數實現:
/*****************************************************************函數名稱:保存對話框*功 能:*作 者:Jin*日 期:2017年2月5日****************************************************************/void CFileView::OnWriteFile(){ //格式:過濾器描述符(顯示作用)+ /0 + 文件擴展名稱(過濾作用) //多個擴展名稱之間用(;)分隔,兩個過濾字符串之間以/0分隔 //最后的過濾器需要以兩個/0/0結尾 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 FileDlg(FALSE, "txt", _T("Test")); FileDlg.m_ofn.lpstrTitle = "Save File"; FileDlg.m_ofn.lpstrFilter = szFilters; //通過以下兩個參數修改對話框初始狀態,程序奔潰,使用默認構造形式正常 //環境:VS2008編譯器+Wind7系統 //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!"}; //寫入文件內容,不包含/0 File.Write(szBufData, strlen(szBufData)); //立即寫入,不緩沖 File.Flush(); //文件操作結束關閉 File.Close(); }}保存文件:
打開文件:
成員函數
CFileDialog類的成員數據成員
| m_ofn | Windows OPENFILENAME結構,提供對基本文件對話框參數的訪問 |
| CFileDialog | 構造一個CFileDialog對象操作 |
| DoModal | 顯示對話框并使用戶可以進行選擇 |
| GetPathName | 返回選定文件的完整路徑 |
| GetFileName | 返回選定文件的文件名 |
| GetFileExt | 返回選定文件的擴展文件名 |
| GetFileTitle | 返回選定文件的標題 |
| GetNextPathName | 返回下一個選定文件的完整路徑 |
| GetReadOnlyPref | 返回選定文件的只讀狀態 |
| GetStartPosition | 返回文件名列表的第一個元素位置 |
| OnShareViolation | 發生共享沖突時調用 |
| OnFileNameOK | 確認鍵入對話框中的文件名 |
| OnLBSelChangedNotify | 當列表框選擇改變時調用 |
| OnInitDone | 處理WM_NOTIFY CDN_INITDONE消息 |
| OnFileNameChange | 處理WM_NOTIFY CDN_SELCHANGE消息 |
| OnFolderChange | 處理WM_NOTIFY CDN_FOLDERCHANGE消息 |
| OnTypeChange | 處理WM_NOTIFY CDN_TYPECHANGE消息 |
新聞熱點
疑難解答