Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
[ ПРОДОЛЖЕНИЕ СЛЕДУЕТ ]
Это все на сегодня. Пока!
Алекс Jenter jenter@rsdn.ru Duisburg, 2001. Публикуемые в рассылке материалы принадлежат сайту RSDN.Программирование на Visual C++
Выпуск №55 от 18 ноября 2001 г.
Добрый день!
Сегодня в выпуске – продолжение второй части статьи "Использование WTL".
Если вы еще не читали первую часть, ее можно найти на RSDN.
СТАТЬЯ
Использование WTL
Часть 2. Диалоги и контролы (продолжение)
Автор: Александр Шаргин
Как известно, обычные диалоги не позволяют себя масштабировать. С точки зрения пользователя это довольно неудобно. Часть информации не помещается в маленьких контролах, и их приходится прокручивать, чтобы просмотреть всё целиком. В то же время часть экрана монитора всё равно остаётся незанятой, и диалог вполне мог бы её занять. Возникает вопрос: как реализовать масштабируемые диалоги в вашем приложении?
Обычно эта проблема решается так. Диалогу назначается стиль WS_THICKFRAME( Border: resizing в редакторе ресурсов). Затем в программе перехватывается сообщение WM_SIZE, сигнализирующее об изменении размеров диалога. В ответ на него программа соответствующим образом изменяет размеры контролов в диалоге. Этот подход универсален и достаточно прост в реализации, но требует написания большого количества кода, связанного с пересчётом координат. Поэтому в WTL введён класс, который в ряде случаев избавит вас от рутинной работы по масштабированию контролов. Этот класс называется CDialogResize<>. Он описан в файле atlframe.h . Хотя этот класс не является универсальным, он подойдёт в большинстве случаев. Замечу, что его можно применять с любым окном, содержащим дочерние окна, но чаще всего он применяется именно с диалогами.
Итак, чтобы воспользоваться поддержкой масштабирования, которую предоставляет WTL, нужно включить в число базовых классов вашего диалога класс CDialogResize<>, задав в качестве параметра шаблона имя порождаемого класса. После этого вам, как обычно, потребуется написать карту – на этот раз карту масштабирования. Макросы, из которых она формируется, приведены в таблице 4.
Макрос | Описание |
---|---|
BEGIN_DLGRESIZE_MAP(thisClass) | Начало карты масштабирования. thisClass– имя класса, в котором содержится карта. |
END_DLGRESIZE_MAP() | Этот макрос завершает карту масштабирования. |
DLGRESIZE_CONTROL(id, flags) | Этот макрос определяет, каким образом должен масштабироваться контрол с идентификатором id. Для этого в WTL определено несколько флагов, которые нужно объединить операцией логического "ИЛИ" и передать в качестве второго параметра макроса flags. Вы можете использовать флаги DLSZ_MOVE_Xи DLSZ_MOVE_Y(перемещение вдоль осей X и Y соответственно), DLSZ_SIZE_Xи DLSZ_SIZE_Y(изменение ширины и высоты контрола), а также флаг DLSZ_REPAINT, если после масштабирования контрола его нужно перерисовывать (то есть вызывать для него функцию Invalidate). |
BEGIN_DLGRESIZE_GROUP() | Контролы, включённые в карту масштабирования, можно группировать. Об эффектах группировки мы поговорим позже. Макрос BEGIN_DLGRESIZE_GROUPначинает группу контролов. Группы не могут быть вложенными. |
END_DLGRESIZE_GROUP() | Завершает группу контролов. Каждому макросу BEGIN_DLGRESIZE_GROUPдолжен соответствовать ровно один макрос END_DLGRESIZE_GROUP. |
Кроме написания карты масштабирования, необходимо выполнить ещё два действия. Во-первых, класс CDialogResize<>имеет свою собственную карту сообщений. В частности, она содержит обработчик сообщения WM_SIZE, который инициирует перемасштабирование контролов при каждом изменении размеров диалога. Эту карту сообщений следует подключить к карте сообщений вашего диалога, используя макрос CHAIN_MSG_MAP:
BEGIN_MSG_MAP(CMyDialog)
...
CHAIN_MSG_MAP(CDialogResize)
...
END_MSG_MAP()
Во вторых, после того, как ваш дилог создан, необходимо инициализировать внутренние структуры WTL, связанные с масштабированием. Это делается при помощи функции DlgResize_Init. Удобно вызывать её из обработчика сообщения WM_INITDIALOG. Функция DlgResize_Initимеет следующий прототип:
void DlgResize_Init(bool bAddGripper = true, bool bUseMinTrackSize = true,
DWORD dwForceStyle = WS_THICKFRAME | WS_CLIPCHILDREN)
В большинстве случаев на параметры можно не обращать внимание, так как значения по умолчанию вполне удовлетворяют всем нуждам. Параметр bAddGripperуказывает, нужно ли добавить к диалогу "гриппер" – маленький уголок, за который можно ухватиться курсором и изменить размеры диалога. Флаг bUseMinTrackSizeопределяет, нужно ли ограничивать минимальные размеры диалога. В большинстве случаев это хорошая идея, так как сильно уменьшенный дилог всё равно плохо выглядит и не удобен для работы с ним. Минимальный размер диалога хранится в переменной m_ptMinTrackSize, которую ваш класс диалога наследует от класса CDialogResize<>. По умолчанию в неё записывается первоначальный размер диалога (тот, который установлен в момент вызова функции DlgResize_Init). Вы можете записать туда любое другое значение. Что касается параметра dwForceStyle, то это просто стиль, который принудительно назначается диалогу в функции DlgResize_Init.
Ещё одна функция из класса CDialogResize<>, о которой следует упомянуть, – DlgResize_UpdateLayout. Эта функция принудительно пересчитывает координаты всех контролов в зависимости от переданных ей размеров диалога ( cxи cy). Именно она вызывается из обработчика сообщения WM_SIZE, но при необходимости вы можете вызывать её в любом другом месте.
На самом деле, единственная проблема с классом CDialogResize<>состоит в том, чтобы правильно составить карту масштабирования. Для этого нужно чётко понимать, как работают флаги DLSZ_XXX. Эти флаги по-разному действуют на контрол в группе или без неё.
Сначала посмотрим, как флаги DLSZ_XXXдействуют на контрол, не включённый в группу. Допустим, размеры диалога изменились на dx и dy соответственно. Тогда:
• DLSZ_SIZE_X: ширина контрола изменяется на dx .
• DLSZ_SIZE_Y: высота контрола изменяется на dy .
• DLSZ_MOVE_X: контрол двигается вдоль оси x на dx . Флаг DLSZ_SIZE_Xпри этом игнорируется .
• DLSZ_MOVE_Y: контрол двигается вдоль оси y на dy . Флаг DLSZ_SIZE_Yпри этом игнорируется .
Как видно из этого описания, задавать одновременно флаги DLSZ_MOVE_Xи DLSZ_SIZE_X(а также DLSZ_MOVE_Yи DLSZ_SIZE_Y) бессмысленно, так как в этом случае будут учитываться только флаги DLSZ_MOVE_*.
Читать дальшеИнтервал:
Закладка: