連載:アップグレード・ウィザードに学ぶVB 6→VB 2005

第5回 .NETではこう変わる! VB 6のMDIフォームとメニュー

グレープシティ株式会社 八巻 雄哉
2007/05/15
Page1 Page2 Page3

■Option Strictステートメント

 この連載も実は今回が最終回となりますので、本題部分以外のコードにも触れておきたいと思います。アップグレード・ウィザードを使って変換されたVB 2005のコードには、その先頭に必ず「Option Strict Off」と「Option Explicit On」という記述が追加されています。

 Option Explicitステートメントは、VB 6のそれと同様に、変数の明示的な宣言を強制してくれるステートメント、Option Strictステートメントは暗黙的なデータ型変換を拡大変換だけに制限してくれるステートメントです。これら2つのオプション機能の詳細については、「改訂版 プロフェッショナルVB.NETプログラミング Chapter 13 オプション機能」を参照してください。

 さて、ここで取り上げなければならない問題は、Option Strictが「On」ではなく「Off」と記述されているという点です。

 そもそも、Visual Studio 2005のオプション設定にある[既定のプロジェクト設定]では、Option StrictがOffと設定されています。このため、Option Strict Offと明示的に記述しなかったとしても、既定の設定では「データの損失を伴う意図しない型変換」や「パフォーマンスに影響を及ぼす遅延バインディング」がコンパイル時にチェックされません。


図6 Visual Studio 2005のオプション設定にある[既定のプロジェクト設定]
メニュー・バーの[ツール]−[オプション]を選択して[オプション]ダイアログを開き、[プロジェクトおよびソリューション]−[Visual Basicの既定値]を選択する。

 「Option Strict」というキーワードでWeb上を検索すると、「Option Strictは『On』に設定することを強く推奨する」といった内容のコンテンツを大量に目にすることができます。「ではなぜ既定値がOffに設定されているのでしょうか」と突っ込みたくはなりますが、MSDNライブラリのOption Strictステートメントにも「必ず使用することをお勧めします」と書かれています。

 筆者の個人的な考えでも、やはりOption StrictはOnに設定すべきだと思います。[既定のプロジェクト設定]でOption StrictをOnに設定し、COM Interop(COM相互運用)などで遅延バインディングを使いたいという場合にのみ、コードの先頭に明示的にOption Strict Offを記述して、そのコードのみOption StrictをOffに設定するという方法がよいのではないでしょうか。

■アップグレード・ウィザードが変換できないVB 6の定数

 変換されたVB 2005のコード(リスト3)を見ると、1カ所だけ、

'UPGRADE_ISSUE: vbNormal をアップグレードする定数を決定できません。

というアップグレード・ウィザードによってコメントが追加されている個所を確認することができます。

 VB 6の定数(列挙値)は、同じ名前で複数の定数が存在しているものがあり、vbNormalという定数名はその代表的なものです。vbNormal定数はWindowStateプロパティの設定値としても使用されていますし、Dir関数のパラメータとしても使用されています。このような定数は、アップグレード・ウィザードでは変換することができません。

 VB 2005のフォームのWindowStateプロパティにはFormWindowState列挙体(System.Windows.Forms名前空間)の値を設定します。VB 6のvbNormalと同じようにウィンドウを既定サイズにする列挙体の値は、FormWindowState.Normalです。

 よって、MenuWindowRestoreAll_Clickメソッド部分は以下のリスト4のように書き換える必要があります。

Public Sub MenuWindowRestoreAll_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MenuWindowRestoreAll.Click

  SetWindowStateAll(FormWindowState.Normal)

End Sub
リスト4 vbNormalをFormWindowState.Normalに修正(VB 2005)

