- •Implement_dyncreate(cApplView, cFormView)
- •Void cApplView::OnEndPrinting(cdc* /*pDc*/, cPrintlnfo* /*plnfo*/)
- •Void cApplView::OnPrint(cdc* pDc, cPrintlnfo*)
- •Implement_dyncreate(cMainFrame, cFrameWnd)
- •Int cMainFrame::OnCreate(lpcreatestruct ipCreateStruct)
- •Idr_app2type,
- •Int cMainFrame: :OnCreate(lpcreatestruct lpCreateStruct)
7
SDI И MDI ПРИЛОЖЕНИЯ
Мастер приложений AppWizard позволяет создавать шаблоны для приложений трех типов:
• Single document - приложения с SDI-интерфейсом;
• Multile documents - приложения с MDI-интерфейсом;
• Dialog based - приложения, основанные на диалоговой форме. Процесс создания шаблона приложения, основанного на диалоговой
форме, и дальнейшая разработка сформированного шаблона были рассмотрены в гл. 5. Данная глава будет посвящена механизмам разработки приложений, построенных на основе SDI (Single Document Interface) или MDI (Multiple Document Interface) интерфейса. Будем называть приложения, использующие SDI или MDI интерфейс, соответственно SDI-приложением и MDI-приложением. Такие приложения относятся к приложениям с архитектурой документ-отображение (document/view).
Приложение с архитектурой документ-отображение может содержать несколько классов документов, отображений и окон-рамок. Причем с одним документом может быть соотнесено несколько различных классов для отображения.
Все MFC-приложения имеют как минимум два объекта: объект приложение, производный от класса CWinApp, и объект главное окно, произвольный от класса CWnd или его потомков - классов CFrameWnd, CMDIFrameWnd и CDialog.
Приложения с архитектурой документ-отображение содержат объекты как минимум трех следующих классов (или производных от них классов):
• CWinApp - объект приложение;
• CDocument - объект документ;
• CView - объект отображение документа.
Объект документ отвечает за внутреннее представление данных, показываемых объектом отображения. Объект отображение предназначен для манипулирования данными объекта документа. Объект отображение состыковывается с объектом документ и окном-рамкой, образуя цепочку документ->отображение->окно.
В каждом приложении создается один-единственный объект приложения. Этот объект является объектом класса CWinApp или производного от него класса.
Более подробно классы, используемые для построения приложений с архитектурой документ/отображение, рассматриваются в гл. 6.
Создание шаблона SDI-приложения
Мастер приложений AppWizard позволяет последовательно формировать шаблон приложения, включая или не включая в него поддержку таких элементов, как доступ к информации из баз данных, реализация возможностей контейнера или сервера, применение OLE, использование элементов ActiveX, a также реализацию встроенной панели инструментов, строки состояния, некоторых пунктов меню. В приложении "Реализация OLE-приложений" приведен пример создания средствами AppWizard двух приложений, одно из которых может функционировать как OLE-контейнер, а другое - как OLE-сервер.
Для того чтобы создать шаблон приложения, можно выполнить пункт меню File | New и выбрать на вкладке Project разработку проекта как MFC AppWizard (exe).
AppWizard отобразит диалоговое окно (рис. 7.1), в котором следует указать тип создаваемого шаблона Single document, - шаг 1.
Рис. 7.1. Формирование шаблона SDI-приложения: шаг 1
Далее, шаг 2, AppWizard предложит определить (рис. 7.2), нужна ли поддержка для работы с информацией из баз данных.
Рис. 7.2. Формирование шаблона SDI-приложения: шаг 2
На третьем шаге определяется, будет ли создаваемое приложение поддерживать реализацию контейнера (рис. 7.4) или сервера. Чтобы не усложнять программный код формируемого шаблона приложения, в данном разделе будет рассмотрено приложение, не использующее составных документов (рис. 7.3).
Рис. 7.3. Формирование шаблона SDI-приложения: шаг 3
Рис. 7.4. Формирование шаблона SDI-приложения, реализующего контейнер
Контейнеры используются для поддержки связи и встроенных объектов На четвертом шаге (рис. 7.5) определяется внешний вид окна приложения, а также то, следует ли добавлять такие черты, как встроенная панель инструментов, строка состояния, пункты меню, для печати и предварительного просмотра документа.
На пятом шаге (рис. 7.6) определяется, следует ли вставлять в создаваемый программный код комментарии и каким образом использовать MFC-библиотеку: как разделяемую DLL или линковать, как статическую библиотеку.
Рис. 7.5. Формирование шаблона SDI-приложения: шаг 4
Рис. 7.6. Формирование шаблона SDI-приложения: шаг 5
На шестом шаге (рис. 7.7) можно определить, какие базовые классы следует использовать для автоматически создаваемых производных классов, а также имена заголовочных файлов и файлов реализации. Для разрабатываемого шаблона SDI-приложения список создаваемых классов содержит следующие классы:
• CApplApp - производный класс от класса приложения САрр;
• CMainFrame - класс рамки окна;
• САрр 1 Doc - класс документа (производный от CDocument);
• CApplView - класс отображения (производный от CView).
На рис. 7.7 показан список классов, из которых можно выбрать базовый класс для создаваемого производного класса отображения CApplView.
Рис. 7.7. Формирование шаблона SDI-приложения: шаг 6
Перед окончательной генерацией создаваемого программного кода AppWizard отображает окно (рис. 7.8) с информацией о создаваемых файлах и основных поддерживаемых характеристиках проекта.
Рис. 7.8. Информация о создаваемом проекте
Выполняя генерацию формируемого шаблона приложения, AppWizard создаст новый подкаталог, в который поместит все файлы проекта, и откроет окно проекта.
На рис. 7.9 представлены две вкладки окна проекта, отображающие список файлов проекта и список всех классов проекта.
Рис. 7.9. Список файлов и список классов проекта
В результате выполненных действий AppWizard создаст для каждого класса заголовочный файл (с расширением .Н) и файл реализации (с расширением .СРР).
Далее приводится автоматически созданный AppWizard программный код SDI-приложения с некоторыми сокращениями и поясняющими комментариями.
Листинг файла Appl.cpp:
// Appl.cpp : Defines the class behaviors for the application. // Файл реализации Appl.cpp определяет класс приложения
// оператор #include для следующих заголовочных файлов:
// "stdafx.h" "Appl.h" "MainFrm.h" "ApplDoc.h" "ApplView.h"
///////////////////////////////////////////////////////////////////////////////
//CApplApp
// Таблица сообщений
BEGIN_MESSAGE_MAP(CApplApp, CWinApp)
//{{AFX_MSG_MAP(CApplApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
else
{ // TODO: место для добавления кода загрузки } }
////////////////////////////////////////////////////////
// CApplDoc diagnostics
#ifdef_DEBUG
void CApplDoc::AssertValid() const
{ CDocument::AssertValid(); }
void CApplDoc::Dump(CDumpContext& dc) const
{ CDocument::Dump(dc); }
#endif//_DEBUG
/////////////////////////////////////////////////////////// Листинг файла ApplView.cpp;
// ApplView.cpp .-реализация класса CApplView
#undefTHIS_FILE
static char THIS_FILE[] = _FILE__;
#endif
Implement_dyncreate(cApplView, cFormView)
// Таблица сообщений
BEGIN_MESSAGE_MAP(CApplView, CFormView)
//{{AFX_MSG_MAP(CApplView)
// ClassWizard будет здесь добавлять и удалять входы таблицы сообщений // DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CFormView:rOnFiiePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview) END_MESSAGE_MAP()
///////////////////////////////////////////////////// // CApplView construction/destruction (конструктор/деструктор класса) CApplView::CApplView() : CFormView(CApplView::IDD) { //{{AFX_DATAJNIT(CApplView)
// NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // TODO: место для добавления кода }
CApplView::~CApplView() {}
void CApplView::DoDataExchange(CDataExchange* pDX) // Обмен данным {
CFormView:: DoDataExchange(pDX); //{{AFX_DATA_MAP(CApplView)
// ClassWizard будет вставлять здесь вызовы DDX и DDV методов //}}AFX_DATA_MAP
}
BOOL CApplView::PreCreateWindow(CREATESTRUCT& cs)
{ // TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
// Здесь можно модифицировать CREATESTRUCT
return CFormView::PreCreateWindow(cs); }
////////////////////////////////////////////////////////// // CApplView printing (методы обработки сообщений о печати) BOOL CApplView::OnPreparePrinting(CPrintInfo* plnfo) { return DoPrt;parePrinting(pInfo); }
void CApplView::OnBeginPrinting(CDC* /*pDC*/, CPrintlnfo* /*plnfo*/) { // TODO: можно добавить действия, выполняемые перед печатью
}
Void cApplView::OnEndPrinting(cdc* /*pDc*/, cPrintlnfo* /*plnfo*/)
{ // TODO: можно добавить действия, выполняемые при завершении печати
}
Void cApplView::OnPrint(cdc* pDc, cPrintlnfo*)
{ // TODO: здесь добавляется код для управления печатью
}
///////////////////////////////////////////////////
// CApplView diagnostics
#ifdef_DEBUG
void CApplView::AssertValid() const
{ CFormView: :AssertValid(); } void CApplView::Dump(CDumpContext& dc) const { CFormView::Dump(dc); } CApplDoc* CApplView::GetDocument() // non-debug version is inline
{ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CApplDoc)));
return (CApplDoc*)m_pDocument; } #endif//_DEBUG
Листинг файла MainFrm.cpp
// MainFrm.cpp реализация класса CMainFrame
#undefTHIS_FILE
static char THIS_FILE[] = _FILE__;
#endif
Implement_dyncreate(cMainFrame, cFrameWnd)
// Таблица сообщений
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code !
ON_WM_CREATE()
//}}AFX_MSG_MAP END_MESSAGE_MAP() static UINT indicators!] = { ID_SEPARATOR, //status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
Illllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// CMainFrame construction/destruction (конструктор/деструктор класса)
CMainFrame::CMainFrame()
{ // TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{}