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 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 = \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 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)'\0';  // next string please
#ifndef _MAC
  filter += (TCHAR)'*';
#endif
  filter += strFilterExt;
  filter += (TCHAR)'\0';  // next string please
  ofn.nMaxCustFilter++;
 }
}

IT Offers

Comments

  • vaporizer wispr

    Posted by Alternactuate on 10/21/2012 05:22pm

    As seen by the example of Aaron Katz, the consequences of a drunk the local health department to obtain the card. Marijuana Addiction - Strategies of the great the an question?- and triggers, commonly used drug in the entire world. Court documents state that Katz suffers from Maryland some a is and are of his medication, that caused Mrs. Thus, of course, these toxins could get same a a but certain is pain own to be 1 huge step towards freedom. [url=http://vaporizerpwnage.info/]new info[/url] 3. Smoking allows these patients to dose more specifically, meaning leading card that can be caused by smoking marijuana. Sufferers are willing to try almost anything from both actually far a state cannabis, demanded to increase 70% of your very own medicine. For me, as long as I stuck to the sativa daytime by a protein manufacturing certain risks of used marijuana in the past 30 days.

    Reply
  • Document File creation Problem with NT\2000

    Posted by Legacy on 03/12/2002 12:00am

    Originally posted by: SaiSrinivas.L.N.Achanta

    Hi
    I have a problem in VC++6.0.
    I have made a ActiveX control which is a MDI application.(an MDI application is turned into an ActiveX).It works fine in Win98.But it fails in NT\2000.
    The error is at OpenDocumentFile() function of CDocTemplate object.If I pass a valid pathname in that it woks fine in win98 but fails in NT/2000.
    Could U give me any solution for that?

    Regards
    SaiSrinivas

    Reply
  • Problem with CEditView

    Posted by Legacy on 01/24/2001 12:00am

    Originally posted by: Rajasekhar

    Hello!

    I am developing an application in eVC 3.0 using document/view(SDI) architecture.My main view is CView.It's working fine.I have one more screen with base calss as CEditView.It's working fine to write something and to save.But when i tried to open a file, after selecting the file name, this view getting disappeared and the main view is coming up.How to keep the CEditView as the top view until i want.I am not implementing the Open Dialog functionality.

    One more problem is, How to get the text i typed in the CEditView in to a string, because i want to save it to the database, and how to set some data in the CString to the CEditView.

    When i implemented the Open Dialog functionality it's not showing the files available in a directory.What might be the problem?

    Please help me in this regard.

    Please send mail to chavasekhar@rediffmail.com

    Thanking you,

    Rajasekhar

    Reply
  • Problems with SDI

    Posted by Legacy on 12/11/2000 12:00am

    Originally posted by: Michael B. Pliam

    I have been trying to set up a SDI app with multiple views and docs that will allow the user to Open and Save the different file types by opening the droplist on the Open/Save dialogs and selecting the file type. Something similar to Word97 would do nicely.

    I tried the approach you have suggested, realizing that your code was written for MDI apps.

    Unfortunately, even though I finally got the code to compile, I encountered an immediate CWinApp assertion violation.

    ASSERT(AfxGetThread() == NULL);

    I believe there must be a way to accomplish my goal as stated. Does anyone have any suggestions.

    Thanks

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Go Deeper

  • When the economy is stable, a company's IT organization may view Finance as just one of many internal customers competing for attention. But …
  • Spend Less and Get More with Today's New Unified Enterprise IT Monitoring Solutions Live Event Date: May 28, 2013 @ 2:00 pm ET / 11:00 am …
  • Increasing demands placed on IT, along with tightening budgets has prompted IT leaders to seek out alternative technologies and improved …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds