在MDI应用程序中,支持同时打开多个文件是非常有用的,
比如,Microsoft的Word,Visual Studio 6.0等,都支持同时打开多个文件。
在MFC中,打开多个文件(以及其他文档管理活动)在MFC的CDocMananger类中实现。
CWinApp包含一个成员m_pDocManager,用于指向要用的CDocManager对象。
如果要修改标准MFC行为,只需提供自己的 CDocManager派生对象即可。
我们可以从 CDocManager派生了一个 CMultiOpenDocManager,并重载了OnFileOpen函数。
新的 DoPromptFileNames函数与原来的 DoPromptFileName函数类似,不过增强了处理多个文件的能力。
class CMultiOpenDocManager : public CDocManager
{
public:
CMultiOpenDocManager() { }
virtual void OnFileOpen();
virtual BOOL DoPromptFileNames(CStringList& fileNames, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
};
使用它的方法非常简单,仅需在应用程序类的InitInstance添加下面代码即可:
m_pDocManager = new CMultiOpenDocManager;
OnFileOpen函数的实现与原来的实现非常类似,
仅把DoPromptFileName替换为 DoPromptFileNames,并增加了OFN_ALLOWMULTISELECT标志,
以及引入了 OpenDocumentFile调用循环:
void CMultiOpenDocManager::OnFileOpen()
{
CStringList newNames;
if (!DoPromptFileNames(newNames, AFX_IDS_OPENFILE,
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT, TRUE, NULL))
return; // open cancelled
POSITION pos = newNames.GetHeadPosition();
while (pos)
{
CString newName = newNames.GetNext(pos);
AfxGetApp()->OpenDocumentFile(newName);
}
}
下面是DoPromptFileNames函数:
它几乎是原来实现的拷贝,在注释中添加了所作的修改。
BOOL CMultiOpenDocManager:oPromptFileNames(CStringList& fileNames, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
CFileDialog dlgFile(bOpenFileDialog);
CString title;
VERIFY(title.LoadString(nIDSTitle));
dlgFile.m_ofn.Flags |= lFlags;
CString strFilter;
CString strDefault;
if (pTemplate != NULL)
{
ASSERT_VALID(pTemplate);
AppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);
}
else
{
// do for all doc template
POSITION pos = m_templateList.GetHeadPosition();
BOOL bFirst = TRUE;
while (pos != NULL)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(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
#ifndef _MAC
strFilter += _T("*.*");
#else
strFilter += _T("****");
#endif
strFilter += (TCHAR)'\0'; // last string
dlgFile.m_ofn.nMaxCustFilter++;
dlgFile.m_ofn.lpstrFilter = strFilter;
#ifndef _MAC
dlgFile.m_ofn.lpstrTitle = title;
#else
dlgFile.m_ofn.lpstrPrompt = title;
#endif
// --- Begin modifications ---
// - use a big buffer for the file names
// (note that pre-SP2 versions of NT 4.0 will nevertheless
// truncate the result)
CString strFileNames;
dlgFile.m_ofn.lpstrFile = strFileNames.GetBuffer(2048);
dlgFile.m_ofn.nMaxFile = 2048;
BOOL bResult = dlgFile.DoModal() == IDOK ? TRUE : FALSE;
strFileNames.ReleaseBuffer();
if (!bResult)
return FALSE; // open cancelled
// - copy the file names to a string list
POSITION pos = dlgFile.GetStartPosition();
while (pos)
{
fileNames.AddTail(dlgFile.GetNextPathName(pos));
}
return TRUE;
// --- End modifications ---
}
|