■MdiChildrenプロパティ

 VB 6のコード(リスト1)のSetWindowStateAllメソッド部分では、これも特殊オブジェクトの1つですが、「Formsコレクション」を使ってプロジェクトに含まれるすべてのフォームを取得し、MDIフォーム以外のフォームに対してWindowStateプロパティを設定するという方法で、すべてのMDI子フォームのウィンドウの状態を変更していました。

 アップグレード・ウィザードによる変換では、VB 6のFormsコレクションはVB 2005のMy.Application.OpenFormsプロパティに置き換えられています。

 VB 6のFormsコレクションには、開かれているフォーム、もしくはLoadステートメントによってメモリにロードされているフォームが含まれます。一方、VB 2005ではLoadステートメントを使ってフォームをロードするという動作は概念的に存在しません。そのため、My.ApplicationオブジェクトのOpenFormsプロパティは、開かれているフォームを含むFormCollectionオブジェクトのみが返されますが、これはFormsコレクションと同様の感覚で使用することができます。

 そして、変換されたVB 2005のコード(リスト3)のSetWindowStateAllメソッド部分のコードは、このままでも問題なく想定した動作となります。

 しかしながら、VB 2005ではMDI子フォームだけを含むFormCollectionオブジェクトを取得するためのMdiChildrenプロパティがFormクラスに用意されています。従って、このMdiChildrenプロパティを使うことで、自分自身であるMDIフォームを除外するというVB 6での処理を記述する必要がなくなるため、より簡潔な記述が可能になります。

 また、VB 2005のFor 〜 Next/For Each 〜 Nextステートメントでは、ループのための変数(リスト3では「currentForm」の部分に該当)をステートメント内で宣言して記述することができます。このように記述することのメリットは、単純にコードの行数が少なくなるということだけではなく、ループのための変数のスコープがそのループ・ブロックに対してのみ設定されるため、ループ・ブロックの外で使用できなくなり、使用用途が明確になります。

 以上の2点を考慮すると、リスト3のSetWindowStateAllメソッド部分のコードは次のリスト5のように修正できます。

Private Sub SetWindowStateAll(ByRef state As System.Windows.Forms.FormWindowState)

  ' MdiChildrenプロパティを使ってすべてのMDI子フォームを取得します。
  For Each currentForm As Form In Me.MdiChildren
    currentForm.WindowState = state
  Next currentForm

End Sub
リスト5 MdiChildrenプロパティを使ってMDI子フォームのウィンドウ状態を変更するように修正したコード
My.Application.OpenFormsプロパティを使う場合に比べ、If 〜 Then 〜 Elseステートメントを使って自分自身であるMDIフォームを除外する処理が必要なくなるため、より簡潔な記述となっている。ループ用の変数であるcurrentFormは、For Each 〜 Nextステートメント内で宣言されているため、ループ・ブロックの外で使用することはできない。

 ここまでの修正をすべて適用したアプリケーションの実行画面が、下記の図7です。


図7 プロジェクトの実行画面(VB 2005アプリケーション)

 変換前のVB 6アプリケーションとほぼ同じ動作となっていることを確認できるかと思います。

 以上、今回はMDIFormオブジェクトとMenuコントロールを使ったVB 6プロジェクトの変換を行いました。VB 2005ではMDIフォームもメニューも特殊な存在ではなくなっているので、その扱いについても特に戸惑うことなく理解できるのではないでしょうか。

 Visual Studio .NET 2002、2003向けの記事ではありますが、一からMDI型アプリケーションを作る場合の手順については「解説:実例で学ぶWindowsプログラミング 第1回 MDI型Windowsアプリケーションの基礎開発」で非常に詳しく解説されていますので、ぜひこちらも参考にしてみてください。

連載の最後に

 今回、この連載を書いていく中で痛感したVB 6とVB 2005の大きな違いがあります。それは、VB 6についての情報がVB 2005のそれと比べて圧倒的に少なく、さらにその情報も利用しづらい状況にあるということです。

 WebでVB 6の情報を検索しようと思ってもVB 2005(もしくはVisual Basic .NET)の情報ばかりが検索結果に並び、なかなかVB 6の情報を探し出すことができませんでした。また、VB 2005のヘルプを見た後にVB 6のヘルプを見ると、その情報量の少なさに驚かされます。VB 6の方が枯れた技術であり、そのノウハウがあふれているからというのは、もはやVB 2005へ移行しない理由にはならないようです。

 VB 6の延長サポート期限である2008年4月8日まで、すでに1年を切りました。まだVB 2005を試したこともないという方、ぜひ今年こそチャレンジしてみてください。End of Article

 

 INDEX
  アップグレード・ウィザードに学ぶVB 6→VB 2005
  第5回 .NETではこう変わる! VB 6のMDIフォームとメニュー
    1.VB 6のMDIフォームとメニュー
    2.VB 2005にMDIFormオブジェクト/メニュー・エディタは存在しない
  3.Option Strictステートメント/VB 6の定数/MdiChildrenプロパティ
 
インデックス・ページヘ  「アップグレード・ウィザードに学ぶVB 6→VB 2005」


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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH