Лекція № 5: Основні типи програм на основі класів MFC

 

План

1. Архітектура “Документ/вигляд”.

2. Програми з одним документом (SDI).

3. Програми з багатьма документами (MDI).

4. Програми на основі діалогу.

 

Архітектура “Документ/вигляд”

До основних типів програм, що будуються під Windows на основі бібліотеки MFC, можна віднести:

- одно-документні програми (SDI);

- багато-документні програми (MDI);

- програми на основі діалогу.

Перші два типи програм будуються на основі архітектури „Документ/Вигляд”. В основі цієї архітектури лежать три глобальні поняття рамка, документ та вигляд. Розглянемо детальніше ці поняття.

Документ. Під „документом” фірма Microsoft розуміє ті дані, що обробляються програмою. Під даними можна розуміти, що завгодно; звичайний текст, зображення, структуровані дані та інше. Ці дані зберігаються в основному в постійній пам’яті комп’ютера і відображаються у рамці програми.

Вигляд. Це спеціальне вікно в якому відображається вміст документу та за допомогою якого відбувається взаємодія з користувачем.

Таким чином спосіб зберігання даних в постійній пам’яті не впливає на спосіб їх представлення користувачу.

Рамка. В архітектурі „Документ/Вигляд”, рамка виконує роль посередника між документом та його виглядом. В її завдання входить: створити відповідні, для кожного з типів документів, вікна виглядів; координувати взаємодію між документами різних типів та їх виглядами. Поняття рамка найчастіше асоціюється з основним вікном програми.

Рамка в загальному складається з основного вікна де розміщено загальні елементи керування (меню, піктограми інструментів, рядок статусу і т.п.) та клієнтської області в якій міститься дочірнє вікно вигляду (SDI- програма) або дочірні вікна (MDI- програма). На рис. __ показано взаємозв’язок між об’єктами рамки, документу та вигляду.

В архітектурі „Документ/Вигляд” за взаємодію користувача з рамкою відповідає операційна система. А керування відображенням документа повністю лягає на плечі розробника.

Для координації створення та взаємодії між трьома основними об’єктами архітектури в бібліотеці класів MFC використовується спеціальні класи шаблонів документів, які створюються та керуються класом „програма”. Таким чином архітектура „Документ/Вигляд” охоплює наступні основні класи:

- CWinApp – створення єдиного об’єкту програми.

- CFrameWnd – клас створення основного вікна програми, базовий для класів CMDIFrameWnd та CMDIChildWnd.

- CDocTemplate – базовий абстрактний клас для створення шаблонів документів: для однодокументних програм від нього створюється клас CSingleDocTemplate; для багатодокументних програм - клас CMultiDocTemplate.

- CDocument – клас для створення документу.

- CView – базовий клас, що разом зі своїми нащадками – CctrlView, CEditView, CListView та іншими, відповідає за відображення даних документу та взаємодіє з користувачем.

 

 

 

Рис. __. Взаємозв’язок між об’єктами рамки, документу та вигляду

 

Шаблон документу. Програма під Windows може одночасно працювати з багатьма різними типами документів, але їх (ці типи) необхідно зареєструвати при ініціалізації примірника програми. Для цього використовується шаблон (причому для кожного типу свій).

Клас шаблону документу призначений для організації взаємодій між класами:

- документу;

- вигляду;

- рамки.

Конструктор класу, фіксує та зв’язує між собою типи класів документу, вигляду та рамки.

 

CDocTemplate:: CDocTemplate(UINT nIDResouce, CRuntimeClass *pDocClass,
CRuntimeClass *pFrameClass, CRuntimeClass *pViewClass);

 

де nIDResouce – ідентифікатор ресурсів (меню, акселератори, рядок описання типу шаблону), що асоціюються з даним типом документу; pDocClass, pFrameClass, pViewClass – вказівними типу CRuntimeClass на документ, рамку та вигляд, відповідно.

