フォームが受け取るメッセージを直接調べるため、フォームをサブクラス化する
手順 1
ウィンドウへのメッセージを受け取る、コールバック関数を作成する。
この関数は、引数と戻り値の
型が、次のように決められている。
Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
手順 2 で、この関数のアドレスを使用するので、標準モジュール内に関数を作成する。
(
AddressOf
演算子の解説参照)
この関数には、メッセージが渡される。
メッセージの種類は
uMsg
に格納されている。
目的のメッセージだったら、それに対する処理を呼び、それ以外のメッセージだったら、元のウィンドウプロシージャに、
メッセージをそのまま渡す。
元のウィンドウプロシージャにメッセージを渡すには、
CallWindowProc
を使うが、
このときに、そのプロシージャのアドレスを渡す必要がある。
(手順 2 を参照)
この関数は、戻り値として、適切な値を返さなければならない。
どのような値を返せばよいかは、メッセージごとの解説で、説明してある。
元のウィンドウプロシージャにメッセージを渡したときは、
CallWindowProc
の戻り値をそのまま返せばよい。
手順 2
SetWindowLong
と
GWL_WNDPROC
を使って、コールバックのアドレスを書き換える。
これにより、元のウィンドウプロシージャが呼ばれる代わりに、手順 1 で作成した関数が呼ばれることになる。
また、
SetWindowLong
の戻り値として、元のウィンドウプロシージャのアドレスが返される。
これは、手順 1 で、
CallWindowProc
を呼び出すときや、手順 3 で、サブクラス化を解除するときに必要になるので、
保持しておく。
手順 3
サブクラス化を解除するには、もう一度
SetWindowLong
と
GWL_WNDPROC
を使って、
コールバックのアドレスを元のウィンドウプロシージャに置き換えればよい。
以下は、MSDN ライブラリからの引用です。
関数ポインタの操作は慎重に行う必要があります。DLL を呼び出すと VIsual Basic の開発環境が不安定になりますが、関数ポインタを操作する場合はアプリケーションが停止し、コードが失われることがよくあります。頻繁にファイルを保存し、必要に応じてバックアップをとることをお勧めします。
なるほど。気をつけよう。