連載

プロフェッショナルVB.NETプログラミング

第24回 Windowsアプリケーションの仕組み

(株)ピーデー
川俣 晶
2002/11/09

Page1 Page2 Page3

フォーム・デザイナの役割と生成されたコード

 ソース・コード中に、Windows フォーム デザイナで生成されたコードというメッセージがあることから、フォームのデザインが何か関係していることは容易に推測できるだろう。では、Windowsアプリケーションのプロジェクトを作成後、デザイン作業を何も行わない状態のとき、ソース・コードはどんな内容なのだろうか。

  1: Public Class Form1
  2:   Inherits System.Windows.Forms.Form
  3:
  4: #Region " Windows フォーム デザイナで生成されたコード "
  5:
  6:   Public Sub New()
  7:     MyBase.New()
  8:
  9:     ' この呼び出しは Windows フォーム デザイナで必要です。
 10:     InitializeComponent()
 11:
 12:     ' InitializeComponent() 呼び出しの後に初期化を追加します。
 13:
 14:   End Sub
 15:
 16:   ' Form は dispose をオーバーライドしてコンポーネント一覧を消去します。
 17:   Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
 18:     If disposing Then
 19:       If Not (components Is Nothing) Then
 20:         components.Dispose()
 21:       End If
 22:     End If
 23:     MyBase.Dispose(disposing)
 24:   End Sub
 25:
 26:   ' Windows フォーム デザイナで必要です。
 27:   Private components As System.ComponentModel.IContainer
 28:
 29:   ' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
 30:   ' Windows フォーム デザイナを使って変更してください。
 31:   ' コード エディタは使用しないでください。
 32:   <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
 33:     components = New System.ComponentModel.Container()
 34:     Me.Text = "Form1"
 35:   End Sub
 36:
 37: #End Region
 38:
 39: End Class
VB.NETでWindowsアプリケーションのプロジェクト作成直後の全ソース・コード

 見てのとおり、何かをする前に、すでに39行ものボリュームのあるコードが存在している。

 このコードの内容をざっと解説しよう。まず、1行目はクラスの宣言の開始を示している。つまり、このソース全体が1つのクラスの定義となっている。VB 6では、フォームはフォーム・モジュールで、クラス・モジュールとは別のものであったが、VB.NETではフォームもクラスの一種である。というより、ほとんどすべての情報はクラスで記述されていると思って間違いないだろう。例外としては構造体やモジュールが存在するが、構造体はクラスに似た存在である。

 2行目は、このクラスがSystem.Windows.Forms.Formクラスを継承していることを示している。つまり、このクラス内では、System.Windows.Forms.Formクラスから継承した機能も利用できるということである。

 4行目は、37行目とペアとなり、ソース・コードの範囲を指定している。これは実行時には何の効力も持たず、単にソース・コードの見やすさを高める働きしか持っていない。#Regionと#End Regionで囲まれた範囲は、VS.NETのコード・エディタ上で、容易に隠したり見せたりすることができる。ウィンドウ左側の「+」記号をクリックするまでソースの一部が隠れているのは、#Regionと#End Regionの働きである。

 6〜14行目はコンストラクタである。このクラスのインスタンスが生成されるときに呼び出される。7行目で、スーパー・クラスのコンストラクタを呼び出し、次に、32行目以降のInitializeComponentメソッドを呼び出している。12行目のコメントは、コンストラクタに追加すべきコードがあればここに書き込め、という意図を説明している。ただし、初期化はフォームのLoadイベントに書き込む手段もあるので、どちらがよいかはケースバイケースで判断する必要があるだろう。Loadイベントはすべての初期化が終了した後で発生するため、よく分からなければ、Loadイベントを使う方が安全だろう。

 16〜24行目は、DisposeパターンのためのDisposeメソッドである。Disposeパターンについては、この連載の後の回で解説したいと思うが、要するに、オブジェクトを使い終わったときに呼び出されるメソッドである。しかし、フォームが閉じるときに呼び出されるClosedイベントやClosingイベントもあるので、Disposeメソッドを書き換える必要はないだろう。Disposeメソッド内には、特に書き換えるべき場所もソース中でコメント指定されていないので、その意味でも書き換えない方が安全だろう。

 26〜27行目は、コンポーネント・モデルのコンテナのインターフェイスを保持する変数だが、そのことを意識する必要はめったにないだろう。コメントに述べられているとおり、Windowsフォーム・ デザイナで必要とされているので、削除したり書き換えたりしないようにしよう。

 29〜35行目は、コンストラクタから呼び出されていたInitializeComponentメソッドの本体である。コメントとして注意が書いてあるとおり、これはWindowsフォーム・ デザイナでフォームのデザインを変更すると自動的にそれに応じて書き換えられるものである。手動でソースを書き直すのではなく、Windowsフォーム・デザイナで変更すべきものである。32行目の先頭に書かれているのは属性と呼ばれるもので、このメソッド内ではデバッガが停止しないことを指定している。属性については、この連載で後ほど詳しく取り上げる予定である。

 さて、InitializeComponentメソッドの内容だが、中身はたった2行しかない。33行目は、27行目の変数componentsの初期化である。System.ComponentModel.Containerはコンポーネント・モデルのコンテナとなるクラスである。コンテナとはコンポーネントの入れ物であり、コントロールのインスタンスが格納される。34行目は、Meつまりフォーム自身のインスタンスのTextプロパティに、"Form1"という値を設定している。これは、Textプロパティの初期状態での設定値である。ほかのプロパティなどは、クラスが持っている初期値が指定されたことになっているので、ここには設定の代入文は見えない。なぜ、Textプロパティだけ何もしなくても代入文が自動生成されるかというと、Textプロパティの初期値はフォームのクラス名と同じであり、フォームのクラス名は生成される段階で決まり、一定していないためだろう。もし、Form2という名前のフォームを作れば、この代入文は、Me.Text = "Form2"でなければならない。

