MFC Solution to Explanding the CFileDialog Common Dialog

Sunday Jan 30th 2000 by Milan Markovic

MFC Solution to Explanding the CFileDialog Common Dialog


This article explains how to expand the CFileDialog common dialog box. Although there are similar articles elsewhere on the Internet, none of them resolved the problem of adding user controls in CFileDialog in an MFC manner (without hook procedures, which are not encouridged by MFC any more).

In this article you'll find a way how to add one static control and one combo box control to CFileDialog standard dialog. The sample code is of no particular use as the problem is general, but briefly explains concept, and what is more important, I am using similar code in my applications.


To add two controls to CFileDialog dialog box, we have to do following:
  1. Enlarge standard CFileDialog. This can be done by subblussing CFileDialog class and overiding OnInitDialog member function
  2. To retrieve information from additional controls, you must override OnDestroy() member function.


The sample included here shows CFileDialogEx class, derived from CFileDialog using classwizard. Added member variable, m_nSubType, is used for displaying possible document subtypes. Choosen value is saved in the same variable and passed to document m_nDocSubType variable. CComboBox and CStatic objects are added for purpose of our sample.There are two message handlers that override standard WM_INITDIALOG and WM_DESTROY messages for CFileDialogEx object:
// CFileDialogEx dialog
class CFileDialogEx : public CFileDialog

 int m_nSubType;
 CStatic m_Static;
 CComboBox m_Combo;  // our combo box control

 // TRUE for FileOpen, FALSE for FileSaveAs
 CFileDialogEx(BOOL bOpenFileDialog, 
  LPCTSTR lpszDefExt = NULL,
  LPCTSTR lpszFileName = NULL,
  LPCTSTR lpszFilter = NULL,
  CWnd* pParentWnd = NULL);

 virtual BOOL OnInitDialog();
 afx_msg void OnDestroy();
Our first task is done by adding handler for WM_INITDIALOG:
BOOL CFileDialogEx::OnInitDialog() 
 // TODO: Add extra initialization here

 // We need to enlarge standard CFileDialog to make space 
 // for our controls idea from Christian Skovdal Andersen 
 // article - Customizing CFileDialog
 char szText[120];
 // This variable should be changed acording to your wishes
 const UINT iExtraSize = 50;
 // Get a pointer to the original dialog box.
 CWnd *wndDlg = GetParent();
 RECT Rect;

 // Change the size of FileOpen dialog
 wndDlg->SetWindowPos(NULL, 0, 0, 
                        Rect.right - Rect.left, 
                        Rect.bottom - + iExtraSize, 

 // Standard CFileDialog control ID's are defined in 
 // Do not forget to include  in implementation file

 // cmb1 - standard file name combo box control
 CWnd *wndComboCtrl = wndDlg->GetDlgItem(cmb1); 

 wndDlg->ScreenToClient(&Rect); // Remember it is child controls

 // Put our control(s) somewhere below HIDDEN checkbox
 // Make space for 3 different subtypes += 60;
 Rect.bottom += 120;
 Rect.left += 50;

 // Our control is CComboBox object

 // IMPORTANT: We must put wndDlg here as hWndParent, 
 // NOTE: "this" as written in Microsoft documentation 
 // example

 // NOTE: IDC_MYCOMBOBOX and IDC_MYSTATIC must be defined 
 // (best in resource.h)
  Rect, wndDlg, IDC_MYCOMBOBOX);

 // save new control font according to other controls font
 m_Combo.SetFont(wndComboCtrl->GetFont(), TRUE);

 // We also need Static Control. Get coordinates from 
 // stc3 control
 CWnd *wndStaticCtrl = wndDlg->GetDlgItem(stc2);
 wndDlg->ScreenToClient(&Rect); += 60;
 Rect.bottom += 80;
 Rect.right += 40;

 // our static control
 m_Static.Create("Proba", WS_CHILD | WS_VISIBLE, Rect, 
  wndDlg, IDC_MYSTATIC);

 m_Static.SetFont(wndComboCtrl->GetFont(), TRUE);

 // Now, fill up static control and combo control
 // Our ComboBox control will offer three diffirent file 
 // subtypes. Current file subtype is held in m_nSubType 
 // member variable which will hold resulting (final) subtype, 
 // also.
 for (int i=0; i < 3; i++) {
  sprintf(szText, "Subtype%d", i);
   (WPARAM) (-1), (LPARAM) (szText));
  // Set displayed subtype to sybtype format of working file
  if (m_nSubType == i)
   wndDlg->SetDlgItemText(IDC_MYCOMBOBOX, szText);
 // Add some general text for static box
 sprintf(szText, "File SubType Format");
 wndDlg->SetDlgItemText(IDC_MYSTATIC, szText);
 return TRUE;  // return TRUE unless you set the focus 
               // to a control
               // EXCEPTION: OCX Property Pages should 
               // return FALSE
Second task is done by adding message handler for WM_DESTROY message:
void CFileDialogEx::OnDestroy() 
 // TODO: Add your message handler code here
 char szText[40];

 // get/save SaveAs file subtype
 if (GetParent()->GetDlgItemText(IDC_MYCOMBOBOX, 
  szText, sizeof(szText)) > 0)
   m_nSubType = szText[strlen(szText)-1] - '0';


Probably you'll add message handler for ID_EDIT_SAVEAS menu item:
void CMyFileDialogDoc::OnFileSaveAs() 
 // TODO: Add your command handler code here
 // Call our Save As dialog box
 CFileDialogEx filedialog(FALSE, NULL, GetTitle(),

 // pass document subtype to our SaveAs dialog box
 filedialog.m_nSubType = m_nDocSubType;

 filedialog.m_ofn.lpstrTitle = 
  "User added controls - Save File As";

 // display our dialog
 if (filedialog.DoModal() == IDOK)
  // get/save document subtype
  m_nDocSubType = filedialog.m_nSubType;
  char szText[100];
  sprintf(szText, "Document will be saved under "
   "subtype %d", m_nDocSubType);


  // do your own SaveAs procedure or call document default
  // CDocument::OnSaveDocument()
 // error handling (if any)
 // ...
Comparing this with hook procedures and user-added templates, that I had to prepare in my earlier API samples, this seems to be much elegant. Only problem was bad Microsoft documentation that used "this" pointer instead of parent window (as explained earlier) while creating user controls. Also, you cannot override OnOK() member function in CFileDialog dialog as you can do that in other dialogs. You should check/save data from your controls in OnDestroy() message handler.

I included demo project that shows trivial use of CFileDialogEx class, but it should be used only as reference for your own purposes.


Download demo project - 19 Kb
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved