Multiple File Selection Dialog | CodeGuru

Multiple File Selection Dialog

I wanted to open a number of files at the same time from a Visual C++/MFC application. However, a ClassWizard generated application (with file support) only allows for the opening of a single file at a time. Therefore, I derived my own custom class from CFileDialog called MFileDlg. Using this class, I can now specify […]

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

I wanted to open a number of files at the same time from a Visual C++/MFC application.
However, a ClassWizard generated
application (with file support) only allows for the opening of a single file at a time.
Therefore, I derived my own custom class from CFileDialog called MFileDlg. Using this class,
I can now specify multiple files to be opened from the Open File dialog.

Class Declaration:


class MFileDlg : public CFileDialog
{
DECLARE_DYNAMIC(MFileDlg)

public:
 MFileDlg(BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL , LPCTSTR lpszFileName = NULL,
  DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT,
  LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL) ;

 int DoModal();
 virtual ~MFileDlg();

protected:
 //{{AFX_MSG(MFileDlg)
 // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

 TCHAR* m_pszFile;
 DECLARE_MESSAGE_MAP()
};

Class Implementation:

IMPLEMENT_DYNAMIC(MFileDlg, CFileDialog)

MFileDlg::MFileDlg(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
 DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
 CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
 m_pszFile = new TCHAR[2048]; //set a 2K buffer to hold selected files
 m_pszFile[0] = ''; //initialize pointer;
}

BEGIN_MESSAGE_MAP(MFileDlg, CFileDialog)
//{{AFX_MSG_MAP(MFileDlg)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

MFileDlg::~MFileDlg()
{
 if (m_pszFile != NULL)
 delete [] m_pszFile; //cleanup
}

int MFileDlg::DoModal()
{
 ASSERT_VALID(this);
 ASSERT(m_ofn.Flags & OFN_ALLOWMULTISELECT); //make sure multiple file selection is on

 m_ofn.lpstrFile = m_pszFile; //initialize the OPENFILENAME structure
 m_ofn.nMaxFile = 2048;

 return CFileDialog::DoModal();
}
Advertisement

How to Use:

1. On your CwinApp-derived class, override the OnOpenFile() function.

void CDigilogApp::OnFileOpen()
{
// TODO: Add your command handler code here
 MFileDlg dlgFile(TRUE);

 CString title, strFilter, strDefault;
 VERIFY(title.LoadString(AFX_IDS_OPENFILE));

 // do for all doc template
 POSITION pos = GetFirstDocTemplatePosition();
 BOOL bFirst = TRUE;
 while (pos != NULL)
 {
  CDocTemplate* pTemplate = GetNextDocTemplate(pos);
  AppendFilterSuffix (strFilter, dlgFile.m_ofn, pTemplate,
  bFirst ? &strDefault : NULL);
  bFirst = FALSE;
 }

 // append the "*.*" all files filter
 CString allFilter;
 VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
 strFilter += allFilter;
 strFilter += (TCHAR)'';   // next string please
 strFilter += _T("*.*");
 strFilter += (TCHAR)'';   // last string
 dlgFile.m_ofn.nMaxCustFilter++;

 dlgFile.m_ofn.lpstrFilter = strFilter;
 dlgFile.m_ofn.lpstrTitle = title;
 dlgFile.m_ofn.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();

 if (dlgFile.DoModal() == IDOK)
 {
  POSITION pos = dlgFile.GetStartPosition();
  while (pos != NULL)
  {
   CString strPath = dlgFile.GetNextPathName(pos);
   if (strPath.Find(":\\") == 1 && strPath.GetLength() > 4)
   {
    // this means we have an invalid path that looks like this:
    // C:\cda.dgl
    // get rid of extra slash
    CString temp;
    temp = strPath.Left(3);
    temp += strPath.Mid(4);
    strPath = temp;
   }
   OpenDocumentFile(strPath);
  }
 }
}

2. Add this declaration and function to your CwinApp- derived class .

static void AppendFilterSuffix(CString& filter, OPENFILENAME& ofn,
CDocTemplate* pTemplate, CString* pstrDefaultExt);

static void 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
  ASSERT(strFilterExt[0] == '.');
  if (pstrDefaultExt != NULL)
  {
   // set the default extension
   *pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1;  // skip the '.'
   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
  filter += (TCHAR)'*';
  filter += strFilterExt;
  filter += (TCHAR)'';  // next string please
  ofn.nMaxCustFilter++;
 }
}

History

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.