|
|
|
2-1-5. プロシージャの仕様としくみウィンドウプロシージャは、クラスを登録すれば、必ず作成しなければいけない関数です。この関数は、Windowsがコールしますので、決まった仕様に基づいてコーディングしなければいけません。LRESULT CALLBACK ApHelloProc(HWND hWnd,UINT uMsg
,WPARAM wParam,LPARAM lParam)
{
static HFONT hFont;
switch (uMsg)
{
case WM_CREATE: // メインウィンドウの新規作成
:
break;
case WM_DESTROY: // ウィンドウの破棄時に発生
:
return 0;
case WM_PAINT: // クライアントエリアの描画
:
return 0;
case WM_COMMAND: // コマンド
:
return 0;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
プロシージャの基本型は、上記の様になります。この関数は、システムがコールするため、CALLBACK 宣言されます。クラスの登録時に WNDCLASS 構造体の lpfnWndProc メンバに、この関数のポインタを設定します。よってグローバルである必要はありませんので、static でもかまいません。Windowsのプログラミングの大部分は、このプロシージャ部のコーディングと言っても過言ではありません。良い事ではありませんが、あちこちにサポート関数を作っても、1、000行を超えることもあります。C++が好まれたのは、この swicth 文の巨大さを解決できたのも1つの理由でしょう。 プロシージャのパラメータ この関数のパラメータは、ウィンドウのハンドルとメッセージ、そして、wParam,lParam のメッセージの追加情報の4つです。hWnd は、ウィンドを識別するハンドルです。1つのクラスで1つのウィンドウを作成するのなら、こんなパラメータは必要ありません。しかし、1つのクラスで複数のウィンドウを作成しますので、今のメッセージがどのウィンドウか識別しなければいけません。それをこのパラメータで行ないます。uMsg はメッセージの番号です。Windowsのメッセージは、WM_CREATE,WM_PAINT,WM_COMMAND などの WM_XXX と言う名前で定義されています。コントロールのメッセージは、EN_XXX などの別の名前があります。またユーザが自由に使うことのできる、WM_USER と言うメッセージもあります。
wParam,lParam は、メッセージの追加データです。よってメッセージによってこれらの内容はすべて異なります。WIN32の場合は、両方とも32ビットの変数で、1つの変数に16+16ビットで値をパックすることが良くあります。その場合は、LOWORD(wparam)や、HIWORD(wParam)のマクロで切り出します。これらの変数はメッセージごとに値が異なりますので、キャストを使わないといけないことが良くあります。 変数は静的変数でないといけません プロシージャ内で、複数のメッセージで参照する変数は、static の静的変数でないといけません。自動変数では動作しません。なぜでしょうか。例えば、作成は WM_CREATE メッセージで、破棄は、WM_DESTROY メッセージで行い、WM_PAINT メッセージで参照をする変数があるとします。この様に各メッセージで共通に使う場合は、絶対に静的な変数でないといけません。Windowsは、1つのメッセージを処理したら、この関数を抜けるので、自動変数では値が保持されないからです。フックとメッセージの処理 プロシージャでは、uMsg のメッセージの内容で,switch 文で分岐します。そして目的に合ったメッセージだけ、case 文でフックして、処理します。他の多くのメッセージは、DefWindowProc 関数に渡され、システムがあらかじめ定めた処理を行ないます。フックとは良い言葉です。必要なメッセージだけ針で引っかけて、処理します。その内容を良く表しています。 各メッセージに対応したプログラムは、ほぼ定型の形式があります。それを理解することが、すなわちWindowsのプログラミングと言っても良いと思います。
|