

Программирование на языке MFC
Мой второй блог в серии программирования
Функция СDocTemplate::MatchDocType
Невооруженным глазом видно, что в начале функции ‘CDocTemplate::MatchDocType] производятся всевоз можные подготовительные действия, а также проверяется, не является ли выбранный нами файл ссылкой на другой файл. С точки зрения архитектуры «документ/представление» все это не очень интересно. Интересное начинается с момента начала перебора списка шаблонов. Обратите внимание, уважаемый читатель, на то, что для каждого шаблона в списке шаблонов вызывается метод CDocTemplate::MatchDocType(). Этот метод определяет, насколько расширение открываемого файла соответствует указанному в шаблонах. В качестве аргументов этому методу передаются имя файла, который мы хотим открыть, и переменная типа "указатель на документ", которая равна NULL. Ниже я привожу исходный текст этого метода. Его можно найти в файле docmgr.cpp:
CDocTemplate:Confidence
CDocTemplate::MatchDocType(LPCTSTR IpszPathName,
CDocument*& rpDocMatch)
{
ASSERT(IpszPathName != NULL); rpDocMatch = NULL;
// go through all documents
POSITION pos = GetFirstDocPosition();
while (pos != NULL)
{
CDocument* pDoc = GetNextDoc(pos);
if (AfxComparePath(pDoc->GetPathName(), IpszPathName)) {
// already open
rpDocMatch = pDoc; return yesAlreadyOpen;
}
}
// see if it matches our default suffix CString strFilterExt; if (GetDocString(strFilterExt,
CDocTemplate::filterExt) && !strFilterExt.IsEmpty())
{
// see if extension matches
ASSERT(strFilterExt[0] == 4.’);
LPCTSTR IpszDot = _tcsrchr(IpszPathName, ‘.’);
if (IpszDot != NULL &&
lstrcmpi(IpszDot, strFilterExt) == 0) return yesAttemptNative; // extension matches,
// looks like ours
}
// otherwise we will guess it may work return yesAttemptForeign;
}
Обратите внимание на следующие обстоятельства. Если файл с именем, совпадающим с первым аргументом метода, уже открыт в соответствии с текущим шаблоном, то указатель на открытый документ сохраняется в указателе, переданном в качестве второго документа. Другими словами, создается новая ССЫЛКА на открытый ранее документ, при этом вторая копия документа не создается. В этом случае метод возвращает значение yesAlreadyOpen.
Если файл ранее не был открыт в соответствии с текущим шаблоном, то выбирается подстрока, содержащая расширение файла (помните, читатель, описание метода CDocTemplate::GetDocString()?), из переданной шаблону строки ресурсов. Если эта подстрока совпадает с расширением открываемого файла, то метод возвращает значение yesAttemptNative. Указатель на документ, переданный в качестве второго аргумента, при этом не изменяется и остается равным NULL.
И наконец, если расширение открываемого файла не соответствует расширению, записанному в шаблоне, то метод возвращает значение yesAttemptForeign. При этом указатель, переданный в качестве второго аргумента, также остается равным NULL.
Любознательный читатель, вероятно, тут же задаст мне вопрос. Как же так, ведь в перечислении CDocTemplate: Confidence используются еще три значения, noAttempt, maybeAttemptForeign и may-beAttemptNative? А в каких случаях возвращаются эти значения? Здесь я могу только догадываться. Возможно, программисту потребуется иногда делать предположение о том, что открываемый файл соответствует текущему шаблону вне зависимости от расширения. Например, если шаблон файла предусматривает расширение «arj», а пользователь выбрал файл с расширением «aDD» (где «DD» означает две любые цифры), то, наверное, программист сможет, переопределив метод CDocTemplate::MatchDocType(), вернуть значение maybeAttemptNative. С другой стороны, если пользователь в этом случае выбрал файл с расширением, скажем, «txt», то программист может сделать предположение о том, что открываемый файл не соответствует шаблону, и вернуть значение тау-beAttemptForeign. Наверное, возможны еще какие-то случае, когда программисту потребуется использовать значение noAttempt.
Похожие статьи: CDocTemplate
