Программирование на Visual C++. Архив рассылки
Шрифт:
ПРИМЕЧАНИЕ
Методы GetPaneTipText, SetPaneTipText, GetPaneIcon и SetPaneIcon доступны, только если макрос _WIN32_IE имеет значение 0x0400 или выше.
И последний важный момент. Всякий раз, когда окно изменяет размер, вы должны посылать строке состояния сообщение WM_SIZE, чтобы она могла скорректировать своё местоположение и размер.
Класс CWaitCursor – это простенькая обёртка вокруг метода SetCursor из Win32 API. При помощи этого класса вы можете временно изменить вид курсора мыши. Чаще всего класс CWaitCursor применяют, чтобы "выплюнуть" песочные часы на время выполнения длительной
Полный список методов класса CWaitCursor приведён в таблице 8.
Метод | Описание |
---|---|
CWaitCursor(bool bSet = true, LPCTSTR lpstrCursor = IDC_WAIT, bool bSys = true) | Конструктор. Параметр lpstrCursor задаёт имя ресурса, из которого следует грузить курсор. Если вы собираетесь использовать системный курсор, параметр bSys устанавливается в true. Наконец, флаг bSet определяет, следует ли вызывать из конструктора метод Set (см. ниже). |
~CWaitCursor | Деструктор. Из него принудительно вызывается метод Restore (см. ниже). |
bool Set | Заменяет текущий курсор курсором, заданным в конструкторе. |
bool Restore | Восстанавливает старый курсор, который был изменён методом Set. |
Предлагаемые по умолчанию параметры конструктора "заточены" для индикации длительной операции. Использование класса CWaitCursor в этом случае тривиально:
Механизм отрисовки контрола родительским окном (owner draw) появился довольно давно – ещё в Windows 3.0. Он позволяет придать контролу совершенно произвольный внешний вид. Его поддерживают такие стандартные элементы управления, как кнопка, меню, простой список и комбинированный список.
В основе механизма owner draw лежат сообщения WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM и WM_DELETEITEM. Так, в обработчике WM_DRAWITEM выполняется собственно отрисовка контрола, а в обработчике WM_MEASUREITEM – задание размеров отдельных элементов, содержащихся в контроле (пунктов меню, элементов списка и т.п.). WTL содержит небольшой класс COwnerDraw<>, который помогает вам обрабатывать все эти сообщения (описан в файле atlframe.h). Чтобы им воспользоваться, включите его в список базовых классов окна, которое будет заниматься отрисовкой контролов.
Посмотрим, какие элементы входят в класс COwnerDraw<>. В первую очередь это карта сообщений. Точнее, две карты (вы ещё не забыли, что в WTL окно может иметь несколько карт сообщений?).
По умолчанию используется
карта с номером 0. Она обрабатывает сообщения в родительском окне. Карту с номером 1 можно использовать для перехвата отражённых сообщений, связанных с механизмом owner draw, в самом контроле.Обработчики сообщений реализованы примерно одинаково. Они распаковывают параметры сообщений и передают управление специальным функциям, которые и выполняют основную работу. Вот прототипы этих функций.
Именно эти функции вы можете переопределить в производном классе, чтобы реализовать отрисовку контрола. Это удобнее, чем вручную перехватывать сообщения и вспоминать, каким образом в их параметрах запакована информация. Обратите внимание, что класс COwnerDraw<> содержит стандартную реализацию этих функций. Функции DrawItem, CompareItem и DeleteItem ничего полезного не делают, зато функция MeasureItem возвращает размер пункта меню в зависимости от настроек системы и размер элемента в списке в зависимости от размера стандартного системного фонта, который используется в диалогах и меню. Если такое поведение вас не устраивает, измените его на любое другое.
Рассмотрим пример использования класса COwnerDraw<> для рисования нестандартной кнопки.
Механизм пользовательского рисования (custom draw) иногда путают с owner draw. Он предназначен для той же цели – изменить внешний вид контролов. Однако он появился несколько позже (вместе с набором общих контролов из библиотеки comctl32.dll) и используется для более новых контролов (таких, как ListView и TreeView).
Пользовательское рисование работает следующим образом. Когда контрол перерисовывается, он посылает родительскому окну одно или несколько уведомлений NM_CUSTOMDRAW, упакованных в сообщение WM_NOTIFY. Каждое уведомление соответствует некоторой фазе перерисовки (до/после рисования контрола целиком или отдельного элемента и т. д.). Фазу можно определить по полю dwDrawStage структуры NMCUSTOMDRAW, указатель на которую передаётся вместе с уведомлением. В зависимости от фазы родительское окно может выполнить некоторые действия (например, изменить цвет или фонт отдельного элемента списка). Подробности можно найти в MSDN (см. статью "Customizing a Control's Appearance Using Custom Draw").
В WTL есть класс CCustomDraw<> (описан в файле atlctls.h), который помогает вам перехватывать уведомление NM_CUSTOMDRAW и распаковывать его параметры. Он очень похож на класс COwnerDraw<>, который мы рассмотрели выше. Его реализация выглядит так.