Szukaj…


Wprowadzenie

Podklasowanie okien jest sposobem na przyłączenie się do standardowej procedury okna i zmodyfikowanie lub rozszerzenie jej domyślnego zachowania. Aplikacja podklasuje okno, zastępując oryginalną procedurę okna nową procedurą okna. Ta nowa procedura okna odbiera wszelkie wiadomości wysłane lub wysłane do okna.

Składnia

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

Parametry

Parametr Szczegół
hWnd Uchwyt okna do podklasy.
SubclassProc Procedura wywołania zwrotnego podklasy.
SubclassId Podany przez użytkownika identyfikator identyfikujący podklasę, wraz z procedurą podklasy jednoznacznie identyfikuje podklasę. Może to być po prostu dowolny kolejny numer.
RefData Dane określone przez użytkownika. Znaczenie jest określone przez aplikację. Jest przekazywany do wywołania zwrotnego podklasy w niezmodyfikowany sposób. Może to być na przykład wskaźnik obiektu do instancji klasy.

Uwagi

Dokumentacja MSDN

Kontrola przycisków Windows w podklasach w klasie C ++

Ten przykład pokazuje, jak manipulować idealnym rozmiarem przycisku, określając stały rozmiar.

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

Instalowanie i usuwanie procedury podklasy

Poniższe metody instalują lub usuwają wywołanie zwrotne podklasy. Połączenie SubclassId i SubclassProc jednoznacznie identyfikuje podklasę. Nie ma liczenia referencji, wywoływanie SetWindowSubclass wiele razy z różnymi RefData tylko aktualizuje tę wartość, ale nie powoduje wielokrotnego wywoływania wywołania podklasy.

BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);

Aby pobrać dane referencyjne przekazane w ostatnim wywołaniu SetWindowSubclass , można użyć metody GetWindowSubclass .

BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Parametr Szczegół
hWnd Uchwyt okna do podklasy.
SubclassProc Procedura wywołania zwrotnego podklasy.
SubclassId Podany przez użytkownika identyfikator identyfikujący podklasę, wraz z procedurą podklasy jednoznacznie identyfikuje podklasę. Może to być po prostu dowolny kolejny numer.
RefData Dane określone przez użytkownika. Znaczenie jest określone przez aplikację. Jest przekazywany do wywołania zwrotnego podklasy w niezmodyfikowany sposób. Może to być na przykład wskaźnik obiektu do instancji klasy.

Wywołanie zwrotne podklasy jest odpowiedzialne za wywołanie następnego modułu obsługi w łańcuchu podklasy okna. DefSubclassProc wywołuje następną procedurę obsługi w łańcuchu podklas okna. Ostatni moduł obsługi wywołuje oryginalną procedurę okna. Powinien być wywoływany w dowolnej procedurze wywołania zwrotnego podklasy, chyba że aplikacja jest całkowicie obsługiwana.

LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Parametr Szczegół
hWnd Uchwyt okna, z którego pochodzi wiadomość
Msg Komunikat w oknie
wParam Argument WPARAM, ta wartość zależy od konkretnego komunikatu okna
Param Argument LPARAM, ta wartość zależy od konkretnego komunikatu okna

SUBCLASSPROC

Jest podobny do wywołania zwrotnego WINDOWPROC ale zawiera dodatkowy argument RefData .

typedef LRESULT (CALLBACK *SUBCLASSPROC)(
    HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam,
    UINT_PTR SubclassId,
    DWORD_PTR RefData
);

Obsługa powiadomień o typowych kontrolach w klasie 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow