Урок 3. Диалоговые окна Добавим в программу, сделанную в уроке 2, диалоговое окно. Точнее, одно диалоговое окно уже есть, его можно найти в Help > About.
Разметка диалоговых окон находится в файле ресурсов в разделе Dialog. Создадим новое диалоговое окно, с помощью которого мы можем регулировать толщину линии. Поменяем идентификатор на IDD_DIALOG_LINE (его можно поменять во вкладке Properties). Также там можно поменять заголовок диалогового окна (в пункте Caption). Слева находится поле, в которое можно вставлять разные элементы управления. Элементы управления можно найти на вкладке Toolbox справа. Выберем Edit Control и нарисуем поле ввода в диалоговом окне. Слева от поля ввода добавим текстовое поле – Static Text. Текст внутри текстового поля можно поменять во вкладке Properties. Для удобства позиционирования элементов можно включить режим сетки. Еще лучше выровнять по центру по вертикали текст в поле Static – чтобы у него было одинаковое выравнивание с текстовым полем. Это можно исправить во вкладке Properties, равно как и другие опции отображения. Центрирование текста по вертикали – это свойство Center Image
-> True.
У каждого элемента управления также есть свой идентификатор, который можно поменять во вкладке Properties. Установим полю ввода более подходящий идентификатор, например, IDC_EDIT_LINE_WIDTH.
Диалоговое окно готово, теперь нужно создать класс окна, чтобы окно можно было вызвать из программы. Для создания класса нужно нажать правой кнопкой мыши на диалоговом окне в редакторе и выбрать Add Class. Появится wizard, в котором в поле Class name нужно ввести имя класса (например, CLineWidth – в MFC принято все классы начинать с C), также нужно удостовериться, что в поле Base class стоит CDialog.
Wizard автоматически сгенерирует h и cpp файлы, содержащие класс диалогового окна. Для работы с ним нужно в нужном месте подключить h-файл, например, в файле CChildView.cpp.
Сделаем пункт меню «Choose line width..» (в Windows, принято, чтобы пункты меню, по которым появляются новые окна заканчивались двоеточием). Добавим обработчик события для этого пункта меню и вызовем окно из него
void CChildView::OnDrawChooselinewidth()
{
CLineDialog d;
d.DoModal();
}
Диалоговое окно здесь – модальное. Функция DoModal завершит свою работу только после закрытия диалогового окна.
Ура, окно вызывается, по пункту меню. Теперь, свяжем толщину линии со значением в поле ввода. Это можно сделать в два этапа – сначала необходимо связать поле ввода с некоторым полем класса CLineDialog, а затем можно пользоваться этим полем для чтения/записи.
Для добавления поля в класс нужно открыть редактор диалога, щелкнуть правой кнопкой мыши по нужному элементу управления и выбрать Add Variable. В открывшемся диалоговом окне нужно убедиться, что стоит галочка Control variable. Она означает, что новое поле будет связано с элементом управления. В Category надо выбрать Value - это означает, что нас интересует только значение, которое вводится в элемент управления. В Variable type надо выбрать int, так как вводить мы будем целое число – ширину линии. Можно также установить минимальное и максимальное значение (от 1 до 15, например), и выберем какое-нибудь имя переменной, например m_line_width.
В результате наших действий добавлась переменная, ее связь с элементом управления задается строчками в методе DoDataExchange:
void CLineDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_LINE_WIDTH, m_line_width);
DDV_MinMaxInt(pDX, m_line_width, 1, 15);
}
Теперь создадим поле m_line_width в классе CChildView которое будет обозначать толщину линии, установим его начальное значение в конструкторе в 1 и изменим строчку в функции OnPaint:
bpen.CreatePen(PS_SOLID, m_line_width * (m_draw_thickline ? 2 : 1), RGB(m_mouse_over ? 255 : 0, 0, 0));
Так как поле ввода теперь связано с полем класса CLineDialog, его можно установить перед вызовом диалогового окна и считать после его закрытия. Это может сделать следующий код:
void CChildView::OnDrawChooselinewidth()
{
CLineDialog d; d.m_line_width = m_line_width;
if (d.DoModal() == IDOK) {
m_line_width = d.m_line_width;
Invalidate();
}
}
Метод DoModal здесь возвращает значение IDOK, если нажата кнопка Ok, и IDCANCEL – если Cancel. Теперь можно регулировать толщину линии, кроме того, остался переключатель толстая/тонкая линия. Сделаем так, чтобы это показатель можно было тоже регулировать в диалоговом окне, заодно это будет примером на радио-кнопки.
Нарисуем два элемента управления radio button. У каждому дадим свое название. Первый элемент играет особую роль. Ему нужно поставить свойство Group = True. Это значит, что элемент будет первым в группе радио-кнопок. Другая группа будет начинаться со следующего элемента, у которого Group = True (в порядке добавления).
Кроме того, именно этот элемент будет взаимодействовать с системой и передавать свое значение. Дадим ему человеческий идентификатор, например IDC_RADIO_THICK. Добавим переменную m_thick_line, связанную с этим radio button’ом (Category: Value, Variable type: int). Целое число будет обозначать номер элемента (в порядке добавления), который сейчас выбран. В нашем случае число 0 будет соответствовать пункту Thin, а число 1 – thick, что, в общем-то и совпадает по смыслу со значениями поля m_thick_line в классе CChildView. Поэтому осталось добавить пару строчек в обработчик события:
void CChildView::OnDrawChooselinewidth()
{
CLineDialog d; d.m_line_width = m_line_width;
d.m_thick_line = (int)m_draw_thickline;
if (d.DoModal() == IDOK) {
m_draw_thickline = (bool)d.m_thick_line;
m_line_width = d.m_line_width;
Invalidate();
}
}
Все работает.
|