Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на 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в этом случае тривиально:
void LengthyOperation() {
// Конструктор объекта waitCur вызовет метод Set, и курсор поменяется на "песочные часы".
CWaitCursor waitCur;
// Выполняем длительную операцию.
…
// Здесь вызывается деструктор для объекта waitCur, и курсор восстанавливается.
}
Механизм отрисовки контрола родительским окном (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 окно может иметь несколько карт сообщений?).
BEGIN_MSG_MAP(COwnerDraw)
MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem)
MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem)
ALT_MSG_MAP(1)
MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem)
MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem)
MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem)
MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem)
END_MSG_MAP()
По умолчанию используется карта с номером 0. Она обрабатывает сообщения в родительском окне. Карту с номером 1 можно использовать для перехвата отражённых сообщений, связанных с механизмом owner draw, в самом контроле.
Обработчики сообщений реализованы примерно одинаково. Они распаковывают параметры сообщений и передают управление специальным функциям, которые и выполняют основную работу. Вот прототипы этих функций.
void DrawItem(LPDRAWITEMSTRUCT);
void MeasureItem(LPMEASUREITEMSTRUCT);
int CompareItem(LPCOMPAREITEMSTRUCT);
void DeleteItem(LPDELETEITEMSTRUCT);
Именно эти функции вы можете переопределить в производном классе, чтобы реализовать отрисовку контрола. Это удобнее, чем вручную перехватывать сообщения и вспоминать, каким образом в их параметрах запакована информация. Обратите внимание, что класс COwnerDraw<>содержит стандартную реализацию этих функций. Функции DrawItem, CompareItemи DeleteItemничего полезного не делают, зато функция MeasureItemвозвращает размер пункта меню в зависимости от настроек системы и размер элемента в списке в зависимости от размера стандартного системного фонта, который используется в диалогах и меню. Если такое поведение вас не устраивает, измените его на любое другое.
Рассмотрим пример использования класса COwnerDraw<>для рисования нестандартной кнопки.
class CButtonDemoDlg : public CSimpleDialog, public COwnerDraw, ... {
private:
HICON m_hIcon1, m_hIcon2;
...
public:
BEGIN_MSG_MAP(CButtonDemoDlg)
...
CHAIN_MSG_MAP(COwnerDraw)
END_MSG_MAP()
void DrawItem(LPDRAWITEMSTRUCT pDIS) {
if ((pDIS->itemState & ODS_SELECTED) != 0) {
// Кнопка нажата
DrawIcon(pDIS->hDC, 0, 0, m_hIcon2);
} else {
// Кнопка отпущена
DrawIcon(pDIS->hDC, 0, 0, m_hIcon1);
}
}
};
Механизм пользовательского рисования (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<>, который мы рассмотрели выше. Его реализация выглядит так.
template class CCustomDraw {
public:
// Message map and handlers
BEGIN_MSG_MAP(CCustomDraw)
NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw)
Интервал:
Закладка: