Программирование на языке 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.

Похожие статьи: