Custom Open File or Save as Dialog

My COpenFileDlg class is an Open or Save dialog that does not allow the user to navigate to any other directory and it only shows files of one specific extension.

Sometimes we don't want to allow the user to switch to another directory or we only need to bring up files of a desired type. COpenFileDlg will pop up a message if the directory doesn't exist and then calls CDialog::OnCancel. Remember the purpose is to restrict access to the user so that's why if the directory doesn't exist we don't want to create it.

Here is how you use the COpenFileDlg class

(1) Include the dialog resource in your project IDD_OPEN_FILE

(2) Insert COpenFileDlg.h and COpenFileDlg.cpp to your project.

(3) Instantiate the class passing to the constructor the following 4 parameters:

The directory path

The file extension(not a wild card, just the extension)

The resource id of an icon that you want to represent the files with (Don't forget to use the appropiate icon size (16X16))

Either TRUE(default) for Open File Dialog or FALSE for Save as Dialog.

(4) Call DoModal on the Instance of COpenFileDlg.

(5) Call either of the two public member functions.

GetFileName() returns only the file name.

GetFilePath() return the full path.

(6) Look at the source code for details.

You'll notice that the dialog resource has a hidden listbox that I use only to forward the file names to the list control since the list control lacks this funcionality. You can click on a file name to select it or double click to select and dismiss the dialog.

Thanks for the time you've taken to read my article and feel free to email me your suggestions.


#include "OpenFileDlg.h"

void CCustomOpenFileDlg::OnShowCustomOpenFileDlg() 
{
 COpenFileDlg dlg(m_strDirPath, m_strFileExt, IDI_FILE_ICON);
 dlg.DoModal();
}

void CCustomOpenFileDlg::OnShowCustomSaveAsFileDlg() 
{
 COpenFileDlg dlg(m_strDirPath, m_strFileExt, IDI_FILE_ICON, FALSE);
 dlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// COpenFileDlg message handlers

BOOL COpenFileDlg::OnInitDialog() 
{
 CDialog::OnInitDialog();

 CWnd* pWnd;
 CString strWndTitle;

 if (!m_bIsOpenFileDlg)
 {
  strWndTitle.LoadString(_T(IDS_SAVE_FILE_AS));
  SetWindowText(strWndTitle);
  SetDlgItemText(IDOK, "Save");
 }
 else
 {
  strWndTitle.LoadString(_T(IDS_OPEN_FILE));
  SetWindowText(strWndTitle);
 }

 pWnd = GetDlgItem(IDOK);
 pWnd->EnableWindow(FALSE);

 CFileFind fileFind;

 // If directory does not exist, do not waste time
 if (!fileFind.FindFile(m_strDir))
 {
  CString msg("");
  msg.Format("Directory %s does not exist", m_strDir);
  MessageBox(msg, "Custom Open File Dialog", MB_OK | MB_ICONWARNING); 
  CDialog::OnCancel();
 }
	
 CString pathAndFileType = m_strDir + "\\*." + m_strFileType;
 m_ctrlFiles.Dir(DDL_DIRECTORY, pathAndFileType);

 int rowCount = m_ctrlFiles.GetCount();
 int row = m_ctrlFiles.GetTopIndex();

 m_IconImage.Create(::GetSystemMetrics(SM_CXICON) / 2,
  ::GetSystemMetrics(SM_CYICON) / 2, TRUE, 10, 10);

 m_IconImage.Add( AfxGetApp()->LoadIcon(m_nIconId) );
 m_ctrlRequestedFiles.SetImageList(&m_IconImage, LVSIL_SMALL);

 LV_ITEM item;   // Create the list items
 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
 item.state = item.stateMask = 0;

 // Iterate through the items in the listbox and populate the listconrol.
 CString strBuffer;
 for (row; row < rowCount; row++)
 {
  item.iItem = row; 
  item.iSubItem = 0; // refers to item therefore  = 0

  m_ctrlFiles.GetText(row, strBuffer);

  item.pszText = (char*) (LPCTSTR) strBuffer;
  item.iImage  = 0;

  item.lParam = row;
  m_ctrlRequestedFiles.InsertItem(&item);
 }
	
 return TRUE;  // return TRUE unless you set the focus to a control
 // EXCEPTION: OCX Property Pages should return FALSE
}

void COpenFileDlg::OnOK() 
{
 int index = m_ctrlRequestedFiles.GetNextItem(-1, LVNI_SELECTED);

 if (index > -1)
 {
  m_strFileName = m_ctrlRequestedFiles.GetItemText(index, 0);
 }
 else
 {
  m_ctrlFileName.GetWindowText(m_strFileName);

  CString strExt = "." + m_strFileType;

  if (!m_strFileName.IsEmpty())
  {
   int nFoundExt = m_strFileName.Find(strExt);

   if (nFoundExt < 0)
   {
    m_strFileName += strExt;
   }
  }
 }

 CDialog::OnOK();
}

void COpenFileDlg::OnClickRequestedFiles(NMHDR* pNMHDR, LRESULT* pResult) 
{
 int index = m_ctrlRequestedFiles.GetNextItem(-1, LVNI_SELECTED);

 if (index > -1)
 {
  m_strFileName = m_ctrlRequestedFiles.GetItemText(index, 0);

  m_ctrlFileName.SetWindowText(m_strFileName);
 }
 else
 {
  m_ctrlFileName.GetWindowText(m_strFileName);
		
  if ( m_strFileName.IsEmpty() )
  {
   CWnd* pWnd = GetDlgItem(IDOK);
   pWnd->EnableWindow(FALSE);
  }
 }
	
 *pResult = 0;
}

void COpenFileDlg::OnDblclkRequestedFiles(NMHDR* pNMHDR, LRESULT* pResult) 
{
 int index = m_ctrlRequestedFiles.GetNextItem(-1, LVNI_SELECTED);

 if (index > -1)
 {
  m_strFileName = m_ctrlRequestedFiles.GetItemText(index, 0);
 }

 CDialog::OnOK();

 *pResult = 0;
}

void COpenFileDlg::OnUpdateEditFilename() 
{
 // TODO: If this is a RICHEDIT control, the control will not
 // send this notification unless you override the CDialog::OnInitDialog()
 // function to send the EM_SETEVENTMASK message to the control
 // with the ENM_UPDATE flag ORed into the lParam mask.

 m_ctrlFileName.GetWindowText(m_strFileName);
		
 if ( m_strFileName.IsEmpty() )
 {
  CWnd* pWnd = GetDlgItem(IDOK);
  pWnd->EnableWindow(FALSE);
 }
 else
 {
  CWnd* pWnd = GetDlgItem(IDOK);
  pWnd->EnableWindow(TRUE);
 }
}

CString COpenFileDlg::GetFileName()
{
 return m_strFileName;
}

CString COpenFileDlg::GetFilePath()
{
 return m_strDir + "\\" + m_strFileName;
}

Download demo project - 7 KB

Download source - 18 KB

Date Last Updated: February 2, 1999



Comments

  • Changing the default file open/save dialogs in an MFC doc/view application

    Posted by Legacy on 02/16/2004 12:00am

    Originally posted by: Carlos Jara

    I try to show the OpenFileDialog from a buttom of a dialog.
    Dialog is a class derived from CDialog, and OpenFileOpen, is a class derived from CWinApp.

    Thanks


    Reply
  • How to sort the filed\s in the folder in CfileDialog ?

    Posted by Legacy on 12/06/2001 12:00am

    Originally posted by: jerry

    Sir,
    I want to display the files in selected folder as a sorted order in the MFC file open dialog box. Is it possible ? ie; any way to get the all files in the selected folder for customizing ? i wanmt ot implement the own sorting algorithm .If possible help to do that..

    Thanks in Advance and Waiting your replay

    respectively,
    Jerry

    Reply
  • File save dialog

    Posted by Legacy on 09/06/2001 12:00am

    Originally posted by: BMistry

    Hi how would I default to user working dir or folder when saving changes made to file
    for example if user select file save item from menubar i like the file to be saved in the folder wher user is working
    Thank you

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

Top White Papers and Webcasts

  • Hybrid cloud platforms need to think in terms of sweet spots when it comes to application platform interface (API) integration. Cloud Velocity has taken a unique approach to tight integration with the API sweet spot; enough to support the agility of physical and virtual apps, including multi-tier environments and databases, while reducing capital and operating costs. Read this case study to learn how a global-level Fortune 1000 company was able to deploy an entire 6+ TB Oracle eCommerce stack in Amazon Web …

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today makes data protection a must-have, as we live in a data-driven society -- the digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join Seagate Cloud …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds