Шаг 24 - Несколько видов для документа

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

Этот пример демонстрирует наиболее эффектную сторону технологии документ-вид. Будем дальше развивать проект.

Создаем код

Добавляем описание для класса разделителя.

.................
#include "afxwin.h" // это для MFC
#include "afxext.h" // это для дополнительных возможностей
#include "resource.h" // идентификаторы ресурсов
class CMyDoc : public CDocument // класс документа
...............

Создаем еще один класс вида.

class CNewView : public CView		// еще один класс вида
{
protected:
CNewView();
DECLARE_DYNCREATE(CNewView)
public:
void OnDraw(CDC* pDC);
CMyDoc* GetDocument();
};
CMyDoc* CNewView::GetDocument()
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
void CNewView::OnDraw(CDC* pDC)
{
CMyDoc* tempDoc=GetDocument();
pDC->SetTextColor(RGB(255,0,0)); // установить красный цвет
pDC->TextOut(10,10,tempDoc->GetDate()); // вывести
}
IMPLEMENT_DYNCREATE(CNewView, CView)
CNewView::CNewView()
{
}

Добавляем описания класса и процедур для создания разделителя.

class CMainFrame : public CFrameWnd	// класс рамки окна
{
protected: CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
public:
virtual BOOL OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext ); // создать клиента
CSplitterWnd m_wndSplitter; // разделитель

};

Реализация.

BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext )
{
ASSERT(m_wndSplitter.CreateStatic(this,1,2)); // создать разделитель
ASSERT(m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyView), // создать первый вид
CSize(100,50),pContext));
ASSERT(m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CNewView), // создать второй вид
CSize(100,50),pContext));
SetActiveView((CView*)m_wndSplitter.GetPane(0,1)); // установить активную панель
return TRUE;
}

А вот и результат работы.

24_1.gif (8837 b)

Описание

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

Описания класса разделителя нет в afxwin.h. Поэтому мы и подключили afxext.h где он есть. Логично? Создали второй класс просмотра, он совершенно аналогичен CMyView за исключением функции рисования. В ней текст выводится красным цветом. Для использования объявляем в классе рамки окна, объект класса разделитель CSplitterWnd.

OnCreateClient функция ответственна за создание клиента рамки окна, т.е. внутреннего наполнения рамки. Вот мы и устанавливаем наполнения, как создаем разделитель m_wndSplitter.CreateStatic(this,1,2), который вставляется в рамку (this) и состоит из двух частей 1,2. К каждой части привязываем просмотр m_wndSplitter.CreateView, указывая класс просмотра, размер и т.д. В самом конце устанавливаем номер активной панели и сообщаем MFC о успешности нашей работы.

Две панели с текстом разного цвета. Выберите пункт меню About и текст поменяется сразу в двух панелях. А теперь фантазию надо применить. Где это используется. В Excel точно для просмотра частей таблицы, можно графику просматривать с разными масштабами и т.д.

Шпаргалка

Включить дополнения.

#include "afxext.h"	  // это для дополнительных возможностей

Включить описание класса разделителя в класс рамки окна.

class CMainFrame : public CFrameWnd	// класс рамки окна
{
..........
CSplitterWnd m_wndSplitter; // разделитель
};

Создать классы видов, сколько вы хотите.

Переопределить функцию OnCreateClient.

class CMainFrame : public CFrameWnd	 // класс рамки окна	
{
............
virtual BOOL OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext ); // создать клиента
};

И реализовать разделители.

BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext )
{
ASSERT(m_wndSplitter.CreateStatic(this,1,2)); // создать разделитель
ASSERT(m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyView), // создать первый вид
CSize(100,50),pContext));
ASSERT(m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CNewView), // создать второй вид
CSize(100,50),pContext));
SetActiveView((CView*)m_wndSplitter.GetPane(0,1)); // установить активную панель
return TRUE;
}

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