サブクラス化の概念 †

ウィンドウは飛んできたメッセージを処理するためのコールバック関数?(以下ウィンドウプロシージャ)を必ず持っている
これはどこで設定されているかというと、RegisterClass(Ex含む)でウィンドウクラスを登録する際に設定され
同じウィンドウクラスを持つウィンドウによって共用されている
つまりメッセージに対するウィンドウの挙動を変えたい場合は
ウィンドウクラス登録の際に設定するウィンドウプロシージャを変更すればいい事になる

しかしこれがWindowsが標準で持っているウィンドウクラス(エディットコントロールとか)だったらどうだろう?
これはもうデフォルトのウィンドウプロシージャが登録されてしまっているので変更しようが無いし
仮に変更できたとしても、今度はそのウィンドウクラスを使っている全てのウィンドウの挙動が変更されてしまう
これが望ましくないのは説明しなくてもなんとなく理解できると思う

という事でウィンドウ指定してウィンドウプロシージャを書き換える必要性が出てくる
前置きが長くなったが、これをウィンドウのサブクラス化と呼ぶ

[edit]
用途は? †

標準のウィンドウプロシージャでは処理されないメッセージを処理する場合に使います
処理を書き換えたりメッセージを無視する事もできます
その辺は応用しだいです

[edit]
サブクラス化の手順 †

サブクラス化自体はSetWindowLong関数を使って元のウィンドウプロシージャを新しい物に置き換えるだけです
ただしこれだと元のウィンドウプロシージャがやっていた処理も新しいウィンドウプロシージャに書かなければいけないので
元のウィンドウプロシージャをグローバル変数に取っておき、新しいウィンドウプロシージャで処理しないメッセージが来た時は
元のウィンドウプロシージャを呼び出して処理させます
その際はCallWindowProc関数を使います

流れを書くと
元のウィンドウプロシージャを格納するグローバル変数を用意
新しいウィンドウプロシージャを用意
メッセージを処理した場合は戻り値を0にする(一部のメッセージでは0以外を指定する場合があります)
自分で処理しないメッセージはCallWindowProcで元のウィンドウプロシージャを呼び出して返ってきた値を戻り値にする
SetWindowLongで元のウィンドウプロシージャを新しい物に置き換える
戻り値が元のウィンドウプロシージャのアドレスなので、1で用意したグローバル変数に保存しておく

こんな感じです
必要が無くなったら再度SetWindowLongを使って元のウィンドウプロシージャに戻しておきましょう

[edit]
ウィンドウプロシージャについて †

大層な呼び名ですが実際はただのコールバック関数です
'ウィンドウプロシージャ定義例
Function WndCallBackProc(hWnd As HWND,dwMsg As DWord,wParam As WPARAM,lParam As LPARAM) As LRESULT
Select Case dwMsg
	'メッセージ処理
	'Case WM_KEYDOWNとか
	'処理したらWndCallBackProc=0(例外有り)
	Case Else
		WndCallBackProc = CallWindowProc(元のウィンドウプロシージャアドレス,
			hWnd,dwMsg,wParam,lParam)
End Select
End Function

プロシージャ名は自由に変更して構いません
引数も前から順にウィンドウハンドル、メッセージ、付加情報1、付加情報2の順に並んでる事が分かっているなら
適当な名前に変更して構いません

戻り値はLRESURT型で返します
LRESULT型は32ビット環境ではLong型、64ビット環境ではInt64をTypeDef?したものとなっています

[edit]
使用関数の軽い説明 †

SetWindowLong(hWnd As HWND,nIndex As Long,NewLong As Long) As LONG_PTR
引数(前から順に)
対象となるウィンドウ
セットする値の種類(今回はGWL_WNDPROCを使用)
セットする値(今回は新しいウィンドウプロシージャのアドレス)
戻り値
前にセットされていたLONG_PTR型の値(今回は元のウィンドウプロシージャアドレス)
失敗時は0
LONG_PTR型は32ビット環境ではLong型、64ビット環境ではInt64のTypeDef?

CallWindowProc(lpPrevWndFunc As DWord,hWnd As HWND,Msg As DWord,wParam As DWord,lParam As DWord) As LRESULT
引数(前から順に)
呼び出すプロシージャアドレス
ウィンドウハンドル(ウィンドウプロシージャの第一引数をそのまま渡す)
ウィンドウメッセージ(同じく第二引数)
WPARAM(同じく第三引数)
LPARAM(同じく第四引数)
戻り値
メッセージの処理結果を表すLRESULT型の値

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2010年01月12日 00:04