Этот пример демонстрирует наиболее эффектную сторону технологии документ-вид. Будем дальше развивать проект.
Добавляем описание для класса разделителя.
.................
#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;
}
А вот и результат работы.
Обратите внимание на то, что обработка сообщения от меню 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;
}