Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual2.doc
Скачиваний:
5
Добавлен:
07.03.2016
Размер:
3.31 Mб
Скачать

9.3.4. Робота з документами та видами на прикладі додатку SingleTemplate

Приклад знаходиться у папці DISK\Structure\SingleTemplate.

Створимо приклад під назвою SingleTemplate, у якому буде 2 класи документів, 3 класи виду і один клас виду зі скролінгом. На рис. 9.12 наведено схему підключення класів вікон у додатку SingleTemplate.

Рис. 9.12. Схема підключення класів вікон додатку SingleTemplate

Програмний код класів можна знайти у комп’ютерній мережі інституту на inf-srv.

Створимо клас CScroll:

class CScroll : public CScrollView

{

.............................................................

};

Вікно класу CScroll похідне від класу CScrollView може виступати як дочірнє вікно при підключенні до окремого клієнтського вікна. У якості клієнтського вікна виберемо клас CFrameWnd. Додамо функцію OnClient в клас CMainFrame, для створення вікна зі скролінгом:

void CMainFrame::OnClient()

{

CRect rect;

GetWindowRect(&rect);

rect.OffsetRect(20,80);

CFrameWnd*fw = new CFrameWnd;

fw->CreateEx(NULL,NULL, "Скроллинг",

WS_VISIBLE|WS_OVERLAPPEDWINDOW,rect, this, 0);

CScroll*scr = new CScroll;

scr->Create(NULL,

NULL,

AFX_WS_DEFAULT_VIEW,

rectDefault,

fw,

AFX_IDW_PANE_FIRST,

NULL);

scr->OnInitialUpdate();

fw->RecalcLayout();

}

Функцію OnInitialUpdate необхідно визвати після створення вікна скролінгу, так як у ній обчислюються настройки, потрібні для правильного відображення скролінгу. Без виклику цієї функції програма не буде працювати. Якщо вікно скролінга створюється майстром, то ця функція знаходиться у секції protected, в такому випадку її необхідно самостійно перенести у public. Код самої функції необхідно також редагувати, так як створена майстром функція не обчислює розміри вікна. Обчислення розмірів вікна можна побачити нижче:

void CScroll::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();

CSize sizeTotal;

// TODO: calculate the total size of this view

CRect rect;

int chir_s, dlina;

chir_s = GetDC()->GetTextExtent("1",1).cx;

dlina = GetDC()->GetTextExtent(str).cx + 10;

// Організація скролінгу

GetClientRect(&rect);

CSize clientSize(rect.right,rect.bottom);

CSize docSize(dlina,20*100);

CSize unitSize(chir_s,20);

SetScrollSizes(MM_TEXT,docSize,clientSize,unitSize);

}

Позначимо ширину символу змінною chir_s, а ширину вікна змінною dlina. Значення ширини тексту визначимо функцією GetTextExtent, з необхідними параметрами. До значення ширини вікна додаємо значення 10, необхідне для відступів. Потім задаємо класи розмірів CSize, необхідні для функції SetScrollSizes. Змінна docSize визначає розмір всього документа, а unitSize – розміри переміщення вікна при прокрутці скролінгу. Змінна clientSize відповідає за розміри клієнтського вікна, які визначаються через функцію GetClientRect.

Клас документа CDpredDoc перейменуємо на CDpredDoc0, і також створимо ще один клас документа CDpredDoc1. В ці класи додамо змінні str типу CString:

class CDpredDoc0 : public CDocument

{

.............................................................

CString str;

.............................................................

};

class CDpredDoc1 : public CDocument

{

.............................................................

CString str;

.............................................................

};

Присвоєння значень змінних відбувається у конструкторах класів:

CDpredDoc0::CDpredDoc0()

{

str = "Документ 0";

}

CDpredDoc1::CDpredDoc1()

{

str = "Документ 1";

}

Додамо функції OnDoc0 та OnDoc1 для переключення класів документів:

void CMainFrame::OnDoc0()

{

if(per_doc == 0)return;

per_view= 0;

per_doc = 0;

CSingleDocTemplate* pDocTemplate =

((CDpredApp*)AfxGetApp())->pDocTemplate;

CDocument*p_doc_vrem = GetActiveDocument();

CView*p_view_vrem = GetActiveView();

//Спочатку видалення активного документу

pDocTemplate->RemoveDocument(p_doc_vrem);

CDpredDoc0 *p_doc0 = new CDpredDoc0;

CDpredView0*p_view0 = new CDpredView0;

p_view0->Create(NULL,

NULL,

AFX_WS_DEFAULT_VIEW,

rectDefault,

this,

AFX_IDW_PANE_FIRST,

NULL);

p_doc0->AddView(p_view0);

pDocTemplate->AddDocument(p_doc0);

SetActiveView(p_view0);

// Спочатку видалення документу, а потім виду

delete p_doc_vrem;

delete p_view_vrem;

RecalcLayout();

}

void CMainFrame::OnDoc1()

