Win32 API
Подкласс Windows
Поиск…
Вступление
Подклассы окон - это способ подключиться к стандартной процедуре окна и изменить или расширить поведение по умолчанию. Приложение подклассифицирует окно, заменив процедуру оконного окна окна новой процедурой окна. Эта процедура нового окна получает любые сообщения, отправленные или отправленные в окно.
Синтаксис
- BOOL SetWindowSubclass (HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
- BOOL RemoveWindowSubclass (HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
- BOOL GetWindowSubclass (HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR * RefData);
- LRESULT DefSubclassProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
параметры
параметр | подробность |
---|---|
HWND | Ручка окна для подкласса. |
SubclassProc | Процедура обратного вызова подкласса. |
SubclassId | Пользовательский идентификатор для идентификации подкласса вместе с подклассовой процедурой однозначно идентифицирует подкласс. Это может быть просто произвольное последовательное число. |
RefData | Пользовательские данные. Значение определяется приложением. Он передается в обратный вызов подкласса неизмененным способом. Например, это может быть указатель объекта на экземпляр класса. |
замечания
Документация MSDN
Подклассовка кнопок управления окнами в классе C ++
В этом примере показано, как управлять идеальным размером кнопки, задавая фиксированный размер.
class ButtonSubclass {
public:
ButtonSubclass(HWND hWndButton) {
SetWindowSubclass(hWndButton, MyButtonSubclassProc, 1, (DWORD_PTR) this);
}
~ButtonSuclass() {
RemoveWindowSubclass(hWndButton, MyButtonSubclassProc, 1, (DWORD_PTR) this);
}
protected:
static LRESULT CALLBACK MyButtonSubclassProc(
HWND hWnd, UINT Msg, WPARAM w, LPARAM l, DWORD_PTR RefData) {
ButtonSubclass* o = reinterpret_cast<ButtonSubclass*>(RefData);
if (Msg == BCM_GETIDEALSIZE) {
reinterpret_cast<SIZE*>(lParam)->cx = 100;
reinterpret_cast<SIZE*>(lParam)->cy = 100;
return TRUE;
}
return DefSubclassProc(hWnd, Msg, w, l);
}
}
Установка и удаление процедуры подкласса
Следующие методы устанавливают или удаляют обратный вызов подкласса. Комбинация SubclassId
и SubclassProc
уникально идентифицирует подкласс. Нет подсчета ссылок, многократно вызывая SetWindowSubclass
с различными RefData
но обновляет это значение, но не вызывает многократный вызов обратного вызова подкласса.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
Чтобы получить ссылочные данные, которые были переданы в последнем вызове SetWindowSubclass
, можно использовать метод GetWindowSubclass
.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
параметр | подробность |
---|---|
HWND | Ручка окна для подкласса. |
SubclassProc | Процедура обратного вызова подкласса. |
SubclassId | Пользовательский идентификатор для идентификации подкласса вместе с подклассовой процедурой однозначно идентифицирует подкласс. Это может быть просто произвольное последовательное число. |
RefData | Пользовательские данные. Значение определяется приложением. Он передается в обратный вызов подкласса неизмененным способом. Например, это может быть указатель объекта на экземпляр класса. |
Ответный вызов подкласса отвечает за вызов следующего обработчика в цепочке подклассов окна. DefSubclassProc
вызывает следующий обработчик в цепочке подклассов окна. Последний обработчик вызывает первоначальную процедуру окна. Он должен вызываться в любой процедуре обратного вызова подкласса, если приложение полностью не обрабатывается.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
параметр | подробность |
---|---|
HWND | Ручка окна, откуда сообщение возникает из |
Msg | Сообщение окна |
WPARAM | WPARAM, это значение зависит от конкретного окна сообщения |
LPARAM | Аргумент LPARAM, это значение зависит от конкретного окна сообщения |
SUBCLASSPROC
Он похож на WINDOWPROC
вызов WINDOWPROC
но содержит дополнительный аргумент RefData
.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
Обработка сообщений об общих элементах управления в классе C ++
class MyToolbarControl {
public:
MyToolbarControl(HWND hWndToolbar, HWND hWndNotifyParent = nullptr) : _Handle(hWndToolbar) {
if (hWndNotifyParent == nullptr) {
hWndNotifyParent = GetAncestor(hWndToolbar, GA_ROOTOWNER);
}
SetWindowSubclass(
hWndNotifyParent , SubclassWindowProc, reinterpret_cast<UINT_PTR>(this), reinterpret_cast<DWORD_PTR>(this)
);
}
~MyToolbarControl() {
RemoveWindowSubclass(
hWndNotifyParent , SubclassWindowProc, reinterpret_cast<UINT_PTR>(this), reinterpret_cast<DWORD_PTR>(this)
);
}
protected:
HWND _Handle;
static LRESULT CALLBACK SubclassWindowProc(
HWND hWnd, UINT Msg, WPARAM w, LPARAM l, UINT_PTR SubclassId, DWORD_PTR RefData) {
MyToolbarControl * w = reinterpret_cast<MyToolbarControl *>(RefData);
if (Msg == WM_NOTIFY) {
NMHDR* h = reinterpret_cast<NMHDR*>(l);
if (h->hwndFrom == w->_Handle) {
// Handle notification message here...
}
}
return DefSubclassProc(hWnd, Msg, w, l);
}
};