CFIleDialog複数のファイルを開く


 , , 
This article was contributed by Zandro Arceo.
I wanted to open a number of files at the same time from a Visual C++/MFC ap
plication. 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 c
an 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 lpszFile
Name = NULL,
  DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISEL
ECT,
  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 lpszFil
eName,
 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] = '/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 selec
tion is on
 m_ofn.lpstrFile = m_pszFile; //initialize the OPENFILENAME structure
 m_ofn.nMaxFile = 2048;
 return CFileDialog::DoModal();
}
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)'/0';   // next string please
 strFilter += _T("*.*");
 strFilter += (TCHAR)'/0';   // 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)'/0';  // next string please
  filter += (TCHAR)'*';
  filter += strFilterExt;
  filter += (TCHAR)'/0';  // next string please
  ofn.nMaxCustFilter++;
 }
}