アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

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)のマクロで切り出します。これらの変数はメッセージごとに値が異なりますので、キャストを使わないといけないことが良くあります。
 WIN16のころは、名前の様に、wparam は、WORDで16ビットでした。よってWIN16から、WIN32への移植の場合は、これらのパラメータの扱い方が一部異なりますので注意してください。

変数は静的変数でないといけません

 プロシージャ内で、複数のメッセージで参照する変数は、static の静的変数でないといけません。自動変数では動作しません。なぜでしょうか。例えば、作成は WM_CREATE メッセージで、破棄は、WM_DESTROY メッセージで行い、WM_PAINT メッセージで参照をする変数があるとします。この様に各メッセージで共通に使う場合は、絶対に静的な変数でないといけません。Windowsは、1つのメッセージを処理したら、この関数を抜けるので、自動変数では値が保持されないからです。

フックとメッセージの処理

 プロシージャでは、uMsg のメッセージの内容で,switch 文で分岐します。そして目的に合ったメッセージだけ、case 文でフックして、処理します。他の多くのメッセージは、DefWindowProc 関数に渡され、システムがあらかじめ定めた処理を行ないます。フックとは良い言葉です。必要なメッセージだけ針で引っかけて、処理します。その内容を良く表しています。  各メッセージに対応したプログラムは、ほぼ定型の形式があります。それを理解することが、すなわちWindowsのプログラミングと言っても良いと思います。

ページ移動