Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

#define DECLARE_WND_SUPERCLASS(WndClassName, OrigWndClassName) \

static CWndClassInfo& GetWndClassInfo \

{ \

 static CWndClassInfo wc = \

 { \

{ sizeof(WNDCLASSEX), 0, StartWindowProc, \

0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \

OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \

 }; \

 return wc; \

}

Параметр WndClassName определяет имя класса вашего нового контрола. В качестве второго параметра OrigWndClassName следует указать имя класса контрола, который вы взяли за основу. При регистрации вашего класса WndClassName WTL скопирует для него параметры из класса с именем OrigWndClassName, а также сохранит адрес

оконной процедуры, связанной с этим классом, в переменной CWindowImplBaseT<>::m_pfnSuperWindowProc и будет обращаться к ней для обработки сообщений, которые не были обработаны через карту сообщений.

С учётом всего сказанного, типичный класс контрола выглядит так.

class CMyCoolControl : public CWindowImpl<CMyCoolControl, CEdit> {

public:

 DECLARE_WND_SUPERCLASS(NULL, CEdit::GetWndClassName)

 BEGIN_MSG_MAP(CMyCoolControl)

// Карта сообщений

 END_MSG_MAP

 …

};

В этом примере новый контрол создаётся на базе поля ввода (которому соответствует класс CEdit). Аналогично используется любой другой контрол.

ПРИМЕЧАНИЕ

Мы уже изучили макрос DDX_CONTROL, входящий в набор макросов DDX. Именно его следует использовать, чтобы связать существующий стандартный контрол (например, нарисованный в редакторе ресурсов) с объектом класса и наделить его дополнительными возможностями.

В библиотеку WTL входит несколько "самодельных" контролов, которые реализованы в файле atlctrlx.h . Вы можете вставлять их в свои программы или использовать как демонстрационные примеры по разработке контролов. Вот список классов, которые написали для вас разработчики WTL.

• CBitmapButton. Кнопка с рисунками.

• CCheckListViewCtrl. Расширенный список с "галочками".

• CHyperLink. Гиперссылка.

• CMultiPaneStatusBarCtrlImpl. Строка состояния с набором панелей.

• CWaitCursor. Курсор типа "песочные часы". Этот класс, в отличие от всех предыдущих, не имеет отношения к контролам.

Поскольку никакой официальной документации на эти классы нет, я приведу их краткое описание. Кроме этого, разобраться с ними вам поможет пример WTLCtlxDemo далее в этой статье.

Класс CBitmapButton

Класс CBitmapButton реализует кнопку, с каждым состоянием которой (нажата/отпущена/выключена/в фокусе) связано изображение. Кроме того, с кнопкой связывается всплывающая подсказка, поясняющая её назначение, и набор расширенных стилей (эти стили не имеют ничего общего с расширенным стилями обычного окна). Каждому стилю соответствует битовый флаг. Полный список флагов приведён в таблице 6.

Флаг Описание
BMPBTN_HOVER Кнопка с этим стилем реагирует на присутствие курсора мыши: если он расположен над кнопкой, она переводится в состояние "в фокусе". Если этот стиль не задан, состояние "в фокусе" присваивается кнопке, на которую установлен клавиатурный фокус ввода. Замечу также, что кнопка со стилем BMPBTN_HOVER не реагирует на клавиатуру, то есть нажать на неё можно только мышью.
BMPBTN_AUTO3D_SINGLE К кнопке принудительно добавляется трёхмерная рамка толщиной в 1 пиксель. Используя этот стиль, вы можете избавиться от необходимости рисовать трёхмерные рамки на всех изображениях, связанных с состояниями кнопки.
BMPBTN_AUTO3D_DOUBLE Аналогичен предыдущему, но к кнопке добавляется рамка толщиной в 2 пикселя (такая, как у всех стандартных кнопок Windows).
BMPBTN_AUTOSIZE Кнопка автоматически масштабируется под размер изображений, которые с ней связаны.
BMPBTN_SHAREIMAGELISTS Кнопка использует разделяемый список изображений. Это означает, что он не будет уничтожен в деструкторе класса CBitmapButton.
BMPBTN_AUTOFIRE Этот стиль имеет отношение к клавиатурному интерфейсу кнопки. Если вы нажали на кнопку, используя клавишу Space, и удерживаете эту клавишу, то кнопка со стилем BMPBTN_AUTOFIRE будет через заданные в системе промежутки времени посылать уведомление BN_CLICKED родительскому окну. Если же этот стиль не задать, уведомление отправится ровно 1 раз – в тот момент, когда вы нажали Space.

Стиль кнопки, а также связанный с ней список изображений, задаются в конструкторе класса CBitmapButton, хотя можно установить/изменить их и позже, используя соответствующие методы. Для задания текста всплывающей подсказки также существуют соответствующий

метод. Полный список методов класса CBitmapButton приведён в таблице 7.

Метод Описание
CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) Конструктор. Параметры – набор расширенных стилей и хэндл списка изображений, который следует связать с кнопкой.
~CBitmapButtonImpl Деструктор. Напоминаю, что внутри деструктора будет разрушен список изображений, связанный с кнопкой в данный момент. Чтобы этого не произошло, следует назначить кнопке расширенный стиль BMPBTN_SHAREIMAGELISTS.
BOOL SubclassWindow(HWND hWnd) Метод для подмены оконной процедуры (т.н. сабклассинга) существующего контрола. Используется макросом DDX_CONTROL, но вы можете вызывать этот метод и сами.
DWORD GetBitmapButtonExtendedStyle Возвращает набор расширенных стилей.
DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) Устанавливает набор расширенных стилей.
HIMAGELIST GetImageList Возвращает хэндл списка изображений.
HIMAGELIST SetImageList(HIMAGELIST hImageList) Устанавливает список изображений.
bool GetToolTipText(LPTSTR lpstrText, int nLength) Возвращает текст всплывающей подсказки.
bool SetToolTipText(LPCTSTR lpstrText) Устанавливает текст всплывающей подсказки (память для него динамически распределяется внутри класса CBitmapButton).
void SetImages(int nNormal, int nPushed = –1, int nFocusOrHover = –1, int nDisabled = –1) Устанавливает соответствие состояний кнопки и изображений в списке. Используйте –1, чтобы оставить соответствующее состояние без изменений. Вы должны задать, по меньшей мере, изображение для состояния nNormal (отпущена), иначе программа не будет работать корректно. Замечу, что вы можете назначить нескольким состояниям одно и то же изображение.
BOOL SizeToImage Принудительно масштабирует кнопку по размеру связанных с ней изображений.
void DoPaint(CDCHandle dc) Эта функция рисует кнопку в одном из четырёх состояний. Вам вряд ли понадобится вызывать её напрямую; зато её можно переопределить в производном классе и придать кнопке нестандартный вид, сохранив при этом остальную функциональность, которую предоставляет класс CBitmapButton.
Класс CCheckListViewCtrl

