Visual Basic 業務アプリ構築法 第1回

Windowsの仕組みとWindowsアプリケーションの構造
長谷川裕行
1998/04/01

長谷川 裕行 (はせがわ ひろゆき)
有限会社 手國堂 代表取締役
http://www.hirop.com/
テクニカルライターとして活躍。プログラミングに関する著書多数、DB Magazineなどにも多くの記事を提供している。

VBによる業務アプリケーション構築に関して

Windows95とWindowsNTのOSとしての構造は、実際にはまったく別物といえるほど異なっています。が、ユーザーから見える部分はもちろん、一般的なプログラミングの視点からも、両者の違いはほとんど見えなくなっています。そのため、ここでは両者を「Windows」とまとめて表現します。

汎用機やオフコンで主にCOBOLなどの言語を使って業務用アプリケーションを組んでいたプログラマーにとって、Windowsという環境はまったくの別世界のように映ります。C++やVBなどソースの書き方の相違にとどまらず、プログラムの設計に対する考え方、構え方自体が大きく異なっているかのように見えるためです。

しかし実際には、汎用機だろうとパソコンだろうと、VBだろうとCOBOLだろうと、最終的にユーザーの求めるものは同じはずです。むしろ、パソコンのC言語やアセンブラでゲームプログラミングをしてきた人の方が、現在のWindowsプログラミングに大きな壁を感じているようです。

かつてパソコンで主流だったMS-DOS(以下、DOS)では、ハードウェアの性能を十分に引き出す高度なプログラミングを行うには、OSの中枢部分、あるいはそれを飛び越えてハードウェアを直接操作する必要がありました。が、Windowsでは、OSがプログラミングのために提供する機能だけを使ってプログラミングすることが大前提となります。

特にオブジェクト指向の考え方は、自由に振る舞えたDOSの世界とは大きく異なるため、大きなギャップを感じてしまう部分です。逆に、元々システム的な制約の中で既存の機能を組み合わせて処理を構築するという技法を身に着けている人たち--つまり、汎用機やオフコンの世界でプログラムを作っていた人たちの方が、オブジェクト指向やVBなどのRADツールの世界になじみやすいのだと思います。

ここでは、汎用機やオフコンでのプログラミングを経験してきた人たちを対象に、Windows環境下でのVBによる業務用アプリケーション構築のための様々な情報を提供していきたいと思います。



Windowsの仕組み

- API関数 -

すべてのハードウェアをWindowsが管理しているため、Windowsプログラミングではハードウェアを操作するあらゆる手段をWindowsに委ねます。そのための機能として、WindowsにはAPI(Application Programming Interface)関数が用意されています。

画面への表示もファイルの読み書きも、すべてAPI関数を使って処理します。API関数はプログラミングツール(処理系)の側ではなく、Windowsの側に組み込まれた機能です。汎用機やオフコンの特にCOBOLなどの高級言語では、必要な処理はすべてライブラリ化されているため、プログラムからOSの持つ基本機能を直接呼び出すことはありません。ところがC言語によるWindowsプログラミングでは、このAPI関数の呼び出しによって処理を進めるという手法が一般的です。

一方C++のようなオブジェクト指向言語では、Windowsの持つAPI関数を呼び出す部分は、それを覆い隠したクラスライブラリという形で提供されるため、プログラマーはAPI関数の存在を意識しなくて済みます。


- メッセージとイベント駆動 -

Windowsとアプリケーション

Windowsはマルチタスクとなっており、同時に複数のアプリケーションを起動できます。しかし、基本的にユーザーから見たOSの動きは、「一時に1つのアプリケーションしか動作していない」ことになっています。複数のアプリケーションが同時並列的に動作するのではなく、ユーザーからの操作を受け取れる1つのウィンドウだけが有効なのです。

ユーザーから操作を受け取れるウィンドウを「アクティブである」と言います。日本語で言う「活性化されている状態」です。アプリケーションは最低1つのウィンドウを持っていて、そのときその時点でアクティブになっているウィンドウを持っているアプリケーションだけが、動作している--ということです。

実際には、アプリケーションはもっと複雑な規則に基づいて管理されているのですが、ここではこのように概略的に受け止めておいてください。


メッセージを処理する

さて、アクティブなウィンドウはどうやって処理を進めるのでしょう?
ユーザーがマウスを動かしたりキーボードを操作したりすると、その信号はWindowsに送られます。Windowsは受け取った信号を、「メッセージ」という形でアクティブなウィンドウを持つアプリケーションに送ります。メッセージは16ビットの整数ですが、プログラムで扱いやすいように"WM_PAINT"、"WM_MOUSEMOVE"などの名前が付けられています。


メッセージの種類は、例えば以下のようになっています。

