|
|
|
1-3-5. クラスとウィンドウの作成クラスの登録 Windowsのアプリケーションでは、ウィンドウクラスを登録し、ウィンドウを作成する必要があります。例外的に、メッセージボックスだけとか、コンソール仕様のアプリケーションとかありますが、通常は、クラスを登録して、ウィンドウを作成します。 WNDCLASSEX wc;
static LPSTR pClassName = "ApHelloClass";
static LPSTR pAppName = "ApHello";
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)ApHelloProc; // (A)プロシージャ
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance,pAppName);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = pAppName;
wc.lpszClassName = pClassName;
wc.hIconSm = LoadImage(hInstance,pAppName,IMAGE_ICON
,16,16,LR_DEFAULTCOLOR);
if (!RegisterClassEx(&wc)) return FALSE;
上記のコードでクラスを登録します。このコードの要は、(A)のプロシージャを登録している部分です。プロシージャとは、システムがコールする関数です。何かあるとシステムは、メッセージと言う形で、ユーザが作成したこの関数をコールします。逆に言うとクラスとは、プロシージャを登録するための手段です。ウィンドウを作成するためには、必ずクラスを登録しなければいけません。違う種類のウィンドウは、別のクラスを登録しますが、同じ種類や似たウィンドウは、同じクラスを使います。つまりクラスとウィンドウは1対多の関係です。前にハンドルの説明をしました。ウィンドウはハンドルで識別しますが、クラスにはハンドルはありません。クラスを識別するのは名前です。wc.lpszClassName で設定した名前がクラス名になりこの名前で識別します。
クラスでは、ウィンドウの基本的な型も設定します。style でスタイルを、hIcon,hCursor,hbrBackground,lpszMenuName でそれぞれ、アイコン・カーソル・背景色・メインメニューを定義します。これらは、ウィンドウ別の違いはあまりありませんので、ここで設定しておけば簡単です。しかしここでは指定せずに、ウィンドウの作成時点で設定したり、途中で変更したりすることも可能です。
cbSize と言う変数があり、これに構造体のサイズを設定していますが、なぜでしょう。WIN32では、良く使う技法です。これには2つの大きな意義があります。まず改訂による拡張機能との互換性をこれで吸収します。
では1行づつ見てみましょう。最初の行は、クラス構造体を宣言しています。次ぎの2行で、クラス名、そしてアプリケーション名を定義しています。ここでは、関数内で、static 宣言していますが、もし他の関数で使用するときは、外に出し、他のファイルで使用するときは、static 宣言をやめ、グローバル化します。 ウィンドウの作成 クラスの登録が終われば、ウィンドウを作成します。CreateWindow を使用しますが、この関数は、システムで既に登録しているクラスである「コントロール」の作成にも使用しますので、非常にたくさんのバラエティがあります。しかし、コントロール関係以外は比較的簡単です。 hWndMain = CreateWindow(pClassName,NULL,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
if (!hWndMain) return FALSE;
SetWindowText(hWndMain,pAppName);
ShowWindow(hWndMain,nCmdShow);
UpdateWindow(hWndMain);
CreateWindow 関数は、まずクラス名を指定してクラスを識別します。次のNULLは、ウィンドウのタイトルは設定しないことを示しています。SetWindowText 関数が後にありますが、これと同じ動作を行ないます。次がウィンドウのスタイルを設定するパラメータです。ウィンドウは、オーバーラップとポップアップ、そして子ウィンドウの3つの大きなタイプがあります。通常のアプリケーションのはオーバーラップウィンドウです。一時的な表示を行なうのが、ポップアップウィンドウで、ウィンドウの中に子ウィンドウを設定することもできます。 つぎの4つが、起動時のウィンドウの位置とサイズです。矩形では無く左上の位置と幅と高さを設定します。すべて、CW_USEDEFAULT ですが、これはシステムのデフォルト値を指定します。これを指定すれば、スクリーンの解像度に合わせて適当な位置に、適当な大きさのウィンドウを作成します。実に、安直で無責任な指定です。普通はウィンドウの位置やサイズは、前回の終了時点を再現することが多いので、レジストリから読み込んで設定する方法が一般的でしょう。またここではすべて0を設定して、WM_CREATE やその他のメッセージで設定することもあります。 次が親ウィンドウのハンドルです。NULL なのは、これがトップウィンドウで親が無いことを示します。前記の子ウィンドウを作成する場合に使用します。次ぎはメインメニューのハンドルを指定します。ApHelloではクラスでメニューを指定しますので、ここは NULL にします。hInstance でインスタンスハンドルを指定します。これはウィンドウはクラスとインスタンスに関連付けられていることを表します。つまりアプリケーションを終了し、インスタンスが破棄されると、このウィンドウも破棄されることを意味します。 最後のパラメータは、WM_CREATE メッセージに渡すパラメータを指定します。ちょっと違うウィンドウの場合は、その違いをこのパラメータを通じて、プロシージャに知らせることもできます。この技法も良く使われています。
CreateWindow はHWNDのウィンドウのハンドルを返します。NULL ならエラーですので終了します。SetWindowText 関数はウィンドウのタイトルを設定します。ApHelloの場合は、変更の必要がないので、CreateWindow の二つ目のパラメータで指定しても良かったのですが、データファイルを使う場合は、それをタイトルにしますので、通常は、SetWindowText 関数を使ってウィンドウのタイトルを設定します。
|