Introduction
This article addresses 2 issues:
- Removing *.* filter from the MFC Doc-View architecture Open/Save File dialogs.
- Displaying only selected filters in the MFC Doc-View architecture Open/Save File dialogs.
The MFC Doc-View architecture's "Open/Save File" functionality allows the user to open/save files of any type using the *.* filter. Now, if you don't want the user to do this, for e.g., I have created a MDI application using AppWizard and I have the following 2 document templates -
CDocTemplate *m_pTest1DocTemplate, m_pTest2DocTemplate
m_pTest1DocTemplate = new CMultiDocTemplate(IDR_TEST1TYPE,
RUNTIME_CLASS(CTest1Doc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CTest1View));
AddDocTemplate(m_pTest1DocTemplate);
m_pTest2DocTemplate = new CMultiDocTemplate(IDR_TEST2TYPE,
RUNTIME_CLASS(CTest2Doc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CTest2View));
AddDocTemplate(m_pTest2DocTemplate);
where -
IDR_TEST1TYPE = \nTest1\Test1 File\nTest1 Files(*.ts1)\n.ts1\nts1\nTest1\n
IDR_TEST2TYPE = \nTest2\Test2 File\nTest2 Files(*.ts2)\n.ts2\nts2\nTest2\n
You have created a new Test1 file and added data to it. Now you want to save the file and click on the Save button. The save file dialog comes up and you can give a name to the file and save it. The tricky part is that this allows the file to be saved in to any extension and WE DID NOT WANT THIS. So to remove the *.* filter in the file types combo box, I do the following -
- Derive a class
CMyDocManager
from CDocManager
.
- Provide an implementation of the virtual function
DoPromptFileName
which is defined in the CDocManager
base class.
BOOL CCGPDocManager::DoPromptFileName(CString& fileName,
UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog,
CDocTemplate* pTemplate)
{
CString cstrInitialDir = "";
if(pTemplate == g_theApp.m_pTest1DocTemplate)
{
cstrInitialDir = "c:\\Test\\Test1Files";
}
else if(pTemplate == g_theApp.m_pTest2DocTemplate)
{
cstrInitialDir = "c:\\Test\\Test2Files";
}
return CUtility::DoPromptFileName(cstrInitialDir,
fileName, nIDSTitle, lFlags, bOpenFileDialog, pTemplate);
}
- In the
InitApplication()
function of the Application class, add the following line -
m_pDocManager = new CCGPDocManager();
Now when the user tries to save a Test1 file, the user can only save it to a .ts1 extension.
To display only selected filters in the MFC Doc-View architecture Open File dialog
Implement the OnFileOpen
function in the CMainFrame
class:
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
void CMainFrame::OnFileOpen()
{
CString cstrFileName;
CDocTemplate *paDocTemplate[] = {g_theApp.m_pTest1DocTemplate,
g_theApp.m_pTest2DocTemplate,
NULL};
if(!CUtility::DoPromptFileName("", cstrFileName, AFX_IDS_OPENFILE,
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, TRUE,
paDocTemplate))
return;
OpenDocumentFile(cstrFileName);
}
Class CUtility
static BOOL DoPromptFileName(CString cstrInitialDir, CString& fileName,
UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate **pTemplate);
static BOOL DoPromptFileName(CString cstrInitialDir, CString& fileName,
UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
static void AppendFilterSuffix(CString& filter, OPENFILENAME& ofn,
CDocTemplate* pTemplate, CString* pstrDefaultExt);
BOOL CUtility::DoPromptFileName(CString cstrInitialDir, CString& fileName,
UINT nIDSTitle, DWORD lFlags,
BOOL bOpenFileDialog,
CDocTemplate* pTemplate)
{
CFileDialog dlgFile(bOpenFileDialog);
CString title;
VERIFY(title.LoadString(nIDSTitle));
dlgFile.m_ofn.Flags |= lFlags;
CString strFilter;
CString strDefault;
if(pTemplate != NULL)
{
ASSERT_VALID(pTemplate);
AppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);
}
dlgFile.m_ofn.lpstrFilter = strFilter;
#ifndef _MAC
dlgFile.m_ofn.lpstrTitle = title;
#else
dlgFile.m_ofn.lpstrPrompt = title;
#endif
dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
dlgFile.m_ofn.lpstrInitialDir = cstrInitialDir;
BOOL bResult = dlgFile.DoModal() == IDOK ? TRUE :
FALSE;
fileName.ReleaseBuffer(); CString
strFilterExt;
templatepTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt);
CString cstrSelFileExt =
fileName.Right(fileName.GetLength() - fileName.ReverseFind('.'));
cstrSelFileExt.MakeLower();
strFilterExt.MakeLower();
if(strFilterExt.Find(cstrSelFileExt) == -1)
{
AfxMessageBox("Invalid extension", MB_OK | MB_ICONHAND);
return FALSE;
}
return bResult;
}
BOOL CUtility::DoPromptFileName(CString cstrInitialDir, CString& fileName,
UINT nIDSTitle, DWORD lFlags,
BOOL bOpenFileDialog,
CDocTemplate **pTemplate)
{
CFileDialog dlgFile(bOpenFileDialog);
CString title;
VERIFY(title.LoadString(nIDSTitle));
dlgFile.m_ofn.Flags |= lFlags;
CString strFilter;
CString strDefault;
int i = 0;
while(pTemplate[i] != NULL)
{
ASSERT_VALID(pTemplate[i]);
AppendFilterSuffix(strFilter,
dlgFile.m_ofn, pTemplate[i], &strDefault);
i++;
}
dlgFile.m_ofn.lpstrFilter = strFilter;
#ifndef _MAC
dlgFile.m_ofn.lpstrTitle = title;
#else
dlgFile.m_ofn.lpstrPrompt = title;
#endif
dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
dlgFile.m_ofn.lpstrInitialDir = cstrInitialDir;
BOOL bResult = dlgFile.DoModal() == IDOK ? TRUE : FALSE;
fileName.ReleaseBuffer();
BOOL bExtMatched = FALSE;
i = 0;
while(pTemplate[i] != NULL)
{
CString strFilterExt;
templatepTemplate[i]->GetDocString(strFilterExt,
CDocTemplate::filterExt);
CString cstrSelFileExt =
fileName.Right(fileName.GetLength() - fileName.ReverseFind('.'));
cstrSelFileExt.MakeLower();
strFilterExt.MakeLower();
if(strFilterExt.Find(cstrSelFileExt) != -1)
{
bExtMatched = TRUE;
break;
}
i++;
}
if(!bExtMatched)
{
AfxMessageBox("Invalid extension", MB_OK | MB_ICONHAND);
return FALSE;
}
return bResult;
}
void CUtility::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())
{
#ifndef _MAC
ASSERT(strFilterExt[0] == '.');
#endif
if (pstrDefaultExt != NULL)
{
#ifndef _MAC
*pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1;
#else
*pstrDefaultExt = strFilterExt;
#endif
ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt);
ofn.nFilterIndex = ofn.nMaxCustFilter + 1;
}
filter += strFilterName;
ASSERT(!filter.IsEmpty());
filter += (TCHAR)'\0';
#ifndef _MAC
filter += (TCHAR)'*';
#endif
filter += strFilterExt;
filter += (TCHAR)'\0';
ofn.nMaxCustFilter++;
}
}