Visual Basic 6.0 初級講座
VB6対応

 

Visual Basic 中学校 > VB6 初級講座 >

第18回 2つ目のフォーム

 

いままでの解説はどれも最初から用意されているフォームの上にいろいろなコントロールを配置してプログラムするものでしたが、もちろん1つのプログラムには2つ以上のフォームがあっても構いません。

現に市販されているソフトのほとんどは2つ以上のフォームから構成されています。みなさんはInternet Explorerがいくつのフォームを使っているか知っていますか?

というわけで今回は2つ以上のフォームを使う方法を説明します。その過程で画像の色を反転するプログラムを作ります。

 

1.設計

 

具体的な話にはいる前に完成するプログラムの簡単な想像をします。まず、画像ファイルを選ぶとその画像がフォームに表示されるようにしましょう。そして、そのフォームにはボタンが付いていてボタンを押すともう一つのフォームが現れて今表示している画像を反転して表示するようにします。つまり、元の画像と反転した画像を横に並べて2つ同時に見れるようにするわけです。1つのフォーム上に2つPictureBox(ピクチャーボックス)を配置しても同様なことができそうですが、フォームを2つ使えばどちらかを最小化したりサイズを変えたりと言うことが容易にできます。

まぁ、元の画像と色を反転した画像を2つ並べてみるだけでは実用性はありませんが楽しんで作ることにしましょう。VBのレベルがあがれば反転以外にももっと複雑な画像処理ができるようになります。

 

2.1つ目のフォーム

 

フォームに画像を表示させるにはフォームのPictureプロパティを使います。次の例ではフォームにC:\Test.bmpという画像ファイルを表示させます。

Form1.Picture = LoadPicture("C:\Test.bmp")

しかし、ユーザが表示する画像を自由に選べるようにしたいですから少し工夫しましょう。この工夫については特別講義に解説がありますから参考にしてください。ここでは、解説は抜きにして完成した全コードだけを載せておきます。

Private Sub Command1_Click()

CommonDialog1.Filter = "画像ファイル|*.bmp;*.gif;*.jpg;*.jpeg"

CommonDialog1.ShowOpen

Form1.Picture = LoadPicture ( CommonDialog1.FileName )

Form1.Caption = CommonDialog1.FileName

End Sub

注:「特別講義1」では、4行目が Image1.Picture・・・ となっていますがここでは上記のように修正しました。

このコードを実行するにはコモンダイアログボックスを参照する必要があります。その手順は次の通りです。

@ メニューの[プロジェクト]から、[コンポーネント]を選択します。

A 一覧表が表示されるので Microsoft Common Dialog Control 6.0 を探してチェックします。(クリックしただけではチェックされません。左の四角をクリックしてください。)

B 「OK」をクリックします。そうすると、左のコントロールのアイコンの一番最後に新しいアイコンが追加されたでしょう。これがコモンダイアログのアイコンです。

Cふつうのコントロールと同じように、コモンダイアログを配置してください。場所は好きなところでいいです。

以上の手順を踏み、かつ上に掲げた6行のコードを打ち込み、さらにコマンドボタンを一つ配置していればプログラムは完成です。不安な人はこの時点で一度実行してみてください。コマンドボタンを押すとフォームに選んだ画像が表示されますね?

しかし、性能が悪いプログラムとなっています。一番の不満は、フォームの大きさが画像より小さいと全体が表示されない点です。そこで前にやったようにスクロールバーで画像全体が見られるようにしてもいいのですが今回はイメージ(Image)を使うことにします。

フォームにImageを一つ貼り付けてください。そして、フォームの大きさが変更されたらイメージの大きさも変更されるようにプログラムします。イメージの大きさは常にフォームの大きさと同じになるようにします。そのためのプログラムは次の通りです。

Private Sub Form_Resize()

Image1.Move 0 , 0 , Form1.ScaleWidth , Form1.ScaleHeight

End Sub

Form_Resizeはフォームのサイズが変更されると自動的に呼び出されます。また、フォームがロードされた直後にも呼び出されます。Moveメソッドはコントロールの位置やサイズを1回で変更できる便利なメソッドです。引数は4つあって 左上の座標、右上の座標、横幅、たて幅 の順です。フォームの横幅とたて幅はそれぞれフォームのScaleWidthプロパティとScaleHeightプロパティで取得できます。

