Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 семестр, WinAPI, MFC.pdf
Скачиваний:
378
Добавлен:
15.06.2014
Размер:
6.17 Mб
Скачать

CDocTemplate::yesAlreadyOpen и копирует объект CDocument файла в объект rpDocMatch. Если файл еще не открыт, но расширение имени в IpszPathName совпадает со значением, определенным в

CDocTemplate::filterExt, то функция возвращает CDocTemplate::yesAttemptNative и устанавливает rpDocMatch в NULL. В остальных случаях функция возвращает значение CDocTemplate::yesAttemptForeign. Другие члены перечисления можно использоватьприпереопределенииэтойфункции.

virtual CDocument* CDocTemplate::CreateNewDocument() —

создает новый документ, тип которого определяется текущим шаблоном. Функция возвращает указатель на вновь созданный документ или NULL в случае ошибки.

virtual CFrameWnd* CDocTemplate::CreateNewFrame( CDocument *pDoc,

CFrameWnd *pOther) -

создает новый фрейм (обычно невидимый) с присоединенными к нему документом и представлением. Параметр pDoc указывает на документ, на который ссылается новый фрейм. Если он равен NULL, то библиотека выводит соответствующее информационное сообщение. При создании нового фрейма можно использовать модель, которая задается параметром pOther. Эта функция позволяетсоздатьновыйфреймвнестандартнойреализацииобработчиков команд ID_FILE_NEW и ID_FILE_OPEN. Она возвращает указатель на вновь созданный фрейм или NULL, если произошла какая-либо ошибка.

virtual void CDocTemplate::lnitialUpdateFrame(

CFrameWnd *pFrame, CDocument *pDoc,

BOOL bMakeVisible = TRUE) -

применяется совместно с функцией CreateNewFrame для создания нового фрейма вне стандартной реализации команд ID_FILE_NEW и ID_FILE_OPEN и служит для получения представлением фрейма (параметр pFrame) вызова функции OnlnitialUpdate. Параметр pDoc указывает на документ, ассоциированный с фреймом, или содержит NULL. Параметр bMakeVisible показывает, долженлифреймстатьвидимымиактивным.

Как мы уже сказали, CDocTemplate - абстрактный класс, и на его основе объекты шаблонов не создаются. Его основная роль заключается в обеспечении шаблонов основными свойствами, а для создания конкретных объектов в библиотеке классов MFC реализованы два класса — CSingleDocTemplate и CMultiDocTemplate, которые специально адаптированы дляработы соответственно в SDI- и MDI-приложениях.

Класс CSingleDocTemplate

Данный класс определяет шаблон документа для однодокументного интерфейса. В SDI-приложениях главный фрейм является одновременно и фреймом документа, т. е. в конкретный момент времени может быть открыт только один документ. Обычно SDI-приложения поддерживают один тип документа (хотя это и не является обязательным условием), т. е. они содержат только один объект класса CSingleDocTemplate.

Объекты этого класса обрабатываются внутри библиотеки MFC. В своей защищенной части класс содержит член, в котором хранится указатель на документ, присоединенный к шаблону:

class CSingleDocTemplate : public CDocTemplate

protected :

CDocument *m_pOnlyDoc;

Ниже представлены основные функции класса.

CSingleDocTemplate::CSingleDocTemplate( UINT nIDResource, CRuntimeClass *pDocClass, CRuntimeClass *pFrameClass, CRuntimeClass *pViewClass) —

создаетобъектсоответствующегокласса. Назначениепараметровприведенов описании конструктора класса CDocTemplate.

Помимо конструктора, в классе реализованы все четыре "чистые" функции класса CDocTemplate.

virtual POSITION CDocTemplate::GetFirstDocPosition() -

возвращаетпозициюпервогодокументаизспискадокументов, ассоциированных с данным шаблоном, или NULL, если список пуст. Она переопределена в обоих производных классах — CSingleDocTemplate и CMultiDocTemplate. Если возникло желание создать свой класс на базе CDocTemplate, то эту функцию следуетвнемпереопределить.

virtual CDocument* CDocTemplate::GeNextDoc(POSITION &rPos) -

возвращает указатель на объект-документ из общего списка документов, ассоциированных с шаблоном, который хранится непосредственно за документом, заданным его позицией в списке (параметр rPos). Позиция полученного документа записывается в rPos. Если возвращен указатель на последний рлемент списка, то в параметр rPos функция записывает NULL. Для получения указателя на первый документ списка необходимо вызвать эту функцию доGetFirstDocPosition. При использовании в качестве параметра rPos недопустимого значения библиотека MFC генерирует исключение.

virtual CDocument* CDocTemplate::OpenDocumentFile( LPCTSTR IpszPathName,

BOOL bMakeVisible = TRUE) -

позволяет открыть файл, заданный полным именем IpszPathName, которой содержит необходимый документ. Если значение этого параметра равно NUL1, то вызывается функция CreateNewDocument, которая создает новый файл, содержащий документ типа, ассоциированного с этим шаблоном. При успешном завершении функция возвращаетуказательнадокумент, впротивномслучаеNULL.

