#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следует указать имя класса контрола, который вы взяли за основу. При регистрации вашего класса WndClassNameWTL скопирует для него параметры из класса с именем OrigWndClassName, а также сохранит адрес оконной процедуры, связанной с этим классом, в переменной CWindowImplBaseT<>::m_pfnSuperWindowProcи будет обращаться к ней для обработки сообщений, которые не были обработаны через карту сообщений.
С учётом всего сказанного, типичный класс контрола выглядит так.
class CMyCoolControl : public CWindowImpl {
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.
Читать дальше