さて、選択された画像はフォームではなくこのイメージに表示されるようにします。それにはさっき打ち込んだ部分にちょっと手を加えるだけで済みます。以下では変更する部分を ピンク色にして示します。それ以外の場所は変更していませんから打ち直す必要はありません。

Private Sub Command1_Click()

CommonDialog1.Filter = "画像ファイル|*.bmp;*.gif;*.jpg;*.jpeg"

CommonDialog1.ShowOpen

Image1.Picture = LoadPicture ( CommonDialog1.FileName )

Form1.Caption = CommonDialog1.FileName

End Sub

これで、ImageのStretchプロパティをTrueにすれば作業完了です。実行してみてください。画像を読み込んでフォームのサイズを変えると、画像もフォームに従ってのびちぢみしますね。

ここまでの全コードと配置したコントロールを以下に示しておきます。

・配置したコントロール

1.CommonDialog1 (このコントロールを配置するためにはメニューの[プロジェクト]から、[コンポーネント]で Microsoft Common Dialog Control 6.0  をあらかじめ追加しておく必要がある。)

2.Command1

3.Image1  StretchプロパティをTrueにしておく

・全コード

Private Sub Command1_Click()

CommonDialog1.Filter = "画像ファイル|*.bmp;*.gif;*.jpg;*.jpeg"

CommonDialog1.ShowOpen

Image1.Picture = LoadPicture ( CommonDialog1.FileName )

Form1.Caption = CommonDialog1.FileName

End Sub

Private Sub Form_Resize()

Image1.Move 0 , 0 , Form1.ScaleWidth , Form1.ScaleHeight

End Sub

 

3.2つ目のフォーム

 

以上で1つ目のフォームの主要な部分は終わりです。これから今回の本番である2つ目のフォームの制作に取りかかります。

まず、フォームを追加する方法から説明しましょう。メニューの[プロジェクト]から、[フォームモジュールの追加]を選択します。一覧のような物が表示されるのでその中から「フォームモジュール」を選んで「開く」ボタンをクリックします。

これでプログラムに2つ目のフォームが追加されました。このように1つのプログラムにはいくらでもフォームを追加できます。これらのフォームは1つのプログラムで制御されているわけです。このようなあつまりを「プロジェクト」と呼びます。この言葉を使うと今の作業は「プロジェクトに新しいフォームを追加した」と表現されるわけです。

さて、プロジェクトエクスプローラを見るとちゃんとフォームが2つ表示されていますね。最初のフォームをデザインしたいときはプロジェクトエクスプローラのForm1をダブルクリックします。2つ目のフォームをデザインしたい場合にはForm2をダブルクリックします。

このようにフォームが増えてくるとプロジェクトエクスプローラの役割も増えてきますからこのフォームの切り替え方も覚えて置いてください。

では、この状態でもう1度プログラムを実行してみましょう。フォームを追加する前と何一つ変わっていないのが分かるでしょう。フォームは追加しただけでは表示されないのです。「フォームを表示しろ」という命令が必要なのです。

そこで、From1にもう一つCommandButton(コマンドボタン)を配置してそのボタンを押したら2つ目のフォームが表示されるようにプログラムしてみましょう。

そのコードは次のようになります。

Private Sub Command2_Click()

Form2.Show

End Sub

これでこのボタンを押すと2つ目のフォームが表示されます。

ところで、我々は色を反転させた画像を表示させるために2つ目のフォームを用意したのですからその準備をしましょう。

2つ目のフォームにもイメージを一つ配置してください。そしてやはり2つ目のフォームのリサイズイベントに次のように記述します。(これはフォーム1とほとんど同じコードですね)。

Private Sub Form_Resize()

Image1.Move 0 , 0 , Form2.ScaleWidth , Form2.ScaleHeight

End Sub

ImageのStretchプロパティをTrueにするのも忘れないでください。

これで準備が整いました。次はいよいよ画像の反転に挑戦です。

 

4.画像の色を反転して転送

 

1つ目のフォームの2つ目のコマンドボタンに先ほど次のようにプログラムしましたね。

Private Sub Command2_Click()

Form2.Show

End Sub

これはForm2を表示させるための処理だったわけですが今度はここにコードを追加します。ただ表示させるだけではなく、Form2のImageに色を反転させた画像を表示させるようにプログラムするわけです。

方法と手順は次の通りです。

1.Form1のImage1に表示されている画像をForm2のPicture1に送る(このとき反転して送るように命令する)。