virtual void CDocTemplate::SetDefaultTitle(CDocument *pDoc) —

загружает заголовок документа, используемый по умолчанию и определенный в строке ресурса, и выводит его в полосу заголовкафреймадокумента.

Кроме перечисленных "чистых" функций, в классе переопределены также функции базового класса AddDocument

и Remove Document.

Класс CMultiDocTemplate

Этот класс определяет шаблон документа для многодокументного интерфейса. MDI-приложения используют главный фрейм как рабочее место, в котором пользователь может открывать произвольное число окон документа, отображающих данные того или иного документа. Они могут поддерживать больше одного шаблона документов, и документы различных типов могут быть открыты одновременно.

Приложение использует шаблон(ы) документа, когда пользователь создает новый документ. Если приложение поддерживает больше одного типа документов, то библиотека получает имена поддерживаемых типов из шаблона и отображает их в списке блока диалога New, реализованного на базе класса

CNewTypeDlg. Как только пользователь выбрал тип документа, приложение создает объекты "документ", "фрейм" и "представление" и сопоставляет их друг другу.

В классе определены два общедоступных члена, отвечающих за совместное использование меню и таблицы акселераторов:

HMENU CMultiDocTemplate::m_hMenuShared; HACCEL

CMultiDocTemplate::m_hAccelTable;

Поскольку в многодокументных приложениях одновременно могут быть открыты несколько документов, в классе предусмотрен защищенный член:

CPtrList m_docList;

хранящий список открытых документов этого типа. Доступ к элементам списка осуществляется посредством функций GetFirstDocPosition и GetNextDoc.

Число непоименованных открытых документов хранится в специальном защищенном члене класса (нумерация начинается с нуля):

UINT m_nUntitledCount;

Значение, хранящееся в этой переменной, используется для генерации имени по умолчанию, и автоматически увеличивается при создании новых документов.

В MDI-приложениях определен, прежде всего, конструктор класса.

CMultiDocTemplate::CMultiDocTemplate( UINT nIDResource,

CRuntimeClass *pDocClass, CRuntimeClass *pFrameClass,

CRuntimeClass *pViewClass) — создаетобъекткласса.

Помимо конструктора, в классе реализованы также все четыре "чистые" функции базового класса:

GetFirstDocPosition, GetNextDoc, OpenFileName и SetDefaultTitle, описание которых приведено выше. Кроме того,

"наполнены новым содержанием" еще три функции: LoadTemplate, AddDocument и Remove Document.

В заключение обсуждения вопросов создания и использования шаблонов документов рассмотрим, каким образом с документом ассоциируется некоторая пиктограмма. Начнем с того, что написано в документации. "Пиктограмма, зарегистрированная для каждого шаблона документа, базируется на его позиции в списке шаблонов приложения. Порядок расположения шаблонов определяется порядком его занесения в список, т. е. порядком вызова функций AddDocTemplate. При этом библиотека MFC присваивает первый ресурс пиктограммы самому приложению, следующий — первому документу, и т. д.". А теперь попытаемся разобраться, что же все-таки здесь имеется в виду, ведь при работе пиктограмма большей частью определяется своим числовым идентификатором, а отнюдь не "...позицией в списке...". Рассмотрим фрагмент файла resource.h приложения NoteDraw:

#define IDR_MAINFRAME 128

//идентификатор главного окна

fdefine

IDR_NOTETYPE

129

//идентификатор окна текстового документа

Idefine

IDR_DRAWTYPE

130

//идентификатор окна графического

//документа ^define IDI_NOTEICON 129 //идентификатор пиктограммы окна

//текстового документа ^define

IDI_DRAWICON 130 //идентификатор пиктограммы окна

//графического документа

 

 

Прежде всего следует обратить внимание на то, что числа, характеризующие идентификаторы ресурсов документов и пиктограмм, принадлежат одному ряду. Это условие является обязательным, т. к. в противном случае на экране вы увидите пиктограмму по умолчанию вместо ожидаемой. И, наконец, числовые значения идентификаторов ресурсов документов и пиктограмм должны совпадать, иначе можно в окне текстового документа увидеть пиктограмму графического и наоборот. Во избежание подобных недоразумений рекомендуем для пиктограмм использовать тот же идентификатор, что и для ресурсов документов: IDR_NOTETYPE и IDR_DRAWTYPE.

Возвращаясь к классу приложения CWinApp, рассмотрим кратко те его функции, которые отвечают за взаимодействие с другими объектами, входящими в архитектуру "документ/представление".

void CWinApp::AddDocTemplate(CDocTemplate *pTemplate) —

добавляет шаблон документа pTemplate в список доступных шаблонов, которые поддерживает приложение. Все необходимые добавления в шаблон документа следует производить в функции Initlnstance до вызова функции RegisterShellFileTypes, т. к. в противном случае типы документов не будут представленывреестре.