プロパティ値の設定により変化するコード

 では、Windowsフォーム・ デザイナでの修正が確かにこれらのソース・コードに反映されるのを確認するために、いくつかのプロパティ値を設定してみよう。まずTextプロパティを"VB.NET Sample"という値に書き換え、次にBackColorプロパティを黄色に変えてみた。以下のような感じである。

VB.NETでフォームのTextプロパティとBackColorプロパティを変更

 この変更後に、InitializeComponentメソッドは以下のように変化した。

  1:   ' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
  2:   ' Windows フォーム デザイナを使って変更してください。
  3:   ' コード エディタは使用しないでください。
  4:   <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
  5:     '
  6:     'Form1
  7:     '
  8:     Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
  9:     Me.BackColor = System.Drawing.Color.Yellow
 10:     Me.ClientSize = New System.Drawing.Size(292, 273)
 11:     Me.Name = "Form1"
 12:     Me.Text = "VB.NET Sample"
 13:
 14:   End Sub
TextプロパティとBackColorプロパティを変更した場合のInitializeComponentメソッド

 変数componentsの初期化コードがなぜか消えているが、その理由は筆者にも分からない。ただ、これで問題は起きていないようである。Textプロパティの変更は、12行目にはっきりと反映されている。BackColorプロパティの変更は、9行目に反映されている。System.Drawing.Color.Yellowは名前による色指定である。System.Drawing.Color構造体は、共有プロパティ(Sharedな定数値)をいくつも持っていて、それぞれに色の名前が付いている。Yellowもその1つである。

 さて、そのほかに、AutoScaleBaseSize、ClientSize、Nameの3プロパティへの代入が追加されている。AutoScaleBaseSize、ClientSizeの2つは、フォーム・デザイナのプロパティ・ウィンドウから入力できない特殊な値である(ClientSizeプロパティはフォームのサイズが反映される)。Nameプロパティは、フォーム・デザイナのプロパティ・ウィンドウから入力できるが、これは特殊な扱いで、フォームのクラス名と連動して同じ値が設定される。この3つは、必要な値が自動的に定義されていると理解しておけば、通常は問題ないだろう。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第24回 Windowsアプリケーションの仕組み
    1.単純なWindowsアプリケーション
  2.フォーム・デザイナの役割と生成されたコード
    3.ボタンの配置により生成されるコード
 
「プロフェッショナルVB.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間