Поиск…


Вступление

Подклассы окон - это способ подключиться к стандартной процедуре окна и изменить или расширить поведение по умолчанию. Приложение подклассифицирует окно, заменив процедуру оконного окна окна новой процедурой окна. Эта процедура нового окна получает любые сообщения, отправленные или отправленные в окно.

Синтаксис

  • 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);
    }
};


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow