(補足)VisualBasicの基本と先週の補足説明

 VisualBasic(以下VB)を利用するにあたって,その基本的な考え方を整理しておく必要がある.ここでは,プログラムを作成する上で重要であるオブジェクトの考え方とイベントの考え方について述べる.

 VBはオブジェクト指向的な言語であり,オブジェクトの概念を理解しておくことは極めて重要である.このことはC++やJAVAといったオブジェクト指向の言語にも通じるものであるので,十分に理解して欲しい.
 オブジェクト(object)とは日本語訳すれば,物体と訳される.自分の身のまわりのもの,たとえば机上にある鉛筆,ノート,ノートパソコンなどもすべてそれぞれが1つのオブジェクトとして捉えられる.
 ここで自動車を例として考えてみよう.自動車を1つのオブジェクトと考えることもできるが,1台の自動車に注目した場合,それは多くの部品から構成されている.オブジェクトという考え方からすれば,これらを構成する部品,ひとつひとつがオブジェクトと考えてもらえればよい.
 ここで話を簡単にするために,自動車はボディとタイヤとアクセルペダルから構成されるとしよう.
 自動車メーカーがボディを作成したとする.そのボディは材質や形状,大きさなどそのボディ固有の特徴を有している.つまり,これらはボディの属性であり,ここではプロパティという言葉を用いる.つまり,ボディのプロパティとして材質や形状,大きさ,色などがある.ボディのオブジェクト名をここでは英語でBodyとし,これらのプロパティを以下のように表現する.
 

 つまり,Body.Materialというように,オブジェクトの有する属性を表現するのである.
 次にこのボディにタイヤをつけよう.タイヤはそのサイズと材質などの属性を有しており,これらによって定義されるオブジェクトである.ここでタイヤのオブジェクト名をtireとして表現すれば,これらのプロパティは以下のように表現されるわけである.
   このボディに合うタイヤの大きさは直径14インチのタイヤである.しかし,あいにくタイヤ工場ではある1種類のタイヤしか生産していないとしよう.それは直径20インチ,幅300mm,金属製というタイヤである.とりあえずは,これをタイヤ工場から持ってくるわけではあるが,このままでは到底利用できない代物である.そこで自動車工場はそのタイヤを加工し,作成したボディに適合するようにするわけである.
 この加工作業はTireというオブジェクトのプロパティを変えることにほかならない.この作業は,以下のように表現される.  上の式 = は「右辺を左辺に代入しなさい」という意味をもつ.つまり,「タイヤサイズを14にしなさい」,「タイヤの材質をラバー(ゴム)にしなさい」という命令である.
 次にこの車にアクセルペダルをつけよう.このアクセルペダルは,エンジンと一体化したものと考えていただきたい.そして,それを踏むことにより,タイヤが回転し,またそれを離すことによってタイヤが停止すると考える.
 アクセルペダルは常にそれが踏まれたか否かを判断している.そしてアクセルペダルが踏まれるという事象が発生すれば,それに応じてタイヤを回転させる作業を行う.ここで事象ということをイベント(event)と呼ぶ.
 たとえば人間は痛みを感じると「痛い」「痛!」「イテッ」「イデ(これは津軽弁か..)」などと言うであろう.たとえば腕をつねられた場合,それはつねられた場所から電気信号として大脳に送られ,それを解釈し,さらにそれを言語として「痛い」と発声するということである.つまり人間の皮膚自体も常にイベントを監視しており,何らかのイベントが発生した場合にそれに応じてどういう行動をすべきかプログラミングされているわけである.
 ここで再び自動車の話に戻れば,アクセルペダルは常にそのイベントを検知しているが,アクセルペダルが押されたという事象が発生した場合にタイヤに対して「回転しなさい」「回転しろ!」「すみませんが回転していただけませんか」...と命令しなければならない.
 これはタイヤに対する命令である.タイヤ自体は回転することが仕事であるから,自分自身,どういう命令をされれば回転すべきかを知っている.ここでタイヤは「Roll」と英語で言われなければ動かないとしよう.これはタイヤ自身にプログラムされているものであり,ここでメソッドという.
 つまりアクセルペダルは,それを踏まれたことによってタイヤに対して「Roll」という命令を行えばタイヤは回転する.ここでアクセルペダルが踏まれたというイベントをPedal_Pushとし,これをVB風に書けば以下の通りになる.  実際の自動車にはタイヤが4つある.そのため,Tire1,Tire2,Tire3,Tire4というようにオブジェクトを4つ作るか,あるいはTire(0 To 3)を配列として定義し,Tire(0),Tire(1),Tire(2),Tire(3)というようにオブジェクト配列として扱うのが有効であろう.それを駆動方式に応じてどのタイヤをまわすかの命令を送ればよいことになる.(例えば前輪駆動の場合には,前輪だけをまわすという命令を送る).

 以上がVBのプログラミングにおいて基本となるオブジェクトとイベントの考え方である. これらの考え方をもとにVBの構造について説明してみよう.

 まずVBを起動し,新規で標準EXEを選択する.これにより,あらかじめ定義されたForm1のウィンドウが作成される.これがさきに述べた自動車の例でいえば,ボディに相当するものである.ボディすなわちForm1の大きさや色などはForm1のプロパティを操作することによって,変更できる.Form1をクリックし選択した上で,右下に表示されるプロパティウィンドウに,設定されているプロパティの状態が表示されている.
 プロパティウィンドウの中でプロパティの初期値を直接的に操作することも可能である.たとえば,プロパティウィンドウの中で,BackColorというプロパティはForm1の背景となる色を決定しているが,それの...をクリックすると色設定の画面が表示されるので,それで適当な色を設定してみよう.
 この操作により,実際にはプログラムが起動すると初期的に以下の操作が行われることを意味している.

 これでボディとなるForm1が配置されたので,次にオブジェクト,つまり部品(車の例でいえばタイヤ等)を配置していくことになる.そのオブジェクトのもとになるのがコントロールである.画面左に表示されているコントロールウィンドウは,その部品集である.この部品をForm1上に配置することによって,オブジェクトとして認識され,オブジェクト名が自動的に与えられる.
 例としてテキストボックスというコントロールを用いる.コントロールウィンドウの中でテキストボックスコントロールを選択し,Form1のウィンドウ上で適当な大きさで左上から右下方向にドラッグする.これにより,テキストボックスがText1というオブジェクト名で作成される.
 作成されたText1というオブジェクトがどのようなプロパティを持っているかを確認するためには,Form1上に作成されたText1のテキストボックスを左クリックにより選択すれば,プロパティウィンドウにそのプロパティが表示されることになる.
 ここでText1のTextというプロパティを選択し,ここに適当な文字を入力してみる.例えば,「Text Boxのテスト」と入力すれば,その情報が初期値としてText1のテキストボックスに表示される.
 この操作は,初期的に以下の設定が行われていると考えればよい.  次にコマンドボタンというコントロールについて説明しよう.とりあえずコントロールウィンドウからコマンドボタンコントロールを選択し,それをForm1上に配置する.これによりボタンがForm1上に配置され,そのオブジェクト名はCommand1として設定される.Command1のプロパティの中にCaptionというプロパティがあるが,このプロパティがボタン上に表示される文字を決定している.コマンドボタンでは,初期状態ではCommand1と表示されているが,この値を変更すれば,その値が変更されることになる.
 なお初期的に設定されるオブジェクト名(Form1,Text1,Command1等)はその名前の変更が可能であり,それはプロパティウィンドウの中の「(オブジェクト名)」を変更すればよい.例えば複数のコマンドボタンを配置するような場合には,その意味がわかるようなオブジェクト名を与えた方がわかりやすい.
 このボタンは押す(クリックする)ために作られたオブジェクトである.つまり,このオブジェクト自身が,それに対する操作を検知している.つまり,さきの自動車の例でのアクセルペダルにあたる.
 ここで作成されたCommand1のコマンドボタンがマウスのどのような操作を感知できるかについて確認しておこう.プロジェクトウィンドウ(画面右上に表示されている)の中からForm1を選択し,コード表示ボタンを押す(あるいはForm1を右クリックして「コードの表示」を選択)ことにより,そのコードが表示される.コードウィンドウ上部に2つのプルダウン可能なボックスが並んでいる.左側のボックスのプルダウン▼からCommand1を選択し,右側のボックスのプルダウン▼をクリックすれば,検知できるイベントの一覧が表示される.ここで左側でCommand1,右側でClickを選択する.
 この操作により,コードウィンドウの中に以下のコードが表示される.