2.Form2のPicture1は送られてきた画像をForm2のImage1に送る。

つまり、Form1のImage1 → Form2のPicture1 → Form2のImage1 という順に画像を送ります。

なんでわざわざ2回送るのかというと、まず、PictureBox(ピクチャーボックス)では画像のサイズ変更が簡単にできないのでフォームのサイズを変更すると画像のサイズも変わるというプログラムがやりにくいと言う点が挙げられます。それならば最初にForm1のImage1から直接Form2のImage1に画像を送ればいいじゃないかと思われるかも知れませんが、実はImageからImageに画像を送るときは画像を反転させて送ることができないのです。そこで画像を反転して受け取れるPicture1を間に挟んでいるというわけです。

という訳でForm2に画像転送用のピクチャーボックスを1つ配置してください。見えているとかっこわるいのでVisibleプロパティはFalseにしておきます。しかしながら、画像を受け取る必要があるのでAutoRedrawプロパティはTrueにしておいてください。

では、具体的に以上の方法を実現していきます。

転送を始める前にForm2のPicture1のサイズをあらかじめ画像のサイズと同じにしておく必要があります。そのためのコードは次の通りです。


Form2.Picture1.Move 0, 0, Image1.Picture.Width, Image1.Picture.Height
 

頭に Form2. がついているのは「Form2の」と言う意味です。何もついていなければ「Form1の」という意味になります。これはこのコードをForm1に記述するからです。このことからたとえば  Image1.Picture.Widthは「Form1のImage1の画像(Pictureプロパティ)の横幅」という意味になります。

サイズが調節できたら転送します。そのコードは次の通りです。


Form2.Picture1.PaintPicture Image1.Picture, 0, 0, Image1.Picture.Width, Image1.Picture.Height, , , , , vbNotSrcCopy
 

長ったらしいコードですが、これが画像を反転させるからくりです。PaintPictureメソッドを使って画像を転送すれば簡単な画像処理を行うことができるのです。このPaintPictureメソッドは引数が多いので簡単に説明しておきましょう。

まず、Form2.Picture1.PaintPictureとなっている点に留意してください。つまり、「Form2のPicture1に画像を描け」という命令なのです。以下に引数でどの画像をどんな風に描くのかを指定るわけです。

第1引数は「どの画像を?」の部分です。ここではImage1のPictureを指定してます。第2引数から第5引数までは画像の部分を指定します。ここでの設定によっては1部分だけ描画するように指示することもできますがここでは全体を描画させたいので画像全体を指すように指定しています。具体的な引数の意味は順に、左上のx座標、左上のy座標、横幅、たて幅です。

第6引数から第9引数は指定した領域内(この場合はForm2.Picture1)のどこに描画するかを指定します。ここでは省略しているので、コピー元と同じ部分に描画されます。

第10引数では「どんな風に」描画するのかを指定できます。ここでの指定はVBの組み込み定数で行います。vbNotSrcCopyは「反転」を表します。この他にどんな指示があるかを一番下で表にまとめておきます。

 

少し話が横にそれましたが、最後はForm2のPicture1からForm2のImage1に画像を転送して終わりです。ここの転送は単純な転送なのでプロパティの受け渡しだけで事足ります。そのコードは次のようになります。


Form2.Image1.Picture = Form2.Picture1.Image
 

右辺がPicture1のImageプロパティになっているのが気になるかも知れません。これはいずれ説明することになると思いますが簡単にいっておくとPaintPictureメソッドで画像を受け取った場合、その画像はPictureプロパティではなくImageプロパティに格納されるのです。そしてImageプロパティが予想通りに動作するためにあらかじめAutoRedrawプロパティをTrueにしておく必要があるのです。ためしにPicture1のAutoRedrawプロパティをFalseにして試してみてください。

以上で完成です。全コードと配置したコントロールを示しておきます。

・配置したコントロール

<Form1>

1.CommonDialog1 (このコントロールを配置するためにはメニューの[プロジェクト]から、[コンポーネント]で Microsoft Common Dialog Control 6.0  をあらかじめ追加しておく必要がある。)

2.Command1

3.Image1  StretchプロパティをTrueにしておく

4.Command2

<Form2>

1.Image1  StretchプロパティをTrueにしておく

2.Picture1  VisibleプロパティをFalse、AutoRedrawプロパティをTrueにしておく

・全コード

<Form1>