WM_PAINT:ウィンドウ内を再描画する必要が生じた
WM_MOUSEMOVE:マウスが動いた
WM_LBUTTONDOWN:左ボタンが押し込まれた
WM_RBUTTONCLICK:右ボタンがクリックされた
WM_QUIT:終了せよ


イベント駆動型アプリケーション

このようにメッセージは、「アプリケーションが何をしたらよいか」を知らせるものとなっています。従ってアプリケーションは、Windowsから送られてくるメッセージを受け取り、その内容を判断して適切な処理を実行すればよいことになります。

例えば、ウィンドウ内のある部分で左ボタンがクリックされたら、アプリケーションには"WM_LBUTTONDOWN"というメッセージが届きます。メッセージには「そのときのマウスポインタの座標」がパラメータとして付属してくるので、アプリケーションはそのメッセージを受け取ると、マウスがクリックされた場所を判断して「その場所でマウスの左ボタンがクリックされたときに行うべき処理」を実行します。
このように、WindowsアプリケーションはWindowsから送られてくるメッセージ、つまりユーザーの操作などの「出来事」(イベント)をきっかけとして処理を進めるので、この構造を「イベント駆動」(Event driven)方式と呼びます。


Windowsアプリケーションの構造

- アプリケーションを構成する2つの機能 -

Windowsアプリケーションの実行部分は、大きく2つの機能に分かれます。1つはWindowsから送られてくるメッセージを待ち受ける部分、もう1つは受け取ったメッセージによって実際の処理を行なう部分です。

Windowsがアプリケーションに送るメッセージには、上記以外にも非常にたくさん存在します。しかしアプリケーションは、その中から自分にとって必要なものだけを処理して構いません。

あるアプリケーションが、画面の描画(これは必須の機能です)、マウスの左ボタンクリックの2つのイベントによって処理を行なうなら、それ以外のメッセージが送られてきても無視して構わないのです。



- メッセージループ -

メッセージを待ち受ける部分では、送られてきたメッセージを判断し、それが画面の描画(WM_PAINT)であれば「画面を描画する処理」を実行し、左ボタンのクリック(WM_LBUTTONDOWN)だったら「左ボタンがクリックされたときに行う処理」を実行します。

そしてまた、Windowsからのメッセージを待ちます。要するに、以下のような構造となっている訳です。

ユーザーがメニューから「終了」を選んだような場合には、アプリケーションに対してWindowsから「アプリケーションを終了せよ」(WM_QUIT)というメッセージが送られてきます。メッセージを待ち受ける部分は、Windowsから"WM_QUIT"メッセージがくるまで、「処理を終えてはメッセージを待つ」という動作を繰り返すことになります。

そのためこのメッセージを待ち受ける処理の部分を「メッセージループ」と呼んでいます。


- メッセージ応答部分 -

受け取ったメッセージごとに、実際の処理は異なります。そのためメッセージ処理部分は、処理するメッセージよっていくつかのブロックに分かれます。これを「メッセージ応答処理」などと呼びます。

マウスの左ボタンがクリックされたときの応答処理には、他のメッセージに関する処理を一切意識することなく、左ボタンがクリックされたときに行わせたいプログラムだけを記述すればいいのです。

Windowsでは、このようなメッセージ応答処理が「処理させたいメッセージの数だけ」存在します。


- ループと分岐 -

メッセージ待ちの構造は、先述したようにループ構造となります。いわゆる「繰り返し」です。一方、メッセージ待ちで受け取ったメッセージをメッセージ応答処理の部分に送る箇所は、「メッセージが"WM_PAINT"だったら"WM_PAINT"に応答する処理を実行する」というように、条件分岐の構造となります。

Windowsアプリケーションは、従来の一般的なプログラミングのように「上から下への」シーケンシャルな(順次直列的な)処理の流れではなく、極めてランダムな処理の流れを形作ります。これが、従来のプログラミングに馴れた人を面食らわせてしまう部分です。

しかし、繰り返しと条件分岐はプログラミングの最重要機能です。この2つの機能を使わないプログラムなど存在しません。COBOLで作成したアプリケーションで、メニュー処理を行なう場合を考えてください。

1.ユーザーのキー入力を受け付ける

2.受け取ったキーの内容を元に、処理を分岐する

 [1]なら伝票入力
 [2]なら伝票訂正
 [3]なら伝票集計
 [4]なら伝票発行
 [5]なら終了

3.対応する処理を実行する

4.1.に戻ってキー入力を待つ

といった感じになっていると思います。今説明してきた、Windowsアプリケーションの構造とまったく同じだということが分かりますね。

Windowsアプリケーションの構造は何も特別なものではありません。このように、私たちがこれまでやってきた通常のメニュー処理と、基本的には何ら変わらないのです。ただ、アプリケーション全体がこのような二重構造となっているため、またその構造を維持するためにWindowsの機能を使わなければならないため、まったく別物のように映っているだけなのです。
Copyright © MESCIUS inc. All rights reserved.