Private Sub Command1_Click()

End Sub

このPrivate Sub ....とEnd Subの間にCommand1ボタンを押したというイベントが発生した場合のプログラムを記入する.

Private Sub Command1_Click()
    Text1.Text = "Command1がクリックされました"
End Sub

このプログラムを実行すれば,Text1のボックスに表示される文字が変わることになる.

それでは先週作成したプログラムについて,再度検証してみよう.
1)PictureBoxをForm1上に配置するということ.
 PictureBoxコントロールを配置することによって,Picture1というオブジェクトが作られる.
 Picture1を配置することにより,そのサイズに応じた画像を格納するためのメモリ空間が確保されると考えればよい.

 ここで額縁の絵を考えてもらいたい.額縁がFormであり,それに絵すなわちPicture1があると思ってもらえばよい.額縁上に配置した絵は初期状態では真っ白な画用紙であり,この画用紙は格子状に区切られていると考える(図工用紙に近い).その格子はそれぞれ番号がつけられており,例えばその画用紙に区切られた格子が100×100の格子であったとすれば,その格子は左上を(0,0)として横方向に(99,0)まで,縦方向に(0,99)まで表され,つまり右下の格子は(99,99)として表される.またひとつの格子の色の表現力は1677万色(24bit;3バイト)である.つまり,これらの格子ひとつひとつに色を設定することによって絵を表現するのである.
 これらの画用紙上に区切られた格子それぞれがコンピュータでの画素単位ピクセルに相当する.つまり,このピクセルひとつひとつに色を与える.なお,Picture1がこのようなピクセル単位の座標系を有するということを指定しておく必要がある.この設定は,プロパティPicture1.ScaleModeにより定義されるので,事前に以下の命令をしておくか,初期的にプロパティウィンドウからその設定を変えておく必要がある.

     Picture1.ScaleMode = 3
 
