DOBON.NET DOBON.NETプログラミング掲示板過去ログ

NewをしてないのにForm2.ShowModalが動作するのはなぜ?

環境/言語:[WinXP .NET2 VB6 VB.NET]
分類:[.NET]

こんにちは。

何度かきっと話題になっているとは思うのですが
Form2のShowModalについてお聞きしたいのです。

インスタンスの挙動がよくわかりません。

VB6からVB.NETへの移行を行っていまして

VB6の場合は
Form2.ShowModalや.Showを行うと
その場で生成され、閉じると破棄されるようですが

VB.NETの場合
f = New Form2
などとやってForm2を生成し、閉じるときに.Disposeをすることは
よくわかります。

ところが、VB.NETでは
Form2.ShowModal
Newをしなくてもこれだけで画面が開き
そのあとも、このインスタンスは継続して破棄されないですし

Form2.Dispose
Form2.ShowModal
とすると、ちゃんと破棄された後に新規で生成されるようです。
なぜNewすることなしに、Form2が表示されるのでしょうか?

この仕組みについて教えてください。

よろしくお願いします。
■No24891に返信(FutoNekoさんの記事)
> こんにちは。
>
> 何度かきっと話題になっているとは思うのですが
> Form2のShowModalについてお聞きしたいのです。
>
> インスタンスの挙動がよくわかりません。
>
> VB6からVB.NETへの移行を行っていまして
>
> VB6の場合は
> Form2.ShowModalや.Showを行うと
> その場で生成され、閉じると破棄されるようですが
>
> VB.NETの場合
> f = New Form2
> などとやってForm2を生成し、閉じるときに.Disposeをすることは
> よくわかります。
>
> ところが、VB.NETでは
> Form2.ShowModal
> Newをしなくてもこれだけで画面が開き
> そのあとも、このインスタンスは継続して破棄されないですし
>
> Form2.Dispose
> Form2.ShowModal
> とすると、ちゃんと破棄された後に新規で生成されるようです。
> なぜNewすることなしに、Form2が表示されるのでしょうか?
>
> この仕組みについて教えてください。

「Form の既定のインスタンス」 と言います。 詳細は Form 既定のインスタンスなどで検索すると良いでしょう。
型名で直接参照されたタイミングでシングルトンなインスタンスを勝手に作っていると考えるとイメージしやすいと思います。

Form の既定のインスタンスを利用しないようにする方法
http://blogs.wankuma.com/jeanne/archive/2006/10/26/42540.aspx
2009/07/06(Mon) 23:12:42 編集(投稿者)

■No24891に返信(FutoNekoさんの記事)
> 環境/言語:[WinXP .NET2 VB6 VB.NET] 
VB.NET,.NET2 というのは恐らく、
VB2005,.NET Framework 2.0 の事ですよね。


> VB6の場合は
> Form2.ShowModalや.Showを行うと
> その場で生成され、閉じると破棄されるようですが
VB6 に ShowModal メソッドはありません。もしかして、
 Form2.Show vbModal
の事でしょうか?

VB6 のフォーム変数の動作についての理解を深めておくため、
VB6 用 MSDN ライブラリの下記の項を参照しておいてください。

[Visual Basic ドキュメント]
└[Visual Basic の使用方法]
 └[プログラミング ガイド]
  ├[Visual Basic の基本]
  │└[プログラミングの基礎]
  │ └[オブジェクトの使用方法]
  │  └[オブジェクトの作成]★…特に後半部分
  └[Visual Basic を使ってできること]
   └[オブジェクト]
    └[独自のクラスの作成]
     ├[Form クラスのカスタマイズ]★…"隠されたグローバル変数"の部分
     └[Visual Basic フォームの有効期間]★…これが一番重要なところ


> VB.NETの場合
> f = New Form2
> などとやってForm2を生成し、閉じるときに.Disposeをすることは
> よくわかります。
なお、VB6 の場合にも、明示的に生成する
 Set F2 = Forms.Add("Form2")
 Set F3 = New Form2
 F2.Show
 F3.Show
の構文が利用可能です。
http://support.microsoft.com/kb/147665/ja


> VB.NETの場合
> f = New Form2
> などとやってForm2を生成し、閉じるときに.Disposeをすることは
Dispose の必要があるのは、ShowDialog で開いた場合のみです。
Show メソッドで(モードレスとして)開いた場合には、Dispose は不要です。


> ところが、VB.NETでは
> Form2.ShowModal
> Newをしなくてもこれだけで画面が開き
VB.NET に ShowModal メソッドは無かったかと思います。これはおそらく、
 Form2.ShowDialog()
の事なのだと思いますが、それが使えるのは、VB2005 からです。
VB.NET 2002/2003 では、フォームの New 作業が必須です。

なお、Form2.ShowDialog() というコードは、
 My.Forms.Form2.ShowDialog()
の省略形にあたります。


> そのあとも、このインスタンスは継続して破棄されないですし
ShowDialog は同期的で、フォームが閉じられるまで呼び出し元に制御が戻りません。
Show は非同期的で、呼び出した瞬間、呼び出し元に制御が戻る仕様です。

なお VB2005 では、プロジェクトのプロパティ(「アプリケーション」タブ)により、
『アプリケーション フレームワークを有効にする』の『シャットダウン モード』で
フォームの有効期間に関する動作を変更できますが、2002/2003 の時代には
その機能が無かったため、複数のフォームを持つ画面では、ApplicationContext を
自力実装する必要がありました。
http://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+200602/06020024.txt


> なぜNewすることなしに、Form2が表示されるのでしょうか?
VB6 版と同様、生成されていなかった場合、そのフォームが自動生成されるためです。
内部的に、下記のようなコードが生成されていると思えば理解しやすいのではないでしょうか。

Private m_Form2 As Form2
Public Property Form2 As Form2
 Get
  If m_Form2 Is Nothing OrElse m_Form2.IsDisposed Then
   m_Form2 = New Form2()
  End If
  Return m_Form2
 End Get
 Set (ByVal Value As Form2)
  If Value IsNot m_Form2 AndAlso Value Is Nothing Then
   m_Form2.Dispose()
   m_Form2 = Nothing
  End If
 End Set
End Property
魔界の仮面弁士さん、じゃんぬねっとさん
非常に丁寧に教えてくださって
ありがとうございます。

なるほど、
My.Forms.で
Form2が定義されて見えるようになるのですね。

シングルトンと言われると
非常に納得できました。

.Disposeがなくても
動くプログラムがありまして

でも、ダイアログFormのタイトルが

AAAの追加
AAAの追加追加
AAAの追加追加追加

などと、文字が重なってしまっていましたが
なんでかなーと思ってましたら

追加と変更で同一フォームを使いまわしており
[元のタイトル]+"追加"
というコードが影響して
Disposeしない限りは、
文字がどんどん増えていったのです。

非情に助かりました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板