none
別スレッドで開いたフォームのプロパティを修正するには? RRS feed

  • 質問

  • こんにちは。 

    別スレッドで開いたフォームのプロパティを修正するにはどうしたらよいのか、なかなか情報を見つけることができません。
    ご教授よろしくおねがいします。

    【やりたいこと】
    メインフォームから別スレッドでフォームを開き、
    そのフォームのコントロールのプロパティ(表示/非表示)をメインのフォームから切り替えたい。

    【フォームを別スレッドにしている理由】
    ・このフォームには複数のWebブラウザコントロールを貼り付けてあり、ここでFlashコンテンツや、マーキータグをつかって電光掲示板みたいなことをしています。
    ・ところが、メインのフォームで処理を行うと、それぞれブラウザの表示が一時停止してしまい、何とかできないか との要望がありました
    ・そこでこのフォームを別インスタンスで開くことで、メインの処理による停止がなくなるようにしました。
    ・ですが、メインの画面の処理内容によって、表示するコントロールを切り替える必要があるのですが、それがうまくできません。
    いろいろ調べてみたのですが、どうしてもうまく動きません。
    ・次のサンプルでは、InvokeRequiredがTrueになりませんし、無理やりInvokeを実施してもウィンドウハンドルがないためできないとエラーになってしまいます。

    そもそもやろうとしていることが無理なのでしょうか?
    ブラウザコントロールを別スレッドで動作させられれば良いのですが・・・

    プログラム内容

    フォーム1
     ボタン1(フォーム2を別スレッドで開く)と、ボタン2(そのフォームのラベルの表示/非表示を切り替える)があります

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            th = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf StartThread))
            th.SetApartmentState(Threading.ApartmentState.STA)
            th.IsBackground = True
            th.start()
        End Sub

        Sub StartThread()
            Form2.ShowDialog()
            'Application.Run(New Form2) '---- これでもだめ
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            'Call Sw()         ’-----
            Call Form2.F2Sw()   ’----- どちらの方法でもうまくいかない
        End Sub

        Delegate Sub SwDelegate()

        Sub Sw()
            If Form2.InvokeRequired Then
                Form2.Invoke(New SwDelegate(AddressOf Sw))
            Else
                Form2.Label1.Visible = Not Form2.Label1.Visible
            End If
        End Sub

    フォーム2

        Delegate Sub F2SwDelegate()

        Public Sub F2Sw()
            If Me.InvokeRequired Then
                Me.Invoke(New F2SwDelegate(AddressOf F2Sw))
                Return
            Else
                Me.Label1.Visible = Not Me.Label1.Visible
            End If
        End Sub

    2011年3月19日 6:09

回答

  • Form2 という型で利用していると言うことは、既定のインスタンスを使っていると言うことになるのでしょうか。
    これの振る舞いを確認していませんが、もしかしたら、メインスレッドとサブスレッドで違うものになっているのかもしれませんね。

    フォームのメンバー変数に明示的にインスタンスを生成し、それに対して ShowDialog や InvokeRequired を使うとどうなりますか?
    以下はイメージで、コンパイルを試していません。

    Private backgroundForm2 as Form2
    Sub StartThread()
     backgroundForm2 = New Form2
     backgroundForm2.ShowDialog()
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
     Call backgroundForm2.F2Sw()
    End Sub
    

    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同
    • 回答としてマーク SIMOZ 2011年3月19日 12:13
    • 回答としてマークされていない SIMOZ 2011年3月19日 12:17
    • 回答としてマーク 山本春海 2011年3月31日 9:02
    2011年3月19日 11:08
    モデレータ

すべての返信

  • Form2 という型で利用していると言うことは、既定のインスタンスを使っていると言うことになるのでしょうか。
    これの振る舞いを確認していませんが、もしかしたら、メインスレッドとサブスレッドで違うものになっているのかもしれませんね。

    フォームのメンバー変数に明示的にインスタンスを生成し、それに対して ShowDialog や InvokeRequired を使うとどうなりますか?
    以下はイメージで、コンパイルを試していません。

    Private backgroundForm2 as Form2
    Sub StartThread()
     backgroundForm2 = New Form2
     backgroundForm2.ShowDialog()
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
     Call backgroundForm2.F2Sw()
    End Sub
    

    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同
    • 回答としてマーク SIMOZ 2011年3月19日 12:13
    • 回答としてマークされていない SIMOZ 2011年3月19日 12:17
    • 回答としてマーク 山本春海 2011年3月31日 9:02
    2011年3月19日 11:08
    モデレータ
  • ありがとうございます。

    試してみました。何の問題もなく動作しました。
    インスタンスについて、もっと勉強する必要があるようですね。
    Accessではあまり意識したことがなく、そのままVBで行っていました。

    大変助かりました。重ねてお礼申し上げます。

    SIMOZ / ムライ

    2011年3月19日 12:17