{

if(per_doc)return;

per_doc = 1;

CSingleDocTemplate* pDocTemplate;

pDocTemplate = ((CDpredApp*)AfxGetApp())->pDocTemplate;

CDocument*p_doc_vrem = GetActiveDocument();

CView*p_view_vrem = GetActiveView();

pDocTemplate->RemoveDocument(p_doc_vrem);

CDpredDoc1 *p_doc1 = new CDpredDoc1;

CDpredView2*p_view2 = new CDpredView2;

p_view2->Create (NULL,

NULL,

AFX_WS_DEFAULT_VIEW,

rectDefault,

this,

AFX_IDW_PANE_FIRST,

NULL);

p_doc1->AddView(p_view2);

pDocTemplate->AddDocument(p_doc1);

SetActiveView(p_view2);

// Спочатку видалення документу, а потім виду

delete p_doc_vrem;

delete p_view_vrem;

RecalcLayout();

}

При підключенні класу документа CDpredDoc0, значення змінної per_doc=0, а при іншому документі per_doc=1. Ця змінна вводиться для з’ясування, який документ відкритий, і якщо відкритий документ CDpredDoc0, то можна змінювати підключене до нього вікно виду (CDpredView0 або CDpredView1). Функціями GetActiveDocument та GetActiveView ми отримуємо вказівки на активні класи документу та виду. Функцією класу шаблону RemoveDocument видаляємо клас активного документа з шаблону. Потім створюємо нові класи документа і виду, додаємо документ до шаблону і робимо активним вікно виду. На наступному етапі видаляємо об’єкти старих класів документа і виду (p_doc_vrem та p_view_vrem, які були активними на початку роботи функції). Видаляти потрібно спочатку клас документа, а лише потім клас виду!

У функціях OnView0 та OnView1 буде відбуватися зміна вікна виду, підключеного до активного документа CDpredDoc:

void CMainFrame::OnView0()

{

if(per_view==0)return;

if(per_doc)return;

per_view=0;

CView* p_view_vrem = GetActiveView();

CDpredView0* p0 = new CDpredView0;

p0->Create(NULL,

NULL,

AFX_WS_DEFAULT_VIEW,

rectDefault,

this,

AFX_IDW_PANE_FIRST,

NULL);

GetActiveDocument()->AddView(p0);

GetActiveView()->ShowWindow(SW_HIDE);

GetActiveDocument()->RemoveView(GetActiveView());

SetActiveView(p0);

//Видалення об’єкту View

delete p_view_vrem;

RecalcLayout();

}

void CMainFrame::OnView1()

{

if(per_view==1)return;

if(per_doc)return;

per_view=1;

CView* p_view_vrem = GetActiveView();

CDpredView1* p1 = new CDpredView1;

//Вказівка на документ

p1->pDoc = (CDpredDoc0*)GetActiveDocument();

p1->Create(NULL,

NULL,

AFX_WS_DEFAULT_VIEW,

rectDefault,

this,

AFX_IDW_PANE_FIRST,

NULL);

GetActiveDocument()->AddView(p1);

GetActiveView()->ShowWindow(SW_HIDE);

GetActiveDocument()->RemoveView(GetActiveView());

SetActiveView(p1);

//Видалення об’єкту View

delete p_view_vrem;

RecalcLayout();

}

На екран виводиться змінна str, яка береться із відповідного класу документа, а також номер вікна виду. Наведемо функції OnDraw вікон виду:

void CDpredView0::OnDraw(CDC* pDC)

{

CDpredDoc0* pDoc = GetDocument();

pDC->TextOut (10,10,pDoc->str + " Представление 0");

}

void CDpredView1::OnDraw(CDC* pDC)

{

pDC->TextOut (10,10,pDoc->str + " Представление 1");

}

void CDpredView2::OnDraw(CDC* pDC)

{

CDpredDoc1* pDoc = (CDpredDoc1*)GetDocument();

pDC->TextOut (10,10,pDoc->str + " Представление 2");

}

У даному фрагменті слід звернути головну увагу на отримання доступу до даних документа з кожного окремого виду. У функції OnDraw з 1-го виду CDpredView0 вказівка на документ отримується через функцію GetDocument яка створюється самостійно при розробці проекту:

CDpredDoc0* pDoc = GetDocument();

У функції OnDraw з 2-го виду CDpredView1 вказівка на документ отримується при переключенні на цей вид функцією OnView1 класу:

p1->pDoc = (CDpredDoc0*)GetActiveDocument();

У функції OnDraw з 3-го виду CDpredView2 вказівка на документ отримується за допомогою приведення функції GetDocument класу CDocument до класу документу з якого необхідно отримати дані:

CDpredDoc1* pDoc = (CDpredDoc1*)GetDocument();

Приклад додатку SingleTemplate приведено на рис. 9.13:

Рис. 9.13. Вікно додатку SingleTemplate, з відкритим документом 0-м та клієнтським вікном скролінга

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]