Manipulating the File Open/Save Filters | CodeGuru

Manipulating the File Open/Save Filters

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 architectures “Open/Save File” functionality allows the user to open/save file of any type using the *.* filter. Now if you don’t want the user […]

Written By
CodeGuru Staff
CodeGuru Staff
Jul 29, 1999
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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 architectures “Open/Save File” functionality allows
the user to open/save file of any type using the *.* filter. Now
if you don’t want the user to do this

For example, I have created an MDI application using the 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), // custom MDI child frame
 RUNTIME_CLASS(CTest1View));
AddDocTemplate(m_pTest1DocTemplate);
m_pTest2DocTemplate = new CMultiDocTemplate(IDR_TEST2TYPE,
 RUNTIME_CLASS(CTest2Doc),
 RUNTIME_CLASS(CChildFrame), // custom MDI child frame
 RUNTIME_CLASS(CTest2View));
AddDocTemplate(m_pTest2DocTemplate);

where…
IDR_TEST1TYPE = nTest1Test1 FilenTest1 Files(*.ts1)n.ts1nts1nTest1n
IDR_TEST2TYPE = nTest2Test2 FilenTest2 Files(*.ts2)n.ts2nts2nTest2n

You have created a new Test1 file and added data to it. Now when 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 this *.* filter
in the file types combo box I suggest the following –

Derive a class CMyDocManager from CDocManager

Provide a implentation of the virtual function DoPromptFileName which is defined in the
CDocManager base class

//Implementation of the base class virtual function
BOOL CCGPDocManager::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
 CString cstrInitialDir = “”;
 //Depending on the Template you can set the Initial Folder
 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 your Application class add the following line –

//m_pDocManager is already defined in the CWinApp class
m_pDocManager = new CCGPDocManager();

Now when the user tries to save a Test1 file then 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);
}

CUtility class

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;
 //Get the file extension of the template
 pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt);
 //Get the file extension of the selected file
 CString cstrSelFileExt = fileName.Right(fileName.GetLength() – fileName.ReverseFind(‘.’));
 cstrSelFileExt.MakeLower();
 strFilterExt.MakeLower();
 //compare both if not the same extension then return false
 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;
  //Get the file extension of the template
  pTemplate[i]->GetDocString(strFilterExt, CDocTemplate::filterExt);
  //Get the file extension of the selected file
  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())
 {
  // 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)’’;  // next string please
#ifndef _MAC
  filter += (TCHAR)’*’;
#endif
  filter += strFilterExt;
  filter += (TCHAR)’’;  // next string please
  ofn.nMaxCustFilter++;
 }
}
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.