ScaleModeの数値はあらかじめVB上において定められている数値であり,この値はプロパティウィンドウの中でも確認することが可能である.さらにVB上ではあらかじめ定められた定数を有している.
ここでは用いるvbPixels=3とあらかじめ定めれている.(vb上で定められた定数は頭2文字がvbである)
 なお,定数については,ユーザーがプログラム内で定義することも可能である.例えば円周率をあらかじめ定義しておきたい場合には,
 CONST PI = 3.1415
などと定めておけば,円の面積を求める場合にPI*R^2という式の中で自動的に3.1415が与えられる.
(ただしサブルーチン外で定義する必要がある)

 画像上のひとつひとつのピクセルに対して色を設定するために,PictureBoxコントロールは以下のようなメソッドを有している.

  object.Pset(x, y), Color

 ここで(x,y)はピクセルの座標,Colorは色の情報(0から1677万までの整数)である.
 たとえば,Picture1の(5,10)のピクセルに色を与えたいという場合には,

  Picture1.Pset(5,10)
 
とPicture1に対して命令すれば,該当するピクセルの色を変えることが可能である.

 さてここで画像ファイルから色情報を読み込むということを考えてみよう.
画像ファイルの構成は,通常,画像形式,幅,高さ,色のモード(何ビットカラーか)というような情報が記載されたヘッダー部分とそれに続いて画像情報がシーケンシャルに記載されている.これらの情報を読み込みながら,それを解読してPset関数でPicture1の各画素に色を設定することも可能である.しかしながら,これをいちいちプログラムすることは容易ではないことから,VisualBasicにはLoadPictureという関数がある.これによって,画像ファイルから各ピクセルの色情報を読み込み,それを表示するということを自動的に行ってくれる.この画像情報の受け口がPicture1.Pictureプロパティであり,それに対して画像情報を与えるということから,以下のようなコードが記載されるわけである.

  Set Picture1.Picture = LoadPicture("C:\CG\PIC\field.jpg")

 次に表示された画像の指定した格子つまりピクセルが有する色情報を知りたいという場合に用いるのが,Point関数である.このPoint関数は,メモリ上に格納された画像情報にアクセスし,該当するピクセルの画像情報を得てくるのである.
 例えば,以下の式は,ピクセル座標(5,19)の画像情報がText1.Textに出力する.
 
 Text1.Text = Point(5,19)

 ここで色情報を受け取りたいピクセル座標をプログラム内であらかじめ指定しておくとは現実的ではない.そこでマウスをクリックした場所の座標値を得るということを行う.ここでPicture1_MouseDownというイベントを利用する.このイベントは,どのボタンが押されたか,シフトが押されているか,クリックした位置の座標を返してくれる便利なイベントである.
 
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

End Sub

(コードウィンドウの上部の2つのボックスから選択するようにすること.自動的に上記コードが作成される)

このイベントによって得られるX,Yの値をPoint関数に受け渡すことによって,マウスをクリックした場所の色情報を得ることができる.Text1に出力するコードは以下のようになる.

Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbRightButton
     Text1.Text=Picture1.Point(X,Y)
    End IF
End Sub
(ここで用いているvbRightButtonも定数)

演習は色をさらにShapeに与えてやろうというものである.まずShapeコントロールをForm1上に配置し,Shapeプロパティを確認しよう.Shapeは長方形や円などを簡単に作成するために作られたコントロールである.
Shapeに塗るべき色というのは,FillColorで決定されるので,プログラム中で

    Shape1.FillColor = Picture1.Point(X,Y)

あるいは事前に受け渡したText1.Textの値を参照するようにすればよい.

  Shape.FillColor = Text1.Text

しかし,これだけではうまく色を表現してくれない.それはShape1の塗りつぶしのスタイルであるFillStyleプロパティが初期条件において透明になっているからである.
 そこでShape.FillStyleの値を事前に変えておく必要がある.それは,下の式により可能である.

  Shape1.FillStyle = 0 あるいはShape1.FillStyle = vbFSSolid

というわけである.

Shape.Fillstyle=vbFSSolidはイベントが生じるごとに行われることになるが,この処理は毎回行う必要はない.そこでプロパティウィンドウでその値を変更してしまうか,あるいはForm_Loadというイベントの中に記載しよう.
(Form_LoadといイベントはFormが読み込まれる時,つまりプログラムの起動時のみに実行される)