Шаг 22 - Организуем связь Документ-Вид

  " Войди в меня , войди в мои сны
Войди в мои сны они так важны "
Ирина Алегрова
К Документ - Вид подходит очень :-).

Создание проекта

Будем работать с проектом, созданным в прошлом шаге.

Создаем код

Добавим функцию получения данных и сами данные к классу документа.

class CMyDoc : public CDocument	  // класс документа
{
protected:
CMyDoc();
CString csDate; // здесь будем хранить
DECLARE_DYNCREATE(CMyDoc)
public:
CString GetDate(); // получить данные
};

Реализация.

CMyDoc::CMyDoc()
{
csDate="Hello View - Doc"; // устанавливаем данные
}
CString CMyDoc::GetDate()
{
return csDate; // выдаем
}

В классе вида нужно создать функцию доступа к классу документа.

class CMyView : public CView	// класс просмотр
{
protected:
CMyView(); CMyDoc* GetDocument(); // получить документ
DECLARE_DYNCREATE(CMyView) // Эта функция вызывается для прорисовки вида
public:
virtual void OnDraw(CDC* pDC);
};

Реализуем ее.

CMyDoc* CMyView::GetDocument()
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc))); // проверить есть ли класс документа
return (CMyDoc*)m_pDocument; // вернуть результат.
}

Вот сейчас проект не соберется. Вот такие ошибки будут.

Compiling...
step22.cpp
D:\VС\step22\step22.cpp(14) : error C2143: syntax error : missing ';' before '*'
D:\VС\step22\step22.cpp(14) : error C2501: 'CMyDoc' : missing storage-class or type specifiers

Это связанно с тем, что у нас класс документа объявлен ниже класса вида по тексту cpp файла. И класс вида просто не знает про него. Для решения этой проблемы мы просто перенесем описание класса документа выше описания класса вида.

#include "afxwin.h"    // это для MFC
#include "resource.h" // идентификаторы ресурсов
class CMyDoc : public CDocument // класс документа
{
............
};
class CMyView : public CView // класс просмотр
{
.............
};

Ну и изменим функцию рисования вида.

void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* tempDoc=GetDocument(); //получить класс документа
pDC->TextOut(10,10,tempDoc->GetDate()); //вывести строку на экран из документа
}

Вот так выглядит наша программа в работе.

22_1.gif (1439 b)

Описание

В классе документа должны находится данные. Вот мы их и объявили в виде строки CString csDate. Так как данные должны быть защищены, то я их поместил в private:. Это соответствует классическим правилам объектно-ориентированного программирования. Доступ к данным только через функции. Для доступа создал функцию CString GetDate(). С ней я думаю просто, она возвращает строку.

Вид должен иметь возможность доступа к докумнту. Для этого создана функция СMyDoc* GetDocument(); в классе вида. Она возвращает указатель на класс документа. Именно указатель нам и нужен. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc))); - в общем по русски это так. Проверить принадлежность указателя m_pDocument на принадлежность классу CMyDOC IsKindOf(RUNTIME_CLASS(CMyDoc)) и проверить, чтобы этот класс существовал ASSERT(.....) .Если все нормально вернуть указатель на класс документа - return (CMyDoc*)m_pDocument;

Мы изменили функцию прорисовки OnDraw. В этой функции мы получаем класс документа и выводим на экран строку.

Так вот, вникайте. Если вы захотите изменить вывод допустим шрифт букв, или место строки, то за всё это отвечает класс просмотра CView, а если необходимо изменить содержание строки то это делается в классе документа CDocument.

Шпаргалка

В классе документа создай данные и доступ к ним.

class CMyDoc : public CDocument	  // класс документа
{
protected:
.......
CString csDate; // здесь будем хранить
...........
public:
CString GetDate(); // получить данные
};

В классе вида реализуй доступ к классу документа.

class CMyView : public CView	// класс просмотр
{
........
CMyDoc* GetDocument(); // получить документ
..........
};
CMyDoc* CMyView::GetDocument()
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc))); // проверить есть ли класс документа
return (CMyDoc*)m_pDocument; // вернуть результат.
}

Напиши код в функции рисования вида.

void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* tempDoc=GetDocument(); //получить класс документа
pDC->TextOut(10,10,tempDoc->GetDate()); //вывести строку на экран из документа
}

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 13.09.99 (обновлено 1.07.2001)