수색…


소개

윈도우 서브 클래 싱은 표준 윈도우 프로 시저에 연결하여 기본 동작을 수정하거나 확장하는 방법입니다. 응용 프로그램은 윈도우의 원래 윈도우 프로 시저를 새 윈도우 프로 시저로 바꿈으로써 윈도우를 서브 클래스합니다. 이 새 창 프로시 저는 창에 보내거나 게시 된 메시지를받습니다.

통사론

  • 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 서브 클래스를 식별하기위한 사용자 지정 ID는 서브 클래스 프로시 듀어와 함게 서브 클래스를 고유하게 식별합니다. 단순히 임의의 연속 번호 일 수 있습니다.
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);
    }
}

서브 클래스 프로 시저 설치 및 제거

다음 메소드는 서브 클래스 콜백을 설치하거나 제거합니다. SubclassIdSubclassProc 의 조합은 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 서브 클래스를 식별하기위한 사용자 지정 ID는 서브 클래스 프로시 듀어와 함게 서브 클래스를 고유하게 식별합니다. 단순히 임의의 연속 번호 일 수 있습니다.
RefData 사용자 지정 데이터. 의미는 응용 프로그램에 의해 결정됩니다. 변경되지 않은 방식으로 서브 클래스 콜백에 전달됩니다. 예를 들어 클래스 인스턴스에 대한 객체 포인터 일 수 있습니다.

서브 클래스 콜백은 윈도우의 서브 클래스 체인에서 다음 핸들러를 호출 할 책임이있다. DefSubclassProc 는 윈도우의 서브 클래스 체인에서 다음 핸들러를 호출합니다. 마지막 핸들러는 원래 윈도우 프로 시저를 호출합니다. 응용 프로그램이 메시지를 완전히 처리하지 않는 한 하위 클래 싱 콜백 프로 시저에서 호출해야합니다.

LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
매개 변수 세부 묘사
hWnd 메시지가 발생한 창 핸들
메시지 창 메시지
wParam WPARAM 인수.이 값은 특정 창 메시지에 따라 다릅니다.
파라 패 LPARAM 인수.이 값은 특정 창 메시지에 따라 다릅니다.

SUBCLASSPROC

그것은 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