Visual C++. Лабораторная работа № 8.
Вызов диалоговых окон из меню Windows Application (на базе однодокументного
приложения). Решение задач с использованием различных элементов графического
интерфейса.
- Цель работы:
- Изучить включение в приложение Single document своих диалоговых окон.
Научиться передавать значения между диалоговыми окнами и главным окном приложения.
Изучить работу модального и немодального диалога. Получить практические навыки в
разработке программ на основе MFC.
1. Создайте приложение с помощью MFС AppWizard (exe), выбрать тип предложения
Single document. Сделать свой пункт в меню с названием MyDial1, из которого будем
вызывать диалоговое окно
2. Создайте диалоговое окно, выполнив команду Insert | Recourse и нажмите
кнопку NEW. В диалоговом окне сделать поле для ввода знаний и переменную для
нее, как это делалось в работах 2-6
3. Добавить необходимый код для запуска Вашего окна как модального из пункта
меню и вывода текста введенного в окне диалога в окно программы (т.е. изучить
методы обмена информацией между модальным диалоговым окном и основным окном
программа). Использовать информацию, полученную на лекции
4. Добавить еще один пункт в меню с названием, например MyDial2. По аналогии с
пунктом 2 добавить еще одно диалоговое окно с полем для ввода значений и кнопкой
(это заготовка для немодального диалогового окна)
5. Добавить необходимый код для запуска немодального диалогового окна и обмена
информацией между немодальным диалоговым окном и основным окном программы
После выполнения п.2 открываем Class Wizard. Нас спросят, хотим ли создать
новый класс. Ответим ДА и введем имя нового класса CMyDlg.
Затем на вкладке ClassView выберем CLab_08View и дважды щелкнем по CLab_08View().
Перейдем в самое начало файла и после уже имеющихся директив вставим
#include "MyDlg.h";
В теле функции OnDrow() напишем:
CLab_08Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(0, 0, pDoc->str);
Переменная str должна быть предварительно объявлена. В обработчике пункта меню пишем:
void CLab_08View::OnMyDlg()
{
CMyDlg dlg;
CLab_08Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (dlg.DoModal() == IDOK) pDoc->str = dlg.m_edDlg;
Invalidate(); //Перерисовать окно
}
Теперь при щелчке по нашему пункту меню появится диалоговое окно. Если
пользователь щелкнет ОК в этом окне, то текст из редактора появится в документе.
Добавляем еще один пункт меню и еще одно диалоговое окно, в свойствах которого
устанавливаем галочку напротив пункта Visible. Добавляем для окна новый класс,
как это описано выше. Пусть этот класс будет называться CMyDlg_2. Тогда дважды
щелкаем по этому классу на вкладке ClassView и пишем в открывшемся коде следующее:
class CMyDlg_2 : public CDialog
{
// Construction
public:
CMyDlg_2(CWnd* pParent = NULL); // standard constructor
CMyDlg_2(CView* pView);
CView* m_pView;
Затем щелкаем дважды на CMyDlg_2::CMyDlg_2(CWnd* pParent =NULL) и добавляем туда
CMyDlg_2::CMyDlg_2(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg_2::IDD, pParent)
{
//{{AFX_DATA_INIT(CMyDlg_2)
m_tx = _T("");
//}}AFX_DATA_INIT
}
CMyDlg_2::CMyDlg_2(CView* pView)
{
m_pView = pView;
}
Переменная m_tx - это переменная, связанная с редактором немодального диалога.
Щелкаем правой кнопкой по CMyDlg_2 и выбираем Add member function. В поле тип
указываем BOOL, а имя функции будет Create(). В теле функции пишем:
BOOL CMyDlg_2::Create()
{
return CDialog::Create(CMyDlg_2::IDD);
}
Подключаем файл MyDlg_2.h, как в файлы .h, так и в .cpp. Затем создаем указатель
на диалоговое окно.
class CLab_08View : public CView
{
protected: // create from serialization only
CLab_08View();
DECLARE_DYNCREATE(CLab_08View)
// Attributes
public:
CLab_08Doc* GetDocument();
CMyDlg_2* m_pDlg;
Добавляемая строка выделена жирным шрифтом. В конструкторе вида создаем объект диалога:
CLab_08View::CLab_08View()
{
m_pDlg = new CMyDlg_2(this);
}
В деструкторе вида его уничтожаем
CLab_08View::~CLab_08View()
{
delete m_pDlg;
}
К пункту меню добавим код:
void CLab_08View::OnModalDlg()
{
m_pDlg->Create();
}
Событие для кнопки Cansel модального диалога:
void CMyDlg_2::OnCancel()
{
m_pView->PostMessage(WM_END);
CDialog::OnCancel();
}
Где WM_END объявляется в файле MyDlg_2.h следующим образом:
#define WM_END WM_USER + 10
Затем вставляем в таблицу реакций на сообщение свое сообщение. Для этого дважды
щелкаем по CLab_08View() и пишем код:
BEGIN_MESSAGE_MAP(CLab_08View, CView)
//{{AFX_MSG_MAP(CLab_08View)
ON_COMMAND(ID__1, OnMyDlg)
ON_COMMAND(ID__2, OnModalDlg)
//}}AFX_MSG_MAP
// Standard printing commands
ON_MESSAGE(WM_END, OnEnd1)
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
Добавляемая строка выделена жирным шрифтом. Затем нужно добавить функцию
OnEnd1() (процедура добавления функции рассмотрена выше). В теле функции пишем
код, который будет разрушать созданное окно:
LONG CLab_08View::OnEnd1()
{
m_pDlg->DestroyWindow();
return 0;
}
В кнопке ОК вместо строки CDialog::OnCancel(); добавляем код:
UpdateData(1);
m_pView->Invalidate();
и модифицируем функцию OnDrow():
CLab_08Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDoc->str = m_pDlg->m_tx;
pDC->TextOut(0, 0, pDoc->str);
Жирным выделена добавленная строка. Теперь по щелчку на ОК в документ будет
выведена строка из редактора m_tx.
Правда, появилась одна проблема: теперь текст из модального окна в документ не
передается. Эта проблема решаема, но, т.к. в заданиях об этом не сказано, то
мы ее решать не будем. Пока крыша окончательно не съехала, перейдем к контрольным
работам по другим предметам…