How to Support Two File Extensions per MFC Document TypeID: Q141921
|
Applications built with the Microsoft Foundation Classes (MFC) document or
view architecture have at most one file extension associated with each
document type. This default file extension, if specified, is stored in the
document template string stored in the string table.
It is often useful to associate two file extensions with a given document
type. This article describes a technique you can use to allow two file
extensions to be stored in the document template string. Through class
derivation and function overrides, it is possible to associate both file
extensions with the document template.
\nExts\nExts\nFiles (*.aaa; *.bbb)\n.aaa;.bbb\nExts.Doc\nExts Doc.
CMyMultiDocTemplate::CMyMultiDocTemplate(
UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass ) :
CMultiDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass)
{ };
BOOL CMyMultiDocTemplate::GetDocString(CString& rString,
enum DocStringIndex i) const
{
CString strTemp,strLeft,strRight;
int nFindPos;
AfxExtractSubString(strTemp, m_strDocStrings, (int)i);
if(i == CDocTemplate::filterExt) {
nFindPos=strTemp.Find(';');
if(-1 != nFindPos) {
//string contains two extensions
strLeft=strTemp.Left(nFindPos+1);
strRight="*"+strTemp.Right(lstrlen((const
char*)strTemp)-nFindPos-1);
strTemp=strLeft+strRight;
}
}
rString = strTemp;
return TRUE;
}
CDocTemplate::Confidence CMyMultiDocTemplate::MatchDocType(const
char* pszPathName, CDocument*& rpDocMatch)
{
ASSERT(pszPathName != NULL);
rpDocMatch = NULL;
// go through all documents
POSITION pos = GetFirstDocPosition();
while (pos != NULL)
{
CDocument* pDoc = GetNextDoc(pos);
if (pDoc->GetPathName() == pszPathName) {
// already open
rpDocMatch = pDoc;
return yesAlreadyOpen;
}
} // end while
// see if it matches either suffix
CString strFilterExt;
if (GetDocString(strFilterExt, CDocTemplate::filterExt) &&
!strFilterExt.IsEmpty())
{
// see if extension matches
ASSERT(strFilterExt[0] == '.');
CString ext1,ext2;
int nDot = CString(pszPathName).ReverseFind('.');
const char* pszDot = nDot < 0 ? NULL : pszPathName + nDot;
int nSemi = strFilterExt.Find(';');
if(-1 != nSemi) {
// string contains two extensions
ext1=strFilterExt.Left(nSemi);
ext2=strFilterExt.Mid(nSemi+2);
// check for a match against either extension
if (nDot >= 0 && (lstrcmpi(pszPathName+nDot, ext1) == 0
|| lstrcmpi(pszPathName+nDot,ext2) ==0))
return yesAttemptNative; // extension matches
}
else
{ // string contains a single extension
if (nDot >= 0 && (lstrcmpi(pszPathName+nDot,
strFilterExt)==0))
return yesAttemptNative; // extension matches
}
}
return yesAttemptForeign; //unknown document type
}
// append the default suffix if there is one
CString strExt;
if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
!strExt.IsEmpty())
{
ASSERT(strExt[0] == '.');
newName += strExt;
}
with these lines:
// append the default suffix if there is one
CString strExt;
if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
!strExt.IsEmpty())
{
ASSERT(strExt[0] == '.');
int nSemi; //added
if(nSemi = strExt.Find(';')); //added
strExt = strExt.Left(nSemi); //added
newName += strExt;
}
The three added lines of code return the first extension by default when
Save As is processed for a document type that has two extensions
specified in its document string. The user must type over this extension
if a file is to be saved with the second extension specified in the
document string.
CATCH_ALL(e)
{
TRACE0("Warning: failed to delete file after failed SaveAs.\n");
DELETE_EXCEPTION(e);
}
with:
CATCH_ALL(e)
{
TRACE0("Warning: failed to delete file after failed SaveAs.\n");
e->Delete(); //modified
}
This is necessary because the DELETE_EXCEPTION() macro is undefined in
this context.
Additional query words: kbinf 1.50 1.51 1.52 2.00 2.50 3.00 3.10
Keywords : kbDocView kbMFC kbThread kbVC
Version : 1.00 1.50 1.51 1.52 | 2.00 2.10
Platform : NT WINDOWS
Issue type :
Last Reviewed: August 5, 1999