У клас шаблону документу CDocTemplate реалізовано декілька чисто-віртуальних функцій (GetFirstDocPosition, GetNextDoc, OpenFileName та ін.), тому цей клас є абстрактним і, як наслідок, його не можна використовувати безпосередньо. Найчастіше використовуються його класи-нащадки CSingleDocTemplate та CMultiDocTemplate, допомогою яких створюються одно- та багато-документні програми, відповідно. При потребі створення програми, що суттєво відрізняється від архітектури „Документ/Вигляд” необхідно створити свій шаблон документу на основі CDocTemplate, в якому перевизначити всі чисто-віртуальні функції.

Реєстрація шаблону документу та зв’язування документу, рамки та вигляду відбувається в методі InitInstance класу CWinApp.

Клас CSingleDocTemplate. Визначає шаблон документу для одно-документного інтерфейсу. В SDI-програмах основна рамка найчастіше є основним вікном програми, тобто одночасно може бути відкритий тільки один документ (хоча це не обов’язково). У своїй захищеній частині клас містить член, в якому зберігається вказівник на документ, що приєднаний до програми. В касі перевизначено всі чисто-віртуальні функції базового класу, що робить його придатним для подальшого використання.

Клас CMultiDocTemplate. Визначає шаблон документу для багато-документного інтерфейсу. В MDI-програмах основна рамка використовується як робоче місце, в якому користувач може відкрити довільну кількість документів одного чи різних типів.

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

 

HMENU CMultiDocTemplate::m_hMenuShared;

HACCEL CMultiDocTemplate::m_hAccelTables;

 

Для збереження списку одночасно відкрити документів використовується захищений член:

 

CPtrList CMultiDocTemplate::m_docList;

 

Доступ до елементів цього списку виконується через методи GetFirstDocPosition та GetNextDoc.

Конструктор класу має такі ж самі параметри як і конструктор базового класу.

При реєстрації та зв’язування документу, рамки та вигляду в SDI-програмі застосовується метод AddDocTemplate класу CWinApp. Нижче наведено приклад уривку коду функції InitInstance в якому реєструється два різних шаблона для MDI-програми.

 

CmulteDocTemplate* pDocTemplate;

// створення об’єкту шаблону для роботи з текстом

pDocTemplate =newCMultiDocTemplate( IDR_NOTETYPE,

RUNTIME_CLASS(CNoteDoc),

RUNTIME_CLASS(CNoteFrame),

RUNTIME_CLASS(CNoteView));

// додавання шаблону до списку

AddDocTemplate(pDocTemplate);

 

// створення об’єкту шаблону для роботи з текстом

pDocTemplate =newCMultiDocTemplate( IDR_DRAWTYPE,

RUNTIME_CLASS(CDrawDoc),

RUNTIME_CLASS(CDrawFrame),

RUNTIME_CLASS(CDrawView));

// додавання шаблону до списку

AddDocTemplate(pDocTemplate);

 

Документ та його вигляд.

Основним достоїнством архітектури „Документ/Вигляд” є розділення даних та їх відображення. Довільні зміни даних здійснюються через спеціальний клас документа, який забезпечує:

- необхідний простір для збереження даних в пам’яті;

- читає та записує дані на диск;

- забезпечує інтерфейс для доступу та поновлення даних.

Відображення даних на екрані, вивід даних на друк чи інший пристрій забезпечує спеціальний клас CView чи похідний від нього. Клас вигляду є вікном, що з одної сторони взаємодіє з користувачем а з другої – організовує доступ до інтерфейсної частини документу.

Типова схема створення документу представлено на рис. __.

 

 

рис. __.Схема дій при створенні документу

 

 

Документ. Базовим класом для створення документів розробника є CDocument. У нього закладено типові функціональні можливості, що можуть знадобитися при роботі з документами довільних типів, такі як відкриття/закриття файлу, читання/запис даних у файл, зв’язок з виглядом (виглядами). Бібліотека MFC працює з документом використовуючи наперед визначений інтерфейс.