В качестве примера рассмотрим фрагмент кода приложения NoteDraw, отвечающий за создание двух шаблонов документов, один из которых позволяет создавать документы для работы с текстом, а второй — с графическими объектами:

CMultiDocTemplate* pDocTemplate;

// Создаем объект "шаблон документа" для работы с текстом pCocTemplate = new CMultiDocTemplate(

RUNTIME_CLASS(CNoteFrame), RUNTIME_CLASS(CNoteDoc), RUNTIME_CLASS(CNoteView)); IDR_NOTETYPE,

//Добавляем шаблон в список

AddDocTempiate(pDocTemplate);

//Создаем объект "шаблон документа" для работы с графикой pDocTemplate = new CMultiDocTemplate(IDR_DRAWTYPE,

RUNTIME_CLASS(CDrawDoc), RUNTIME_CLASS(CDrawFrame), RUNTIME_CLASS(CDrawView));

//Добавляем шаблон в список AddDocTempiate(pDocTemplate);

STRINGTABLE PRELOAD DISCARDABLE BEGIN

IDR_MAINFRAME "NoteDraw" IDR_NOTETYPE "\nNote\nNote\nNote Files

( * . tnci) \n . tnd\nNote . DocumentXnNote Document" IDR_DRAWTYPE "\nDraw\nDraw\nDraw Files (*.dnd)\n.dnd\nDraw.Document\nDraw Document" END

POSITION CWinApp::GetFirstDocTemplatePosition() -

позволяет получить позицию первого шаблона документа приложения. Если список пуст, то возвращается NULL.

CDocTemplate* CWinApp::GetNextDocTemplate(POSITION &pos) -

позволяет получить шаблон документа, определяемый его позицией (параметр роз) в списке шаблонов приложения. После возврата из функции в роз содержится значение позиции следующего шаблона документа. Если полученный шаблон был последним в списке, то роз устанавливается в NULL.

Использование этих двух функций позволяет просматривать список доступных шаблонов документов приложения. При этом порядок их расположения в списке определяется порядком их записи туда посредством вызова функции AddDocTempiate.

virtual CDocument* CWinApp::OpenDocumentFile(LPCTSTR IpszFileName) -

открывает файл документа, задаваемый именем IpszFileName, и возвращает указатель на соответствующий объектдокумент. Если к моменту вызова функции файл уже был открыт, то активизируется фрейм, содержащий этот документ. Если приложение поддерживает несколько шаблонов документов, то для поиска соответствующего шаблона библиотека MFC использует файла. Вслучаеуспешноговыполненияшаблонсоздаетфреймипредставлениесоответствующегодокумента.

void CWinApp::CloseAllDocuments(BOOL bEndSession) -

закрываетвсеоткрытыедокументыдовыходаизприложения. Еслиприэтомпараметр bEndSession равен TRUE, то завершается и сеанс работы с Windows. Функцию следует вызывать после функции HideApplication.

virtual BOOL CWinApp::SaveAIIModified() -

вызывается библиотекой MFC для того, чтобы сохранить все документы, когда закрываетсяглавноеокноприложенияили обрабатывается сообщение WM_QUERYENDSESSION. Реализация этой функции по умолчанию вызывает функцию CDocument::SaveModified для сохранения всех изменений в документах,открытыхвнутриприложения.

afx_msg void CWinApp::OnFileNew()

и

afxjnsg void CWinApp::OnFileOpen() —

обработчики команд ID_FILE_NEW и ID_FILE_OPEN. Если обработка команды возлагается на библиотеку классов MFC, в карту сообщений класса приложения необходимодобавитьоператоры

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE__OPEN,

CWinApp::OnFileOpen)

ИЛИ

ON_COMMAND(ID_FILE_NEW, OnNameCommandFileNew) ON_COMMAND(ID__FILE_OPEN, OnNameCommandFileOpen)

если вы хотите самостоятельно обрабатывать эту команду. При этом на плечи программиста ложится реализация обработчика OnNameCommandFileNew (имя, естественно, произвольное).

В свете архитектуры "документ/представление" основным назначением объекта-приложения является то, что он содержит полный список шаблонов документов, используя для этого общедоступный член

CDocManager* CWinApp::m_pDocManager;

Фактически список хранится в защищенном члене класса библиотеки MFC — CDocManager

CPtrList CDocManager::m_templateList;

и доступ к нему осуществляется при помощи рассмотренных функций объекта-приложения

GetFirstDocTemplatePosition и GetNextDocTemplate, которые после предварительной обработки передают управление соответствующей функции класса CDocManager. В качестве примера рассмотрим три фрагмента кода из исходных текстов реализации функций классов CWinApp и CDocManager, первый из которых отвечает за добавление документа в шаблон, а остальные обрабатывают команду ID_FILE_NEW:

Наибольший интерес здесь представляет тот факт, что приложение может одновременно поддерживать несколько шаблонов (или типов) документов (рис. 32).

Экземпляры Экземплярыодногокласса другогокласса