Из названия может показаться, что этот класс реализует список с галочками (check boxes), но это не совсем так. Стандартный контрол ListView уже поддерживает галочки. Достаточно задать ему расширенный стиль LVS_EX_CHECKBOXES. Что касается класса CCheckListViewCtrl, то он позволяет манипулировать несколькими галочками одновременно. Для этого пользователь выделяет несколько элементов в списке (используя Shift и Ctrl, в списке можно довольно быстро пометить нужную группу элементов). После этого щелчок по галочке любого элемента (или нажатие на Space) будет приводить к изменению состояния галочек у всех выделенных элементов. При необходимости такое поведение контрола можно подавить, удерживая Ctrl (при этом список будет вести себя, как обычный ListView).

Реализация класса CCheckListViewCtrl достаточно очевидна. Метод SubclassWindow подменяет оконную процедуру списка и принудительно устанавливает ему стиль LVS_EX_CHECKBOXES. Всю остальную работу делают обработчики сообщений WM_LBUTTONDOWN, WM_LBUTTONDBLCLK и WM_KEYDOWN. Все они используют для переключения галочек вспомогательную функцию CheckSelectedItems. Вы можете вызывать эту функцию и сами, хотя такая необходимость возникает нечасто. Функция CheckSelectedItems получает единственный параметр – номер элемента (этот элемент должен быть выделен). Она считывает состояние его галочки, инвертирует это состояние и применяет ко всем выделенным элементам в списке.

Резюмируя сказанное выше, для применения класса CCheckListViewCtrl в большинстве случаев достаточно просто связать объект этого класса с контролом, используя макрос DDX_CONTROL.

Класс CHyperLink

Класс CHyperLink предназначен для создания гиперссылок. На самом деле, большую часть функциональности он наследует от базового класса CHyperLinkImpl. Гиперссылка создаётся на основе статического элемента управления.

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

Тройняшки не по плану. Идеальный генофонд

Лесневская Вероника
Роковые подмены
Любовные романы:
современные любовные романы
6.80
рейтинг книги
Тройняшки не по плану. Идеальный генофонд

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Завод-3: назад в СССР

Гуров Валерий Александрович
3. Завод
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Завод-3: назад в СССР

Секретарь лорда Демона

Лунёва Мария
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Секретарь лорда Демона

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Я тебя не отпущу

Коваленко Марья Сергеевна
4. Оголенные чувства
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Я тебя не отпущу

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Девочка из прошлого

Тоцка Тала
3. Айдаровы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Девочка из прошлого

Вернуть невесту. Ловушка для попаданки 2

Ардова Алиса
2. Вернуть невесту
Любовные романы:
любовно-фантастические романы
7.88
рейтинг книги
Вернуть невесту. Ловушка для попаданки 2

Идеальный мир для Лекаря 7

Сапфир Олег
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7

Хозяйка дома на холме

Скор Элен
1. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка дома на холме

Жена проклятого некроманта

Рахманова Диана
Фантастика:
фэнтези
6.60
рейтинг книги
Жена проклятого некроманта

Имя нам Легион. Том 9

Дорничев Дмитрий
9. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 9