Об’єкти класу CDocument отримують команди від елементів керування інтерфейсу користувача в першу чергу. Якщо вони деяких з них не обробляють, то передають далі на обробку до шаблону.

До основних методів цього класу, що найчастіше використовуються, можна віднести:

 

const CString& CDocument::GetPathName()

- повертає шлях до файлу документу.

 

virtual void CDocument::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU = TRUE)

- встановлює новий шлях до файлу документу та при необхідності добавляє його до списку часто використовуваних документів програми.

 

BOOL CDocument::IsModifed()

- дозволяє визначити чи документ був змінений після останнього збереження.

 

void CDocument::SetModifedFlag(BOOL bModifed = TRUE)

- дозволяє позначити документ як змінений.

 

void CDocument::AddView(CView *pView)

- приєднує новий вигляд до документу.

 

void CDocument::RemoveView(CView *pView)

- від’єднує заданий вигляд від документу.

 

virtual POSITION CDocument::GetFirstViewPosition()

- повертає структуру для початку пошуку виглядів, що асоціюються з документом.

 

virtual CView* CDocument::GetNextView(POSITION &rPosition)

- повертає вигляд з наступної позиції в списку, що асоціюються з документом.

 

Наступні віртуальні функції викликаються з MFC в процесі роботи з документом. Їх назви розкривають їхнє призначення.

 

virtual void CDocument::OnNewDocument();

virtual void CDocument::OnOpenDocument();

virtual void CDocument::OnSaveDocument();

virtual void CDocument::OnCloseDocument();

 

Перевизначивши дані методи можна забезпечити гнучке та детальне керування документом.

 

Вигляд. Для відображення документів у MFC створена спеціальна група класів, що забезпечують створення та управління дочірніми вікнами в яких зображується вміст документу. Базовим класом для них, як показано на рис. __ є CView.

 

 

 

Рис. __. Ієрархія класів виглядів документу

 

 

На відміну від документу, що може мати декілька виглядів одночасно, вигляд асоціюється тільки з одним документом. Для одного документу можна створити декілька рамок з виглядами або розділити одну рамку між декількома виглядами: однотипними чи різнотипними. Усі перераховані можливості надаються бібліотекою MFC.

Для прикладу розглянемо основні методи, що реалізовано в базовому класі виглядів CView. В інших класах, реалізовано додаткові методи, що відображають специфіку представлення в них інформації.

У класах вигляду, окрім конструктора, найчастіше використовуються методи:

 

CDocument* CView::GetDocument()

- повертає вказівник на документ, що асоціюються з виглядом.

 

virtual void CView::OnInialUpdate()

- викликається один раз коли вигляд приєднується до документу. В ньому проводиться первинна ініціалізація класу вигляду.

 

virtual void CView::OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint)

- викликається документом, щоб повідомити вигляду, що в ньому відбулися зміни.

 

virtual void CView::OnActivateView(BOOL bActivate,

CView *pActivateViev, CView *pDeactivateViev)

- викликається з MFC, коли вигляд активується (отримує фокус вводу) чи деактивується (втрачає фокус вводу).

 

virtual void CView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)

- викликається з MFC при прокрутці даних у вигляді.

 

Клас CView містить одну чисто-віртуальну функцію OnDraw, яка власне і відповідає за промальовування документу на екрані або іншому пристрої.

 

virtual void CView:: OnDraw (CDC *pDC) = 0

 

Її необхідно обов’язково перевизначити при створення класу нащадку.

Інші базові класи вигляду забезпечують специфічний інтерфейс для представлення даних у вигляді: тексту - CEditView; списку - CListView; дерева - CTreeView. У MFC реалізовано також і вигляди з розширеними можливостями.

 

Документ та його вигляд.

4. Програми на основі діалогу.