В этом разделе рассматривается программа использующая MDI ( интерфейс многих документов )
Мы создадим программу, в которой документом является графическое изображение - круг.
В ToolBar будет создана иконка, при нажатие на которою будет вызываться диалоговое
окно, позволяющее изменять координаты круга. Местоположение круга можно будет согранять в
файл с расширением CIR.
Создание проекта программы
1. Создайте новый проект( у меня MDI ), использующая MDI интерфейс с поддержкой MFC. Все
шесть шагов в MFC AppWizard оставте без изменения.
2. Если вы сделали всё правильно, то создадутся пять классов : CMDIApp, CMainFrame,
CChildFrame, CMDIDoc и CMDIView. В классе документов CMDIDoc вы пишите код
для поддержки данных программы, а в классе представления CMDIView - код, отвечающий
за то, что вы видите на экране. Вы будете писать код в функциях-элементах только этих двух
классов.
3. Объявляем элементы данных класса документа. Их будет два : координаты круга по X
и по Y. Для этого открываем файл CMDIDoc.h и изменяем объявление класса
CMDIDoc следующим образом:
class CMDIDoc : public CDocument
{
protected: // create from serialization only
CMDIDoc();
DECLARE_DYNCREATE(CMDIDoc)
// Attributes
public:
int m_X; // координаты круга по x
int m_Y; // координаты круга по y
// Operations
...
...
4. Объявляем элементы данных класса представления. Их будет тоже два : координаты круга
по X и по Y. Для этого открываем файл CMDIView.h и изменяем объявление
класса CMDIView следующим образом:
class CMDIView : public CView
{
protected: // create from serialization only
CMDIView();
DECLARE_DYNCREATE(CMDIView)
// Attributes
public:
CMDIDoc* GetDocument();
int m_X; // координаты круга по x
int m_Y; // координаты круга по y
// Operations
...
...
Как вы видите, имена переменных могут совпадать( обычно так и делается ).
5. Инициализируем элементы данных класса документа. Для этого откройте файл MDIDoc.cpp,
найдите в нём функцию OnNewDocument() и напишите в ней следующий код:
BOOL CMDIDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
m_X = 100; // начальное положение по X=100
m_Y = 100; // начальное положение по Y=100
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
6. Инициализируем элементы данных класса представления. Для этого нужно создать
функцию-элемент OnInitialUpdate() класса представления:
Выберите ClassWizard в меню View. На странице Message Maps
выберите следующие события:
Class neme : CMDIView
Object ID : CMDIView
Message : OnInitialUpdate
и нажмите на кнопку Add Function
Напишите следующий код в функцию OnInitialUpdate():
void CMDIView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
CMDIDoc* pDoc = GetDocument(); // получить указатель на документ
// обновить элементы данных представления
// соответствующими значениями документа.
m_X = pDoc->m_X;
m_Y = pDoc->m_Y;
pDoc->SetTitle("ANDY"); // всем документам даётся название ANDY
}
7. Теперь напишем код для вывода круга на экран.
Функция OnDraw() класса представления автоматически выполняется всякий раз, когда
нужно вывести окно документа.
Напишите следующий код в функции OnDraw() :
void CMDIView::OnDraw(CDC* pDC)
{
CMDIDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->Ellipse(m_X - 20, m_Y - 20, m_X + 20, m_Y + 20); // рисуем круг диаметром 20
}
8. Напишем код для сохранения и считывания данных из файла.
Откройте файл MDIDoc.cpp, найдите в нём функцию Serialize() и измените её:
void CMDIDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here( это выполняется если выбрать SAVE )
ar<<m_X; // записываем m_X в выбранный файл
ar<<m_Y; // записываем m_Y в выбранный файл
}
else
{
// TODO: add loading code here ( это выполняется если выбрать OPEN )
ar>>m_X; // считываем значение из выбранного файла в m_X
ar>>m_Y; // считываем значение из выбранного файла в m_Y
}
}
9. Часто бывает нужно изменить некоторые параметры программы, такие как заголовок
главного окна или тип файла по умолчанию, который выводится в диалоговых панелях
SAVE и OPEN. Для этого нужно выбрать закладку ResourceView и
открыть пункт String Table. Вы увидите список переменных проекта( три колонки :
ID, Value и Caption ).
IDR_MAINFRAME - заголовок главного окна (изменяется в поле Caption)
IDR_MCIRCLTYPE - тип файла по умолчанию, вы увидите 6 подстрок разделёнными
знаком \n. Третья и четвёртая подстроки определяют тип документа по умолчанию. У меня
CIR FILES( *.cir ) и .cir соответственно. Вы можете поставить свои значения.
10. Теперь создадим кнопку в панеле инструментов. Для этого нужно выбрать закладку ResourceView и
открыть пункт Toolbar. Вы увидите панель инструментов в режиме редактирования. Нажмите
на самую правую кнопку( пунктирный квадрат ), ниже нарисуйте кнопку по вашему усмотрению. Теперь дважды
нажмете на вашу кнопку и введите ID: ID_MYBUTTON и Prompt: Изменение координат круга\nИзменение
координат круга. Ну вот и всё, кнопка готова. Теперь нужно создать функцию, которая будет
выполняться при нажатии на вашу кнопку :
Выберите пункт меню View далее ClassWizard, выберите закладку Message Maps,
Project: MDI, Class name: CMDIView, Object IDs: ID_MYBUTTON, Message: COMMAND и нажмите на
кнопку Add Function. В ответ создастся функция void CMDIView::OnMybutton().
11. Теперь по аналогии с главой 15 создадим собственное диалоговое окно с ID: IDD_MY_DIALOG и
классом CMyDialog и разместим в нём четыре Edit Box с переменными типа INT:
m_DX - текущая позиция по X, m_DY - текущая позиция по Y, m_DXN - новая позииция по X,
m_DYN - новая позииция по Y. Не забудте написать #include "MyDialog.h" в
файлах MDIDoc.cpp и MDIView.cpp.
12. Теперь напишем код в функцие OnMybutton().
void CMDIView::OnMybutton()
{
// TODO: Add your command handler code here
CMDIDoc* pDoc = GetDocument(); // получаем указатель на документ
CMyDialog MyD; // создаём переменную класса CMyDialog
MyD.m_DX = MyD.m_DXN = pDoc->m_X; // инициализмруем переменные диалога
MyD.m_DY = MyD.m_DYN = pDoc->m_Y; .//
MyD.DoModal(); // создаём новый диалог
pDoc->m_X = MyD.m_DXN; // получаем новые значения
pDoc->m_Y = MyD.m_DYN; //
OnInitialUpdate(); // синхронизируем данные
Invalidate( TRUE ); // перерисовываем экран( вызов OnDraw() )
pDoc->SetModifiedFlag(); // ставим флаг изменения документа
}
13. Ну вот и всё, программа готова. Отсюда можно взять рабочую
программу, использующую MDI, в которой используется собственное диалоговое окно.
|