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 | サブクラスを特定するためのユーザ指定の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);
}
}
サブクラスプロシージャのインストールと削除
次のメソッドは、サブクラスのコールバックをインストールまたは削除します。 SubclassId
とSubclassProc
の組み合わせは、 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);
}
};