Before I tell you how to change the default behaviour, lets understand how MFC displays the file open and file save dialogs.
When you select the menu File Open, the command message is routed to CWinApp::OnFileOpen, which calls CDocManager::OnFileOpen through its member m_pDocManager (a pointer to a CDocManager object). This last function calls the CDocManager virtual member DoPromptFileName, and on success calls CWinApp::OpenDocumentFile, with the selected document path. The file open dialog is displayed in the DoPromptFileName virtual function.
When saving, the File Save (or Save As) command message is routed to the CDocument::OnFileSave (or CDocument::OnFileSaveAs). In boths cases the CDocument::DoSave function gets called, either with a file name (we are saving an opened document) or NULL parameter (new document or saving as). At last, if the file name is NULL, CDocument::DoSave calls CWinApp::DoPromptFileName, that validates the m_pDocManager member and calls CDocManager::DoPromptFileName to display the Save As dialog.
As we see, the CDocManager::DoPromptFileName function (which is virtual!) is responsible for displaying the standard open and save dialogs (a boolean parameter decides which one).
It seems trivial now, that to change default behaviour, you have to override the DoPromptFileName function in the CDocManager class, and somehow tell the application class to use your own modified CDocManager, instead of the original class. Below is the code for a custom CDocManager that displays a dialog descending from CFileDialog:
// CDocManager class declaration
//
class CDocManagerEx : public CDocManager
{
DECLARE_DYNAMIC(CDocManagerEx)
// Construction
public:
CDocManagerEx();
// Attributes
public:
// Operations
public:
// Overrides
// helper for standard commdlg dialogs
virtual BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle,
DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
// Implementation
public:
virtual ~CDocManagerEx();
};
// DocManager.cpp : implementation file
//
#include “stdafx.h”
#include “PreviewFileDlg.h”
#include “DocManager.h” // the header with the class declaration
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static void AppendFilterSuffix(CString& filter, OPENFILENAME& ofn,
CDocTemplate* pTemplate, CString* pstrDefaultExt)
{
ASSERT_VALID(pTemplate);
ASSERT_KINDOF(CDocTemplate, pTemplate);
CString strFilterExt, strFilterName;
if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) &&
!strFilterExt.IsEmpty() &&
pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) &&
!strFilterName.IsEmpty())
{
// a file based document template – add to filter list
#ifndef _MAC
ASSERT(strFilterExt[0] == ‘.’);
#endif
if (pstrDefaultExt != NULL)
{
// set the default extension
#ifndef _MAC
*pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1; // skip the ‘.’
#else
*pstrDefaultExt = strFilterExt;
#endif
ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt);
ofn.nFilterIndex = ofn.nMaxCustFilter + 1; // 1 based number
}
// add to filter
filter += strFilterName;
ASSERT(!filter.IsEmpty()); // must have a file type name
filter += (TCHAR)’