Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Далее полученный класс можно использовать для создания как модальных, так и немодальных диалогов, например:
// Создаём модальный диалог
CMyDialog modal;
modal.DoModal();
// Создаём немодальный диалог
CMyDialog modeless;
modeless.Create(HWND_DESKTOP);
Класс CAxDialogImpl<>очень похож на предыдущий. Вся разница в том, что вместо функции DialogBoxParamон использует функцию AtlAxDialogBox, а вместо функции CreateDialogParam– функцию AtlAxCreateDialog:
// modal dialogs
int DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL) {
ATLASSERT(m_hWnd == NULL);
_Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT*)this);
#ifdef _DEBUG
m_bModal = true;
#endif //_DEBUG
return AtlAxDialogBox(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
}
...
// modeless dialogs
HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) {
ATLASSERT(m_hWnd == NULL);
_Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT*)this);
#ifdef _DEBUG
m_bModal = false;
#endif //_DEBUG
HWND hWnd = AtlAxCreateDialog(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
ATLASSERT(m_hWnd == hWnd);
return hWnd;
}
Эти функции, в отличие от своих аналогов из Win32 API, могут создавать диалоги, содержащие ActiveX-контролы. Мы не будем рассматривать их реализацию, поскольку тема использования ActiveX-контролов выходит за рамки данной статьи.
Чтобы создавать диалоги на базе класса CDialogImpl<>, необходимо каждый раз порождать от него собственные классы. Это довольно утомительно. Класс CSimpleDialog<>предназначен для отображения простейших модальных диалогов, содержащих только статическую информацию и стандартные кнопки, такие как "OK" и "Отмена". Кроме функции DoModal, которая реализована почти так же, как в классе CDialogImpl<>, этот класс предоставляет собственную карту сообщений и обработчики OnInitDialogи OnCloseCmd. Последний вызывается в ответ на нажатие любой кнопки со стандартным идентификатором ( IDOK, IDCANCEL, IDABORT, IDRETRY, IDIGNORE, IDYESили IDNO) и закрывает диалог.
Обратите внимание, что идентификатор ресурса диалога в классе CSimpleDialog<>задаётся не как константа, а как первый параметр шаблона. Благодаря этому класс можно использовать, не порождая от него собственных классов. Если, к примеру, вы нарисовали в редакторе диалоговое окно About и назначили ему идентификатор IDD_ABOUT, отобразить его можно, используя класс CSimpleDialog<>напрямую:
CSimpleDialog dlg;
dlg.DoModal();
Ещё раз подчеркну, что класс CSimpleDialog<>не содержит реализации метода Create, а поэтому не позволяет создавать немодальные диалоги. Методы EndDialogи DestroyWindowтакже отсутствуют.
Механизм динамического обмена данными (DDX – Dynamic Data eXchange) используется для обмена данными между контролами и переменными вашей программы. Термин DDX был введён в MFC, хотя сам механизм под разными названиями существует и в других библиотеках. В WTL он также присутствует. Его реализация содержится в классе CWinDataExchange<>.
Прежде чем рассказывать про класс CWinDataExchange<>, скажу несколько слов об общих принципах реализации дополнительной функциональности в WTL.
Обычно дополнительные возможности WTL реализуются в отдельных классах. Чтобы получить доступ к этим возможностям, необходимо произвести свой класс от всех классов WTL, содержащих нужную нам функциональность. Далее каждый из базовых классов конфигурируется с помощью соответствующей карты (map), которая составляется из специально предусмотренных для этой цели макросов. Обычно карта начинается макросом BEGIN_XXX_MAPи заканчивается макросом END_XXX_MAP(XXX обозначает некоторый идентификатор, разъясняющий назначение карты). Между ними располагаются все остальные макросы карты.
Некоторые механизмы WTL, подключённые к нашему классу, требуют также начальной инициализации, которую можно выполнить, например, в обработчике сообщения WM_INITDIALOG.
Настроив нужные нам механизмы WTL, мы можем использовать их, вызывая или переопределяя предусмотренные для этой цели методы.
Вернёмся к механизму DDX. Чтобы использовать его, включите в список базовых классов вашего диалога (или другого окна, содержащего контролы) класс CWinDataExchange<>(описан в файле atlddx.h ). В качестве параметра шаблона задаётся имя вашего производного класса. Например:
class CMyDialog : public CDialogImpl, public CWinDataExchange{
…
};
Следующий шаг – включить в public-секцию вашего класса карту DDX. Каждая строчка в этой карте связывает идентификатор контрола с некоторой переменной в вашей программе. Обычно это переменная-член класса, но она может быть и глобальной/статической. В обмене могут участвовать числовые или текстовые данные с ограничениями или без них. Список макросов, из которых строится карта DDX, приведён в таблице 1.
Макрос | Описание |
---|---|
BEGIN_DDX_MAP(thisClass) | Начало карты DDX. thisClass– имя класса, в котором содержится карта. |
DDX_TEXT(nID, var) | Связывает строковую переменную varс контролом nID(здесь и далее nID– это идентификатор контрола). Переменная varможет иметь тип TCHAR*, BSTR, CComBSTRили CString. Обмен данными осуществляется при помощи функций SetWindowTextи GetWindowText. Чаще всего макрос используется для статических контролов и полей ввода, хотя может применяться и с другими окнами. |
DDX_TEXT_LEN(nID, var, len) | Аналогичен предыдущему, но длина строки ограничивается значением len. Попытка передать строку, длина которой превышает len, приведёт к ошибке валидации (об ошибках немного позже). |
DDX_INT(nID, var) | Связывает целочисленную переменную varс контролом nID. |
DDX_INT_RANGE(nID, var, min, max) | Аналогичен предыдущему, но передаваемое значение должно лежать в диапазоне от minдо max. Невыполнение этого условия приведёт к ошибке валидации. |
DDX_UINT(nID, var) | Связывает целочисленную беззнаковую переменную varс контролом nID. |
DDX_UINT_RANGE(nID, var, min, max) | Аналогичен предыдущему, но передаваемое значение должно лежать в диапазоне от minдо max. Невыполнение этого условия приведёт к ошибке валидации. |
DDX_FLOAT(nID, var) | Связывает переменную с плавающей точкой varс контролом nID. varможет иметь тип floatили double. Макрос DDX_FLOATбудет доступен, только если вы определите макрос _ATL_USE_DDX_FLOATперед включением заголовочного файла atlddx.h . |
DDX_FLOAT_RANGE(nID, var, min, max) | Аналогичен предыдущему, но передаваемое значение должно лежать в диапазоне от minдо max. Невыполнение этого условия приведёт к ошибке валидации. |
DDX_CONTROL(nID, obj) | Связывает объект objс контролом nID. Для связывания используется метод obj.SubclassWindow, поэтому объект должен принадлежать классу CWindowImplBaseT<>или производному от него. |
DDX_CHECK(nID, var) | Привязывает переменную varтипа intк флагу checked кнопки nID. Для обмена данными используются сообщения BBM_SETCHECKи BM_GETCHECK. |
DDX_RADIO(nID, var) | Связывает переменную varтипа intс группой переключателей. Контрол nIDдолжен быть первым в группе. |
END_DDX_MAP() | Этот макрос завершает карту DDX. Не имеет параметров. |
Рассмотрим пример карты DDX для диалога, который позволяет вводить имя, адрес и номер телефона.
Читать дальшеИнтервал:
Закладка: