Практика работы в среде визуального программирования
Панель инструментов, меню, акселераторы
В этом параграфе будем рассматривать работу с меню с помощью редактора ресурсов на примере создания простой программы.
Создание меню
- Создадим SDI программу с названием Menu.
- Вкладка Resource View, идем по дереву Menu
Menu.rc
Menu
IDR_MAINFRAME двойной клик.
- Вставим пункт меню: File
Type Hear, вводим название Print Welcome.
- Вызовем свойства пункта меню: Клик правой кнопкой по имени
Properties.
- Запишем в поле ID: ID_FILE_PRINTWELCOME.
- Закроем редактор меню и запустим программу.
В меню File появилась команда, но она не работает (не подключена). Для того чтобы программа реагировала на выбор только что созданного пункта меню, свяжем с ним обработчик.
- В окне утилиты Class View вызовем свойства класса CMenuView.
- В окне свойств нажмем кнопку Events.
- Выберем в списке идентификаторов ID_FILE_PRINTWELCOME и раскроем ветку.
- Раскроем список напротив поля COMMAND и выберем "Add" OnFilePrintwelcome.
Создадим переменную типа CString и инициализируем в объекте документа. Добавим код, выделенный жирным, в прототип класса CMenuDoc.
public: virtual ~CMenuDoc(); CString StringData;
Проинициализируем переменную в конструкторе:
StringData="";
Напишем код обработчика OnFilePrintwelcome
void CMenuView::OnFilePrintWelcome() { CMenuDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!pDoc) return; pDoc->StringData="Добро пожаловать в меню."; Invalidate(); }
Добавим следующую строку в метод OnDraw:
pDC->TextOut(0,0,pDoc->StringData);
Усложним задачу. Создадим полномасштабную ветку меню с собственными подменю. Добавим в меню пункт Demo.
- Войдем в редактор меню.
- Выделим Edit
Вызовем контекстное меню
Выберем Insert New
Введем имя Demo.
- Введем пункты: Grayed, Checked, Submenus
Если в начало ввести &, то первая буква меню будет подчеркнута. Пусть это буква D, тогда Alt+D - это клавишный ускоренный вызов. Добавим подменю в пункте Submenus. Выделим пункт Submenus, в раскрывшейся слева вкладке Type Hear введем имя первого элемента подмею. Добавим в подменю еще оди пункт. Получим:
- Sub1
- Sub2
Создание акселератора
Акселератор - сочетание клавиш для выбора команды меню. Чтобы добавить акселератор, сделаем следующее:
- Откроем папку Accelerator в редакторе ресурсов. Дважды кликнем IDR_MAINFRAME.
- Выделим последнюю пустую строку.
- В появившемся списке в поле ID выберем строку ID_SUBMENUS_SUB1.
- Выберем строку Ctrl из списка в поле Modifiers.
- Выберем строку VK_F5 из списка в поле Key.
- Выход.
- Добавить в название клавиши Sub2\tCtrl+F5.
Добавление кнопок на панель инструментов
Создадим кнопку на панели для команды Sub1
- Откроем папку Toolbar в редактрое ресурсов. Дважды кликнем IDR_MAINFRAME
- Выделим пустую кнопку и сделаем рисунок.
- Вызовем свойства нарисованной кнопки. Выберем в поле ID имя идентификатора ID_SUBMENUS_SUB1.
Добавим код для пункта Sub1. Для этого вызовем свойства класса CMenuView из утилиты Class View. Перейдем к списку событий Events. Раскроем вкладку ID_SUBMENUS_SUB1 и добавим обработчик.
void CMenuView::OnSubmenusSub1() { CMenuDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!pDoc) return; pDoc->StringData="Меню 1"; Invalidate(); }
Тоже можно сделать и для Sub2.
Диалоговые окна. Работа с элементами управления - кнопками, текстовыми полями
Модальное диалоговое окно
Создадим программу, которая будет выводить диалоговое окно в ответ на выбор пользователем пункта Show Dialogs в меню File. В диалоговом окне создадим текстовое поле и кнопку. При нажатии на кнопку в текстовое поле должна заноситься символьная строка. Символьную строку изменим и при выходе из диалогового окна в клиентской области выведем измененную символьную строку.
Создание диалогового окна
- Создадим SDI программу Dialog.
- Включим в меню File команду Show Dialogs и свяжем с обработчиком.
- Войдем в редактор ресурсов. Щелкнем правой кнопкой по папке Dialog, выберем Insert
- Dialog. Среда переведет нас в режим визуального редактирования диалогового окна.
- Вставим два элемента: кнопку и текстовое поле.
- Изменим надпись на кнопке через свойства Properties: "Print String".
Создадим класс диалогового окна на основе созданного только что ресурса:
- Project
Add Class…
- В списке Categories: выберем MFC. В списке Templates: выберем MFC Class. Нажмем Add.
- В поле Base class: выберем CDialog. В поле Dialog ID выберем идентификатор только что созданного ресурса.
- Введем имя класса: CDlg и нажмем Finish.
Связывание обработчиков с элементами диалоговых окон
При нажатии на кнопку в текстовом поле должна появиться строка "Текст в диалоговом окне". Свяжем сообщение о нажатии на кнопку с обработчиком этого сообщения
- Вызовем свойства класса CDlg через Class View.
- Перейдем к списку событий Events.
- Выберем поле ID_BUTTON1 и добавим обработчик OnBnClickedButton1.
Связывание переменных с элементами диалоговых окон
Visual C++ позволяет связывать переменные класса с элементами диалоговых окон. Создадим переменную m_text для хранения строки текстового поля с помощью мастера:
- Вызовем контекстное меню класса CDlg через Class View. Выберем пункт Add
Add Variable…
- Установим флажок Control Variable. Выберем в поле Control ID: IDC_EDIT1, в поле Category: Value, Variable type: CString, Variable name: m_text.
- Finish.
Обработчик OnButton1:
void CDlg::OnBnClickedButton1() { m_text="Текст в диалоговом окне"; UpdateData(false); }
Обмен информацией между переменной и элементом IDC_EDIT1 осуществляется в специальном методе, включенном в класс диалогового окна:
void CDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_text); }
Код этого метода генерируется мастером, изменять его вручную не рекомендуется. Вызов метода UpdateData(BOOL) с параметром false заносит в текстовое поле значение переменной m_text. Вызов с параметром true присваивает переменной m_text содержимое текстового поля.
Переопределение метода для кнопки Ok
Переопределение необходимо, если поле редактировалось и необходимо сохранить текущее содержимое текстового поля. Для того чтобы переопределить метод, вызовем свойства класса CDlg, перейдем к списку виртуальных функций, нажав кнопку Overrides. Выберем метод OnOk().
void CDlg::OnOK() { UpdateData(true); CDialog::OnOK(); }
Отображение диалогового окна
Чтобы класс вида мог работать с членами класса CDlg, необходимо включить в него Dlg.h - заголовочный файл класса CDlg:
#include "Dlg.h"
В методе OnFileShowdialogs() создадим новый объект класса CDlg и отобразим его, пользуясь методом DoModal(). Далее добавим в класс документа переменную StringData типа CString и присвоим ей значение переменной m_text. Выведем значение переменной StringData в клиентском окне в левом верхнем углу.
Обработчик OnFileShowdialogs:
void CDialogView::OnFileShowdialogs() { CDlg dlg; int result=dlg.DoModal(); if(result==IDOK) { CDialogDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!pDoc) return; pDoc->StringData=dlg.m_text; Invalidate(); } }
Добавим в метод OnDraw строку:
pDC->TextOut(0,0,pDoc->StringData);
Использование диалогового окна в качестве главного
Создадим диалоговое окно в качестве главного и выведем в нем, по нажатию на кнопку, текстовое сообщение. Создадим программу BaseDialog.
- На первом шаге работы мастера Application Wizard выбрать Dialog based (базовым классом для новой программы станет класс CDialog ).
- Finish.
- Перейдем в редактор ресурсов, откроем ресурс диалогового окна для редактирования.
- Поместим кнопку и текстовое поле.
- Свяжем кнопку с обработчиком (двойной клик по OnButton1).
Создавать класс диалогового окна в этом случае не надо. Его создал уже автоматически Application Wizard. Рассмотрим общий способ работы с элементами управления - будем рассматривать их как объекты:
- Вызовем контекстное меню текстового поля (щелчок правой кнопкой мыши по элементу управления в редактрое ресурсов).
- Выберем пункт Add Variable…
- Выберем необходимый тип и введем имя переменной.
- Нажмем Finish.
Обработчик OnButton1:
void CBaseDialogDlg::OnButton1() { m_edit.SetWindowText(CString("Диалоговое окно!")); }
Совместное использование флажков и переключателей
Флажок - управляющий элемент, который позволяет выбрать один или несколько вариантов. Переключатели осуществляют выбор одного из нескольких элементов.
Флажки
Создадим диалоговое окно с тремя флажками и текстовым полем, в котором будет отображаться информация о выбранном флажке. Создадим программу Maps на основе диалогового окна (Dialog based). Редактор диалоговых окон: Удалить надпись "TODO …", и добавить три флажка и текстовое поле. Флажки надо выстроить в виде столбца. Текстовое поле расположим внизу. Названия флажков - Flag 1, Flag 2, Flag 3.
Выравнивание элементов в редакторе диалоговых окон:
Нажать на Ctrl и, не отпуская ее, щелкнуть на каждом из флажков. Последний из выбранных флажков будет служить "эталоном" (он выделен синими маркерами).
- Выравнивание по горизонтали (по левому краю): Контекстное меню->Align Lefts.
- Выравнивание по вертикали (расстояния между флажками будут одинаковыми):
- Контекстное меню -> Align Tops.
Связывание флажков с кодом программы:
С помощью Class View каждый флажок свяжем со своим обработчиком ( OnCheck1(), OnCheck2(), OnCheck3() ). Создадим переменную m_text и свяжем ее с текстовым полем.
void CMapsDlg::OnCheck1() { m_text="Выбран 1 флажок"; UpdateData(false); } void CMapsDlg::OnCheck1() { m_text=" Выбран 2 флажок "; UpdateData(false); } void CMapsDlg::OnCheck1() { m_text=" Выбран 3 флажок "; UpdateData(false); }
Переключатели
Создать диалоговое окно с тремя переключателями и текстовым полем, в котором будет отображаться информация о выбранном переключателе. Создадим программу Radios на основе диалогового окна (Dialog based). Редактор диалоговых окон: Удалить надпись "TODO …" , и добавить три переключателя и текстовое поле. Переключатели надо выстроить в виде столбца и внизу текстовое поле. Названия переключателей: Radio 1, Radio 2, Radio 3.
void CRadiosDlg::OnRadio1() { m_text="Выбран 1 переключатель"; UpdateData(false); } void CRadiosDlg::OnRadio2() { m_text=" Выбран 2 переключатель"; UpdateData(false); } void CRadiosDlg::OnRadio3() { m_text=" Выбран 3 переключатель"; UpdateData(false); }
Совместное использование флажков и переключателей
Создать диалоговое окно с тремя флажками, тремя переключателями и текстовым полем, в котором будет отображаться информация о выбранном варианте. Использовать групповые поля. Групповые поля предназначены для группировки элементов - как визуальной, так и функциональной. Все переключатели внутри группового поля работают совместно. Создадим программу Choice на основе диалогового окна (Dialog based). Редактор диалоговых окон: Удалить надпись "TODO …" , и добавить две группы флажков и переключателей и одно текстовое поле. Названия переключателей - Math, Gum, Inf, Bio, флажки - Math, Phys, Hist, Bio. Создадим для каждого переключателя свой обработчик - OnRadio1(),…, OnRadio4(). Для текстового поля введем переменную m_text. Свяжем с флажками переменные, которые будут изменять состояния флажков. Эти переменные будут представлять весь элемент. Зададим нужное состояние флагов в обработчиках для каждого переключателя.
void CChoiceDlg::OnRadio1() { m_check1=true; m_check2=true; m_check3=false; m_check4=true; m_text="85 ball"; UpdateData(false); } void CChoiceDlg::OnRadio2() { m_check1=false; m_check2=true; m_check3=true; m_check4=true; m_text="70 ball"; UpdateData(false); } void CChoiceDlg::OnRadio3() { m_check1=true; m_check2=true; m_check3=true; m_check4=false; m_text="83 ball"; UpdateData(false); } void CChoiceDlg::OnRadio4() { m_check1=true; m_check2=true; m_check3=false; m_check4=true; m_text="70 ball"; UpdateData(false); }