tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルMDIフォームで閉じた画面まで取得できてしまう
記事No16021
投稿日: 2014/11/20(Thu) 12:00
投稿者ぼす
お世話になります。

MDIChild画面を複数件立ち上げて(同一Form名、Captionが異なる)
MDIChildのForm QueryUnload(Unloadが機能しない為)で以下のように解放しています。
            For Each fmMdiTmpForm In Forms
                If Not TypeOf fmMdiTmpForm Is MDIForm Then
                    If fmMdiTmpForm.MDIChild Then
                        If fmMdiTmpForm.hwnd = Me.hwnd Then
                            Set fmMdiTmpForm = Nothing
                            Exit Sub
                        End If
                    End If
                End If
            Next

MDIChildの画面を1つ閉じて、複数件ある場合に閉じた画面も検出されてしまいます。
検出方法は
            For Each fmMdiForm In Forms
                If Not TypeOf fmMdiForm Is MDIForm Then
                    If fmMdiForm.MDIChild Then
                        If fmMdiForm.hwnd = Me.hwnd Then
                            debug.print fmMdiForm.caption
                        End If
                    End If
                End If
            Next
どのように、閉じるもしくは、検出すれば、現状の複数件あるMDIChildを取得できますか?

ご伝授下さい。
宜しくお願い致します。

[ツリー表示へ]
タイトルRe: MDIフォームで閉じた画面まで取得できてしまう
記事No16022
投稿日: 2014/11/20(Thu) 14:16
投稿者魔界の仮面弁士
> MDIChildの画面を1つ閉じて、複数件ある場合に閉じた画面も検出されてしまいます。
その『閉じた画面』が「Unload イベント」に至っていないのであれば、
Forms コレクションには残ったままとなります。

閉じたフォームの状態がどうなっているか分かりますか?



ここでいう状態とは、VB6 ヘルプの

 +[Visual Basic ドキュメント]
  +[Visual Basic の使用方法]
   +[プログラミング ガイド]
    +[Visual Basic を使って出来ること]
     +[オブジェクト]
      +[独自のクラスの作成]
       +[Visual Basic フォームの有効期間]

の項にある、下記の記述のことです。

》 Visual Basic のフォームは、その有効期間中、通常 4 つの状態を通過します。
》 1. 作成されているが、ロードされていない。
》 2. ロードされているが、表示されていない。
》 3. 表示されている。
》 4. メモリおよびシステム リソースが完全に解放されている。


Forms コレクションが管理しているのは、状態 2 と 状態 3 ですが、
その点の認識は問題ないでしょうか?


Forms.Count プロパティが返す値は、ロード中のフォーム全て(状態 2 と 状態 3)で、
DoEvents 関数の戻り値が表す値は、表示されているフォーム全て(状態 3 のみ)です。



下記のようにしておくと、フォームの遷移状態をトレースできます。


Option Explicit

Private Sub Form_Initialize()
    Debug.Print Hex(ObjPtr(Me)), TypeName(Me) & " is Initialized"
End Sub

Private Sub Form_Load()
    Debug.Print Hex(ObjPtr(Me)), TypeName(Me) & " is Loaded, HWND = " & Hex(Me.hWnd)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Debug.Print Hex(ObjPtr(Me)), TypeName(Me) & " is Unloaded"
End Sub

Private Sub Form_Terminate()
    Debug.Print Hex(ObjPtr(Me)), TypeName(Me) & " is Terminated"
End Sub




> 複数件ある場合に閉じた画面も検出されてしまいます。

閉じた画面、というものが
 「Hide メソッド、もしくは Visibile = False による非表示状態」
もしくは
 「Unload はされたが、何らかの理由で再度ロードされた非表示状態」
の場合、Forms で列挙されることになります。

表示されているかどうかを調べる場合は、Visible プロパティで分かります。
ただし、状態 1 にあるフォームの Visible プロパティを参照した場合、
自動的に状態 2 に遷移してしまいますので、その点は注意してください。



それともう一つ。For Each での列挙中に、フォームのロードやアンロードを
行っていないかも確認しておいてください。列挙中にコレクションの要素数が増減すると
列挙処理が正しく行われなくなりますので。

[ツリー表示へ]
タイトルRe^2: MDIフォームで閉じた画面まで取得できてしまう
記事No16026
投稿日: 2014/11/25(Tue) 09:58
投稿者ぼす
ありがとうございます。
指示されたことをやってみます。

[ツリー表示へ]