サーチ…


前書き

ウィンドウのサブクラス化は、標準のウィンドウプロシージャに接続し、そのデフォルトの動作を変更または拡張する方法です。アプリケーションは、ウィンドウの元のウィンドウプロシージャを新しいウィンドウプロシージャに置き換えることによってウィンドウをサブクラス化します。この新しいウィンドウプロシージャは、ウィンドウに送信またはポストされたメッセージを受け取ります。

構文

  • 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の組み合わせは、 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 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