Создание
и связывание переменных
Итак, мы ввели
в состав класса, управляющего главным окном приложения, способность реагировать
на уведомляющие события UDN_DELTAPOS, EN_CHANGE, а также на событие Windows
WM_HSCROLL. Теперь пора показать, как с помощью Studio.Net можно создать переменные,
способные обмениваться данными с элементами управления (дочерними окнами) диалога.
Технология обмена в Visual C++ давно устоялась и происходит по такому алгоритму:
- При открытии окна диалога
ему посылается сообщение WM_INITDIALOG, на которое откликается либо класс
вашего диалога, либо родительский класс CDialog.
- В функции отклика OnlnitDialog
вашего класса вы делаете необходимые начальные установки и вызываете родительскую
версию этой функции. Причем порядок этих действий зависит от типов элементов
управления и их установок.
- Родительская версия OnlnitDialog
вызывает функцию UpdateData (FALSE) для провоцирования обмена данными между
переменными диалогового класса и элементами управления. Направление обмена
задается параметром функции UpdateData: если он TRUE, то обмен совершается
в сторону переменных, а если FALSE, то в сторону элементов управления. Очевидно,
что в состав класса надо ввести переменные и связать их с элементами управления.
- После того или по мере
того как пользователь ввел или вводит изменения в состояния элементов управления,
вновь, если это предусмотрел программист, вызывается функция UpdateData (TRUE)
или одна из функций типа GetDlgitem*. Они провоцируют обмен данными в сторону
переменных.
- Функция UpdateData вызывает
функцию DoDataExchange, которая обязательно есть в каждом диалоговом классе.
Последняя состоит из последовательности вызовов глобальных функций MFC типа
DDX_ и DDV_, которые умеют надежно обменивать данные в обе стороны и вежливо
сообщать о возможных ошибках и несоответствиях при обмене.
- При закрытии диалога
(здесь имеется в виду не наш диалог, который является главным окном
приложения, а обычный модальный диалог) каркас приложения вновь вызывает UpdateData
(TRUE) для того, чтобы произвести считывание данных, введенных пользователем.
Необходимо
помнить, что простым элементам -управления (static Control, Button Control или
Edit Control) обычно ставят в соответствие простые переменные типа int, BOOL
или cstring. Более сложным элементам (Spin Control, Slider Control) обычно соответствуют
переменные, которые являются объектами классов (CSpinButtonCtrl, CSliderCtrl).
Сейчас мы введем в диалоговый класс переменные, которые мы свяжем (ассоциируем)
с элементами управления. Некоторые из этих переменных мы уже заочно использовали
в коде функций-обработчиков.
- Откройте окно диалога,
установите фокус на счетчик (IDC_SPIN) и вызовите контекстное меню.
- В меню выберите команду
Variable — появится мастер Add Variable Wizard.
- В окне мастера установите
флажок Control variable.
- Переключатель Control-Value
установите в положение Control.
- В окне Control ID выберите
идентификатор элемента IDC_SPIN.
- В окне Variable Name
задайте имя переменной m_ Spin.
- В окне Access выберите
тип доступа private.
- В окне Comment задайте
комментарий: Счетчик кодов.
- Нажмите кнопку Finish.
В окне Class
View отыщите новый узел Variables, раскройте его и щелкните два раза мышью элемент
m_Spin. В окне LookDlg.h вы увидите, что мастер вставил декларацию:
//======
Счетчик кодов
CSpinButtonCtrl
m_Spin;
Найдите тело
функции DoDataExchange и убедитесь, что в ней появилась строка:
DDX_Control
(pDX, IDC_SPIN, m__Spin) ;
которая связывает
элемент IDC_SPIN с объектом m_spin. Теперь повторите все действия для элемента
IDC_SLIDER. В классе CLookDig должен появиться объект m_Slider класса CSliderCtrl.
В окне диалога
осталось еще довольно много элементов управления, с которыми не связаны никакие
переменные. Сейчас мы создадим эти переменные, но предварительно напомним, что
элементы типа static Control (поле текста) могут быть как управляемыми, так
и нет. В последнем случае все они должны иметь один и тот же идентификатор IDC_STATIC.
Мы будем управлять шестью элементами типа static и одним элементом (IDC_CURRENT)
типа Edit Control. Все элементы будут связаны с переменными по схеме Value,
то есть между ними будет происходить обмен с помощью функций DDX_Text, а переменные
будут иметь тип cstring. Процедура создания и связывания переменных для всех
элементов типа static одинакова, поэтому мы приведем описание только одной,
а вы повторите ее для всех других.
- Откройте окно диалога,
установите курсор в окно IDC_TOTAL и вызовите контекстное меню.
- В меню выберите команду
Variable — появится мастер Add Variable Wizard.
- В окне мастера Control
ID: должен быть выбран идентификатор IDC_TOTAL.
- Установите флажок Control
variable.
- Переключатель Control-Value
установите в положение Value.
- В окне Access: выберите
тип доступа private.
- В окне Variable Type:
задайте тип переменной CString.
- В окне Variable Name:
задайте имя переменной m_Total.
- Нажмите кнопку Finish.
Полезно просмотреть
состав класса CLookDlg и убедиться в том, что в нем появилась новая переменная
m_Total, а в тело DoDataExchange добавлена строка:
DDX_Text(pDX,
IDCJTOTAL, mJTotal);
Вызов функции
DDX_Text гарантирует, что в ключевые моменты жизни приложения будет производиться
обмен между переменной m_Total и полем текста IDC_TOTAL. Вы никогда не будете
явно вызывать функцию DoDataExchange. Ее вызывает функция UpdateData. Она создает
объект вспомогательного класса CDataExchange и задает направление обмена. Если
параметр функции UpdateData равен TRUE или отсутствует, то обмен осуществляется
в сторону переменных, если он равен FALSE, то — наоборот. Каркас приложения
без вашего участия и в нужные моменты вызывает UpdateData, но вы можете и сами
вызывать эту функцию тогда, когда необходимо произвести обмен. Обычно это моменты,
когда вам надо считать все данные из окон или, наоборот, отразить в окнах изменения
в данных, произведенные программой. Сейчас повторите шаги по созданию переменных,
связанных с окнами элементов типа static Control. Все переменные должны иметь
тип cstring. Данные для этой операции приведены в табл. 4.4.
Таблица.
4.4. Идентификаторы элементов и связанные с ними переменные
Если не было
ошибок ввода, то в теле функции DoDataExchange должно быть 6 строк вида DDX_Text.
Процедура по созданию и связыванию переменных для окон редактирования почти
не отличается от только что рассмотренной (для текстовых полей). Различия вы
увидите в списке по выбору типа переменной (Variable Туре). Для элементов типа
Edit Control существует множество преобразований вводимого текста в данные числовых
типов (int, double и т. д.). С учетом сказанного создайте переменную cstring
m_CurPos и свяжите ее с полем редактирования IDC_CURRENT.