Private Sub Command1_Click()

CommonDialog1.Filter = "画像ファイル|*.bmp;*.gif;*.jpg;*.jpeg"

CommonDialog1.ShowOpen

Image1.Picture = LoadPicture ( CommonDialog1.FileName )

Form1.Caption = CommonDialog1.FileName

End Sub

Private Sub Command2_Click()

Form2.Show

Form2.Picture1.Move 0, 0, Image1.Picture.Width, Image1.Picture.Height

Form2.Picture1.PaintPicture Image1.Picture, 0, 0, Image1.Picture.Width, Image1.Picture.Height, , , , , vbNotSrcCopy

Form2.Image1.Picture = Form2.Picture1.Image

End Sub

Private Sub Form_Resize()

Image1.Move 0 , 0 , Form1.ScaleWidth , Form1.ScaleHeight

End Sub

<Form2>

Private Sub Form_Resize()

Image1.Move 0 , 0 , Form2.ScaleWidth , Form2.ScaleHeight

End Sub

 

5.まとめ

 

今回のテーマは「フォームを追加」することだったのですが画像を反転して転送する方が大変だったのでテーマが不明瞭になってしまいました。そこで少しこの点をまとめておきます。

・フォームを追加するにはメニューの[プロジェクト]から、[フォームモジュールの追加]を選択して、「フォームモジュール」を選ぶ。

・追加したフォームはプロジェクトエクスプローラに表示される。

・フォームを切り替えたいときはプロジェクトエクスプローラをダブルクリックする。

・フォームを表示するにはShowメソッドを使う。

例    Form2.Show

・別のフォームにあるコントロールを呼び出すときは頭にフォーム名をつける。

例    Form2.Image1.Visble = True

だいたいこんなところでしょう。

この他に重要なことを若干あげておきます。

・フォームを表示したくなくなったらHideメソッドで隠せる。

例    Form2.Hide

・Hideメソッドは一時的に隠すだけである。フォームをメモリ上から消去するにはUnloadステートメントを使用する。

例    Unload Form2

まだまだあるのですが続きはもっと高度なことをやるときに説明しましょう。それでは失礼します。

 

6.付録        PaintPictureメソッドの第10引数

 

定数名

意味

論理的な式

&H42 物理パレットのインデックス 0 に対応する色 (デフォルトは黒) で、コピー先の長方形を塗りつぶします。 dest = BLACK
vbDstInvert コピー先長方形の色を反転します。 dest = (NOT dest)
vbMergeCopy コピー元の色と、コピー先の色を、論理 AND 演算子で結合します。 dest = (source AND pattern)
vbMergePaint コピー元の色を反転した色と、コピー先の色を、論理 OR 演算子で結合します。 dest = (NOT source) OR dest
vbNotSrcCopy コピー元の色を反転して、コピー先にコピーします。 dest = (NOT source)
vbNotSrcErase コピー元の色と、コピー先の色を、論理 OR 演算子で結合し、さらに反転します。 dest = (NOT src) AND (NOT dest)
vbPatCopy 指定したパターンをコピー先にコピーします。 dest = pattern
vbPatInvert 指定したパターンの色と、コピー先の色を、論理 XOR 演算子で結合します。 dest = pattern XOR dest
vbPatPaint 指定したパターンの色と、コピー元の色を反転した色を、論理 OR 演算子で結合し、さらにその結果を、コピー先の色と論理 OR 演算子で結合します。 dest = DPSnoo
vbSrcAnd コピー元の色と、コピー先の色を、論理 AND 演算子で結合します。 dest = source AND dest
vbSrcCopy コピー元をコピー先にそのままコピーします。 dest = source
vbSrcErase コピー先の色を反転した色と、コピー元の色を、論理 AND 演算子で結合します。 dest = source AND (NOT dest )
vbSrcInvert コピー元の色と、コピー先の色を、論理 XOR 演算子で結合します。 dest = source XOR dest
vbSrcPaint コピー元の色と、コピー先の色を、論理 OR 演算子で結合します。 dest = source OR dest
&HFF0062 物理パレットのインデックス 1 に対応する色 (デフォルトは白) で、コピー先の長方形を塗りつぶします。 dest = WHITE

定数名の列にはVBのヘルプに記載されていない定数も載せておきました。

この表は、MSDN、オブジェクトブラウザ、Wingdi.hに記載されている内容を適当に写した物です。