投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/2/22 12:35:23
BringToFront や SendToBack は、Owner での親子関係や TopMost の最前面表示を
超えて切り替える事はできません。あくまでも、マウス操作で切り替えられる範囲の切り替えだけです。

> で、だめでした。無理なようです。

提示されたコードを見る限り、幾つか不自然な個所があります。

f (Form2) の Owner は Me (Form1)
f2 (Form3) の Owner も Me (Form1) になっているため、
この場合の親子関係はこのようになります。
 Form1
  ┣Form2
  ┗Form3


Form1 は親なので、子である Form2 や Form3 よりも手前に来ることはできません。
Owner を一切指定しないのであれば、Form1 が手前に来ることもできます。

Form2 と Form3 は兄弟なので、本来であればどちらを手前にすることもできるのですが、
今回は Form2 が TopMost ですが、Form3 はそうではないため、
Form2 が常時手前にくることになります。

もしも TopMost を設定したウィンドウが複数あった場合には、
TopMost 同士の中でのみ、前面/背面の切り替えが可能です。

上記の仕様について、認識されていますか?


結果として、Form2 が最前面表示、Form1 が最背面で、その間に Form3 がくる形となります。

もしもそれでは都合が悪いというのであれば、TopMost や Owner の指定を
見直してみてください。BringToFront を用いるのは、その後の話です。



> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
>   Form3.BringToFront()
> End Sub
Form2/Form3 が表示されている最中に、Form1 の Button1 をもう一度押しててみてください。
押した数だけ、Form2 や Form3 が生成・表示されますよね?

これは、Form1 の Button1 内で
 「Dim f As New Form2」
 「Dim f2 As New Form3」
として、Form3 を毎回 【New】で生成し、それを【Show】しているためです。

たとえば Form3 を生成した後で、
 Dim f2 As New Form3
 f2.Text = Now.ToString("HH:mm:ss.fff")
のように、いつ生成したのかをタイトルに記録しておくと、
複数起動したときに、どちらが先に生成したものかを確認出来るでしょう。


一方、Form2 で操作しているのは、それらとは無関係の
 Form3.BringToFront()
です。

f2 な Form3 インスタンスは Show していましたが、
Form3 な Form3 インスタンスはまだ Show したことが無いので、
これは「まだ表示されていないフォームを手前に表示しようとしている」ことになります。

MsgBox( Form3.Visible ) 'まだ表示されていないので False が表示される 
MsgBox( Form3.Text ) ' Form1 で「生成時刻」をセットしたのとは別インスタンスなので、既定値のまま 
Form3.BringToFront() 'まだ表示されていないフォームなので、手前に表示しようがない 


Form1 で「New」したフォームを操作したいのであれば、複数起動される可能性あるフォームのうち、
どのフォームを手前に表示したいのか、そのインスタンスを明示して BringToFront する必要があります。
たとえば下記のようにすれば、現在開かれている Form3 フォームを、
順次手前に持ってくることになります。(Owner や TopMost の壁は越えられませんが)
For Each f As Form3 In Application.OpenForms.OfType(Of Form3)()
    f.BringToFront()
Next


一方、そういった明示的なインスタンス管理を行わず、暗黙のフォーム変数で操作したいのなら
Form1 の中でも New は使わずに、「Form2.Show(Me)」 で表示させるようにして、統一性を図りましょう。