Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / MFC
Article

Removing filters from the Windows Common File Open Dialog

Rate me:
Please Sign up or sign in to vote.
3.67/5 (3 votes)
22 Nov 1999CPOL1 min read 75.4K   3   18   4
Removing filters from the Windows Common File Open Dialog.

Introduction

This article addresses 2 issues:

  1. Removing *.* filter from the MFC Doc-View architecture Open/Save File dialogs.
  2. 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), // 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 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 -

  1. Derive a class CMyDocManager from CDocManager.
  2. Provide an implementation 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);
    }
  3. In the InitApplication() function of the 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, 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; //Get the file extension of the
    templatepTemplate->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
        templatepTemplate[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++;
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Philips Electronics India Limited
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralCFileDialog Pin
Tran Duy Hung1-Sep-04 17:55
Tran Duy Hung1-Sep-04 17:55 
GeneralExcellent! Pin
Haakon S.29-Mar-04 8:58
Haakon S.29-Mar-04 8:58 
GeneralCode problem Pin
Peter Wasser26-May-00 13:55
Peter Wasser26-May-00 13:55 
GeneralRe: Code problem Pin
Haakon S.29-Mar-04 8:53
Haakon S.29-Mar-04 8:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.