演示了如何多选文件,重设缓冲区,在国外站点找到的
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++; } }