Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

Рассмотрим пример карты DDX для диалога, который позволяет вводить имя, адрес и номер телефона.

BEGIN_DDX_MAP(CMyDialog)

 DDX_TEXT_LEN(IDC_NAME, m_name, 20)

 DDX_TEXT(IDC_ADDRESS, m_address)

 DDX_UINT_RANGE(IDC_PHONE, m_phone, 0, 9999999)

END_DDX_MAP

ПРИМЕЧАНИЕ

Если вы использовали MFC, вы, вероятно, заметили сходство карты DDX с виртуальной функцией CWnd::DoDataExchange. Они действительно похожи. Одно отличие состоит в том, что макросы WTL не используют вспомогательную структуру, аналогичную CDataExchange из mfc. Это несколько упрощает их использование. Второе отличие – в WTL собственно обмен и валидация объединены вместе, а в MFC им соответствуют различные функции (DDX_* для обмена данными и DDV_* для валидации).

Вот и всё. Никакой дополнительной инициализации механизм DDX в WTL не требует. Чтобы выполнить обмен данными, используйте функцию DoDataExchange. Вот её прототип:

BOOL DoDataExchange(BOOL bSaveAndValidate = FALSE, UINT nCtlID = (UINT)-1)

Параметр bSaveAndValidate задаёт направление обмена (FALSE или DDX_LOAD соответствует записи значений из переменных в контролы, а TRUE или DDX_SAVE – из контролов в переменные). Второй параметр задаёт идентификатор контрола, с которым необходимо произвести обмен. Значение по умолчанию (-1) соответствует всем контролам, упомянутым в карте DDX. Функция DoDataExchange возвращает TRUE, если обмен данными был успешным, или FALSE в противном случае.

ПРИМЕЧАНИЕ

В MFC обмен данными осуществляет функция CWnd::UpdateData, похожая на DoDataExchange из wtl. Отличие в том, что функция UpdateData не позволяет задавать идентификатор контрола. Вместо этого она всегда воздействует на все контролы, прописанные в функции CWnd::DoDataExchange. Реализация в wtl несколько гибче, но было бы ещё лучше, если бы разработчики WTL предусмотрели разбиение карты DDX на подкарты (как это сделано для карт сообщений). Часто в реальной программе требуется выполнить обмен данными не с одним контролом и не со всеми контролами, а с некоторым их подмножеством.

Иногда в процессе обмена данными возникают ошибки. Их делят на две разновидности: ошибки обмена (data exchange errors) и ошибки валидации (data validation errors). Ошибки обмена возникают, когда контрол не содержит значения, соответствующего типу связанной с ним переменной (например, поле ввода, связанное с переменной типа int, содержит пробелы или другие нецифровые символы). Ошибки валидации фиксируются в случае несоответствия передаваемого значения и наложенных на него ограничений (максимальная длина строки, минимальное и максимальное значение числа). В случае возникновения ошибки обмена вызывается виртуальная функция OnDataExchangeError, а при возникновении ошибки валидации – виртуальная функция OnDataValidateError. Дальнейший процесс обмена данными прерывается, а DoDataExchange возвращает FALSE, сигнализируя о неуспехе операции.

Класс CWinDataExchange<> предоставляет свои реализации функций OnDataExchangeError и OnDataValidateError. Они обе совершенно одинаковы.

// Overrideables

void OnDataExchangeError(UINT nCtrlID, BOOL /*bSave*/) {

 // Override to display an error message

 ::MessageBeep((UINT)-1);

 T* pT = static_cast<T*>(this);

 ::SetFocus(pT->GetDlgItem(nCtrlID));

}

void OnDataValidateError(UINT nCtrlID, BOOL /*bSave*/, _XData& /*data*/) {

 // Override to display an error message

 ::MessageBeep((UINT)-1);

 T* pT = static_cast<T*>(this);

 ::SetFocus(pT->GetDlgItem(nCtrlID));

}

Как видим, эти функции издают звуковой сигнал и устанавливают фокус ввода на контрол, в котором содержится неверное значение. Вы можете изменить это поведение на любое другое. Обратите внимание на структуру _XData, которая передаётся в функцию OnDataValidateError. Она содержит информацию об ограничении, которое было нарушено. Вот как описана эта структура в файле atlddx.h.

// Helpers for validation error reporting

enum _XDataType {

 ddxDataNull = 0,

 ddxDataText = 1,

 ddxDataInt = 2,

 ddxDataFloat = 3,

 ddxDataDouble = 4

};

struct _XTextData {

 int nLength;

 int nMaxLength;

};

struct _XIntData {

 long nVal;

 long nMin;

 long nMax;

};

struct _XFloatData {

 double nVal;

 double nMin;

 double nMax;

};

struct _XData {

 _XDataType nDataType;

 union {

_XTextData textData;

_XIntData intData;

  • Читать дальше
  • 1
  • ...
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: