Visual Basicでグラフィックを扱う場合は、2つのコントロールのいずれかを利用します。それは「Image」と「PictureBox」です。この2つは非常に似ていますが、微妙に使い方が異なります。
PictureBoxはその名の通り、グラフィックを表示するためのボックスです。これを配置すると四角い枠のボックスが表示されます。そしてその中にグラフィックが表示されます。当然ですが、枠の中はコントロールのデフォルトの色で表示されており、そこにグラフィックが表示されるわけです。
これに対し、Imageはグラフィックだけを表示するコントロールです。つまり、枠だの内部の背景だのといったものは全くなく、透明の部品にグラフィックだけがぺたっと貼り付けられるのですね。
下の図が、PictureBoxとImageの2つに同じグラフィックを設定して比べてみたところです。わかりやすいように、フォームの背景色をちょっと変えてみました。こうすると、両者の違いは一目瞭然ですね?
Imageは、コントロールの背景が透き通ってますから、下の表示が透けて見えます。PictureBoxは枠の中にグラフィックだけをきちんと独立して表示させたいときに利用するのがよいでしょう。
あるいは読者の中にはこう考えた人もいるかも知れません。「それなら、PictureBoxに背景などを表示させて、その上にImageを重ねれば簡単にグラフィックを重ね合わせて表示できるな」と。
ところが、これはうまくいきません。なぜなら、Imageのグラフィックは必ずPictureBoxの下に表示されるようになっているからです。Imageのほうが手前にあっても、です。従って、PictureBoxの上にImageを重ねることはできません。
といっても、がっくりすることはありません。実は、Form自体にもグラフィックを表示させることができるのです。ですから、Formに背景を表示し、その上にImageを重ねればいいというわけです。めでたしめでたし!
さて、肝心の「グラフィックをコントロールに表示させる方法」ですが、これは簡単です。これらのコントロールに表示するグラフィックは「Picture」というプロパティとして用意されています。
コントロールをクリックして選択し、プロパティウィンドウより「Picture」という項目を探して下さい。その右端に「…」というマークがあります。このマークをクリックすると画面にファイルを選ぶためのダイアログが現れますので、ここで表示させたいグラフィックファイルを選べばOKです。簡単ですね?
では、コードを使って何かの図形を描くにはどうすればいいのでしょう。この方法についても考えてみましょう。まず、簡単なサンプルを作ってみることにします。
1.新しいプロジェクトを作り、そこにPictureBoxを1つとCommandButtonを作成する。
2.PictureBoxは、図形がわかりやすいように背景の色を変えておこう。背景色はBackColorというプロパティで用意されている。作成したPictureBoxを選択し、プロパティウィンドウからBackColorを探して選択する。このプロパティの右端には下向き三角形のマークがあるのでここをクリックすると、システムで使う色や主な色がポップアップで表示される。ここで白を選んでおこう。
3.作成したボタンをダブルクリックしてコードウィンドウを開き、以下のコードを記述する。
Private Sub Command1_Click() Picture1.Circle (1000, 1000), 500 End Sub
ここで使ったのは、PictureBoxに用意されている「Circle」という機能です。前回、コントロールに用意されているプロパティを利用しましたが、このCircleはプロパティとはちょっと違う。「コントロール固有の命令」のようなものなのです。
プロパティというのは「コントロール固有の値」でした。そのコントロールに用意されているさまざまな値がプロパティとして用意されていましたね。だから、その値を取り出したり変更したりといったことはできたけれど、それ自身が「何かを実行する」という機能を持っていたわけではありません。
ところがこのCircleは、「自分自身の中に円を描く」という機能を実行するものです。プロパティと違い、機能を持っているのです。こうした「コントロールに固有の命令」を「メソッド」と呼びます。
メソッドも、利用の仕方はプロパティととても似ています。コントロール名の後にメソッド名をピリオドでつなげて書けばいいのです。ただし、多くのメソッドでは、その後にさまざまな値を一緒に書いてやらないといけません。
例えば、このCircleメソッドもそうです。これは、以下のような形をしています。
《コントロール》.Circle (横位置, 縦位置), 半径
ややわかりにくいですが、()の中に円の中心地点の横方向と縦方向の位置をカンマで区切って記述し、その後にカンマで区切って半径を記述するわけですね。こうした「命令を実行するのに必要な値」をパラメータといいます。このCircleメソッドでは3つのパラメータが最低でも必要となるわけですね。
ここで登場する位置は、そのコントロールの左および上からどれだけ離れているかを示すものです。ということは、今回のCircleメソッドは、コントロールの左および上からそれぞれ1000離れた地点に、半径500の円を描く、ということだったわけです。…ん? 1000離れた地点に半径500の円?? あれ、なんか変ですね?
これらの値の単位って、一体なんでしょう? ドット数にしては数字がやたら大きすぎます。一体何を基準にしているんでしょうね?
これは、実は「Twip」というWindows特有の単位を利用した値なのです。Windowsマシンでは、様々なグラフィックカードでさまざまなモニタが接続されています。それぞれ解像度のdpiもてんでバラバラです。こういう状態では、「全てのモニタで同じ大きさを表示する」ということができません。
そこでWindowsでは「Twip」というものを用意したのです。これは、ドット数にそれぞれのモニタ固有の値をかけたものです。だいたい、一般的なモニタだと1ドット=15 Twip前後ぐらいになります。
《コントロール》.Line (横位置1, 縦位置1)-(横位置2, 縦位置2)
直線は、2つの点を結ぶように描きますから、このように2つの点を指定することで、1つ目の地点から2つ目の地点に線を描画するようになるのですね。
が、実をいえばこのLineは1つしか点を指定しなくても描くことができます。Visual Basicでは、こうした描画命令を使って図形を描いたとき、最後に描画した地点を記憶しているのです。そこで、まず1度、上のように2点を指定して線を描画した後で、1つ目の地点を省略し、
《コントロール》.Line -(横位置2, 縦位置2)
このようにメソッドを実行すると、1回目のLineの最後の地点から、このLineで指定した地点へと線が描画されます。連続して直線を描くときにはとても便利な機能ですね。
では、これも簡単なサンプルを作ってみましょう。先に作ったプロジェクトで、ボタンのサブルーチンを以下のように書き換えて下さい。
Private Sub Command1_Click() Picture1.Line (500, 500)-(1000, 500) Picture1.Line -(500, 1000) Picture1.Line -(1000, 1000) Picture1.Line -(500, 500) End Sub
このように、Lineで連続して図形を描くときは、1回目だけを2点指定し、それ以後は2点目だけを指定して描くとちょっとだけ手間が省けます。これは覚えておくと便利でしょう。
さて、円、直線と来たら、次はやはり四角形でしょう。ところが、Visual Basicには四角形を描くメソッドが用意されていないのです。ではどうすればいいのかというと、Lineを利用するのです。
Lineメソッドには、オプションのパラメータがたくさんあります。その中に「ボックス描画」のオプションというのがあるのです。これを使うと、2点を結ぶ線ではなく、2点を対角とする四角形を描きます。このパラメータを使ったLineメソッドは、こんな感じで記述します。
《コントロール》.Line (横位置1, 縦位置1)-(横位置2, 縦位置2), , B
Lineには他にもいろいろオプションパラメータがあるので、それらを省略しているため、間に何もないパラメータを挟んだ形になってますが、このように記述することで四角形を描くことができます。では、試してみましょうか。
Private Sub Command1_Click() Picture1.Line (500, 500)-(1000, 1000), , B End Sub
実は、描画メソッドで描く図形の色というのは、メソッドを実行したときにコントロールに設定されている色で決められていたのです。グラフィック描画できるコントロールには、描画の色に関するプロパティがいくつか用意されています。まずはこれらをざっと紹介しておきましょう。
「ForeColor」――描画する図形の線の色を示すもの。これを変更して秒がメソッドを実行すると、線の色が変わる。
「FillColor」――描画する図形の内部を塗りつぶして描きたいとき、中の塗りつぶし色として使われるもの。
「FillStyle」――描画する図形の塗りつぶしに関する設定を行なうもの。デフォルトでは「1-透明」になっており、この状態では内部は塗りつぶされない。「0-塗りつぶし」にすると、FillColorで指定した色で図形の内部を塗りつぶすようになる。
「 DrawWidth」――描画する図形の線の太さを示すもの。これは単位はドット数となる。例えば「3」とすれば3ドットの太さで線が描かれる。
これらをあらかじめ変更してから描画命令を実行すれば、色を使ったり内部を塗りつぶしたりして図形を描画できるというわけです。また、もちろんこれらのプロパティはサブルーチンの中から呼び出して変更することも可能です。ですから、これを変更しては描画し、また変更しては描画する…という具合に繰り返せば、さまざまな色を使ったカラフルな図形も作れるわけです。
が! ここで問題となるのは、「色をどうやって指定するか」でしょう。プロパティのForeColorやFillColorの部分を見ると、「&H00FF00AA&」などとなにやら奇怪な暗号のような値が設定されています。
実は、これは16進数を使って色を指定しているものなのですが、もっとわかりやすく使いやすい方法として、「色の値を返す関数」というのを使う方法を覚えておきましょう。
関数というのは、値を返す働きをする機能のことです。これは、Visual Basic自身に組み込まれているもので、さまざまな値の計算結果などを調べるのに使われます。色の値を調べる関数はその名もズバリ「RGB」というものです。これは、このように使います。
変数 = RGB(赤, 緑, 青)
()の中に、3つのパラメータをカンマで区切って記述します。この「赤」「緑」「青」は、それぞれの色の輝度を示す数字で、0〜255の任意の整数となります。もちろん、0が最低で255が最高となります。例えば、Picture1のForeColorを赤い色に変更したければ、
AKA = RGB(255, 0, 0) Picture1.ForeColor = AKA
Private Sub Command1_Click() H = (Rnd * Picture1.Width) \ 1 V = (Rnd * Picture1.Height) \ 1 R = (Rnd * 256) \ 1 G = (Rnd * 256) \ 1 B = (Rnd * 256) \ 1 Picture1.ForeColor = RGB(R, G, B) Picture1.Circle (H, V), 500 End Sub
ここでは、新しい関数とプロパティが登場します。まず、「Rnd」という関数。パラメータも何もない、実に単純なものですね。これは「0〜1の間の小数をランダムに返す」という働きを持ったものです。
小数を返すというのは一見すると処置に困ってしまいそうですが、そんなことはありません。0〜1の小数ということは、これに整数をかけて端数を切り捨てれば、任意の整数が得られるということになります。例えば、10をかければ、0〜10(未満)の小数が得られますね? ここで端数を切り捨てれば、0〜9の整数が得られるわけです。わかりますか?
では、「端数を切り捨てる」というのはどうやればいいんでしょう? これもそのための関数とかを使うのか?と思うでしょうが、実はもっと簡単な方法があります。¥を使って値を1で割ればいいのです。¥は、小数点以下を切り捨てた値を返しますね? ですから、例えば「9.999 \ 1 = 9」という具合に、1で割ることで小数点以下を切り捨てた整数だけが得られるわけです。――まあ、端数切り捨ては他にもいろいろ方法がありますが、とりあえず何も新しい関数などを覚えなくてすむので、これが一番わかりやすいでしょう。
では、このサブルーチンで行なっていることを考えてみましょう。
H = (Rnd * Picture1.Width) \ 1 V = (Rnd * Picture1.Height) \ 1
こうして縦横幅のランダムな値を使えば、Picture1の中の任意の地点を指定できるというわけです。
R = (Rnd * 256) \ 1 G = (Rnd * 256) \ 1 B = (Rnd * 256) \ 1
Picture1.ForeColor = RGB(R, G, B) Picture1.Circle (H, V), 500
というわけで、ごくざっとですが、メソッドを使ってコントロールに図形を描画する基本について説明をしてみました。図形の描画は、自分で思い通りにできるようになるとなかなか面白いものです。ここにあげたサンプルを元に、それぞれでいろいろ書き換えて遊んでみましょう!