スケルトンプログラムの導入、ウィンドウクラスとメッセージハンドラ -002-
前へ TOPへ 次へ

仕組みと解説

さて,前ページで見たように,最も小さいWindowsアプリケーションでも、こんなに大きくて複雑になってしまう理由には,このOSが持つ2つの性質が挙げられます。 一つは、Windowsが複数のプログラムを時分割で「同時に」動作させるOS(この性質をmulti-taskという)で,かつ同時に複数回同じアプリケーションの起動を許している(この性質をre-entrantという)事。 二番目は、Windowsアプリケーションは、事象駆動型(この性質をevent-drivenという)であり、OSがアプリケーションに、ウィンドウの管理をする責任を任せているという性質です。

それではまず、このプログラムの流れはどうなっているのかを簡単に説明します。 プログラムを見るとWinMain()と、WindowProc()という2つの関数があります。 Windowsアプリケーションでは、プログラムが実行されるとまずWinMain()が呼ばれる仕組みになっているのですが、それにしてもWindowProc()を呼んでいる部分が見当たりませんね。 いったいWindowProc()はどのようにして呼ばれるのでしょうか? ソースをよく見ると、ウィンドウクラスを定義している部分で、

というような記述があって、WindowProc()関数へのポインタを渡していることから、どうやらウィンドウクラスというものに何か秘密がありそうです。 前のページのソースをざっと見て、この点に気がついたアナタはなかなか目の付け所がいいですね! プログラムの大まかな流れは以下の図の通りです。

プログラムの流れ

WinMain関数とWindowProc関数はWindowsAPIプログラムの中で中核となる関数で、基本的に独立なプロシジャです。 WinMain関数はそのプログラム独自のウィンドウ(窓)を1つ生成し,そのウィンドウにWindowProc関数を1つ割り当てています。 WinMain関数はまた,GetMessage関数で抽出してきたOSからのメッセージをDispatchMessage関数でWindowProc関数に配達(dispatch)します。 WindowProc関数のほうでは、OSから降りてきたメッセージ種類(例えばマウスイベント発生、ウィンドウ消去イベント発生など)毎にプログラムロジックを分割しておき、それぞれ必要なデータ処理を行います。

処理の流れ

以下にそれらの説明をします。

WinMain

さてこのWinMain関数の引数ですが、標準のmain関数とは打って変わって何だか不可解なものばかりですね。
第1引数と第2引数のHINSTANCEという変数型はインスタンスハンドルと言って、実行するアプリケーション毎に異なった数字が割り当てられる、アプリケーションを識別するためのものです。UNIXのプロセスIDに相当する用語です。 Windowsでは基本的に同じアプリケーションを同時に複数実行することができるので(=リエントラント可能という)、単にアプリケーション名だけでは区別できない場合があるんですね。 そのため、実行されているアプリケーションにそれぞれ固有の番号を振って、これで識別しているんです。これがインスタンスハンドルなんですね。
コマンドライン引数というのはmain関数でもありましたね。コマンドラインからオプションを指定してアプリケーションを実行することができ、その引数への文字列型ポインタがlpszArgsです。 main関数と大きく異なるのは、main関数では引数をスペース毎に区切って渡してくれましたが、WinMainではコマンドラインの文字列をそのまま渡してくるだけで、複数の引数を渡す場合は自分で解析しなければなりません。 なお、この変数型LPSTRはchar*と同じものと考えて差し支えないです。実際、ここで得られた文字列を、従来のstrcpy等の文字列操作関数で処理することができます。

RegisterClassEx

この関数はCreateWindow(または同Ex)関数でウィンドウを作成する前にウィンドウクラスを定義しておくのに用いる。 入力引数であるlpwcxは構造体へのポインタとなっており、この構造体に予め適切なクラス属性を入れておく。 関数が正常終了すると,登録されたクラスを識別するアトムが関数の戻り値としてリターンされる。 異常終了の場合は,戻り値に0が返る。
WNDCLASSEX構造体は以下の通り

CreateWindow

いわゆるウィンドウを作成する関数。 ウィンドウには通常のウィンドウ(オーバラップウィンドウ)、ポップアップウィンドウ、サブウィンドウなどが含まれる。 ウィンドウの作成には上記のRegisterClassExによるウィンドウクラス登録、ウィンドウタイトル情報、ウィンドウの初期位置情報などが必要である。

関数が正常終了すると、作成されたウィンドウのハンドルが戻り値としてリターンされる。
異常終了の場合は、戻り値にNULLが返る。
  また、この関数が成功するとWindowProc関数宛にWM_CREATEメッセージを発行する。


前へ TOPへ 次へ