none
サブウィンドウからの戻る際のちらつきについて RRS feed

  • 質問

  • 初めまして。yamanobuと申します。

    初めて投稿させて頂きます。

    失礼な文章等がありましたら申し訳ありません。

    質問ですが、

    メイン画面(FormA)からShowDialogメソッドを使用して、

    サブウインドウ(FormB)を起動した後、サブウィンドウ(FormB)を閉じてメイン画面に戻った際に、

    一瞬、他のウィンドウがアクティブになり(これをちらつきと言っています。)、

    メイン画面がアクティブになります。

    ソースは以下に記述します。


        public partial class FormA : Form
        {
            public FormA()
            {
                InitializeComponent();
            }

            private void button6_Click(object sender, EventArgs e)
            {
                FormB abc = new FormB();

                abc.ShowDialog();
            }

        public partial class FormB : Form
        {
            public FormB()
            {
                InitializeComponent();
            }

            private void FormB_FormClosing(object sender, FormClosingEventArgs e)
            {
                this.Dispose();
            }
        }

    質問として、メイン画面(FromA)でサブ画面(FormB)のDisposeすれば、
    ちらつきは解消されることは、分かっているのですが、
    上記ソースのように、サブ画面(FormB)側でDisposeを行った場合に、
    ちらつきが発生する根本的な原因がわかりません。
    根本的な原因を分かる範囲で教えて頂けないでしょうか?

    よろしくお願い致します。

     

    2011年7月29日 8:38

回答

  • 現象が発生する状態にしてSpyでWindow Messageのやり取りを見てみると、
      1.WM_ACTIVATEAPP fActive = false で自分のApplicationがdeactiveになる
      2.WM_ACTIVATEAPP fActive = true で自分のApplicationがactiveになる

    という流れになります。この流れでつらつきが発生しています。

    また、FormClosingでDisposeしてしまうと、
    その後のShowDialog内の残りの処理(modal用のmessage loopから抜けた後の処理)で不整合が起きるため、
    ShowDialogを抜けてからDisposeしてください。

    • 回答としてマーク yamanobu 2011年8月1日 1:45
    2011年7月31日 10:04

すべての返信

  • Form の Closed イベントで Dispose したらどうなりますか?

    2011年7月29日 8:50
  • ShowDialog() に親ウィンドウを与えてあげてください。通常は this かと思います。

    簡略化の都合であればしかたがないのですが、可能であれば Dispose は親側のほうがすっきりするかもしれません。

    using (FormB abc = new FormB())
        abc.ShowDialog(this);

     

    2011年7月29日 8:55
  • 細かいメカニズムは忘れたと言うより、調べてなかったかもしれませんが、基本的に ShowDialog から抜けてくる前に Dispose すると問題が起きます。
    基本的に、ShowDialog から抜ける前に Dispose を呼ぶのは NG と考えてください。

    以下は推測です。

    たぶん、Dispose を呼んだ場合は、親 or オーナーフォームをアクティブにしようとするのだと思われますが、この時点でそのフォームはまだ無効状態なので、アクティブにできず、別のアプリケーションなどにアクティブが移るのではないでしょうか。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年7月29日 14:27
    モデレータ
  • 現象が発生する状態にしてSpyでWindow Messageのやり取りを見てみると、
      1.WM_ACTIVATEAPP fActive = false で自分のApplicationがdeactiveになる
      2.WM_ACTIVATEAPP fActive = true で自分のApplicationがactiveになる

    という流れになります。この流れでつらつきが発生しています。

    また、FormClosingでDisposeしてしまうと、
    その後のShowDialog内の残りの処理(modal用のmessage loopから抜けた後の処理)で不整合が起きるため、
    ShowDialogを抜けてからDisposeしてください。

    • 回答としてマーク yamanobu 2011年8月1日 1:45
    2011年7月31日 10:04
  • galaco様

    返信ありがとうございます。

    >Form の Closed イベントで Dispose したらどうなりますか?

    FormのClosed イベントでDispose を行ってもちらつきは発生いたします。

    2011年8月1日 1:50
  • 他の方が仰っているとおり、閉じてから Dispose した方がいいみたいですね。

     

    2011年8月1日 1:55
  • 返信ありがとうございます。

    K.Takaoka殿

    親側でDisposeを行い、ちらつきが解決するのですが、

    説明不足で申し訳ありませんでしたが、

    なぜ子ウィンドウでDisposeを記述するとちらつきが発生するのかという、

    メカニズムというか、理由を知りたかった次第です。

    2011年8月1日 1:56
  • 返信ありがとうございます。

    Azulean様

    >細かいメカニズムは忘れたと言うより、調べてなかったかもしれませんが、基本的に ShowDialog から抜けてくる前に Dispose すると問題が起きます。
    >基本的に、ShowDialog から抜ける前に Dispose を呼ぶのは NG と考えてください。

    了解しました。

    漏れがないように、親にも子にもDisposeを記述していたのですが、今後気をつけます。

    >以下は推測です。

    >たぶん、Dispose を呼んだ場合は、親 or オーナーフォームをアクティブにしようとするのだと思われますが、この時点でそのフォームはまだ無効状態なので、アクティブにできず、別のアプリケーションなどにアクティブが移るのではないでしょうか。

    なるほどです。参考になります。

     

     

    2011年8月1日 2:01
  • 返信ありがとうございます。

    kozz様

    >現象が発生する状態にしてSpyでWindow Messageのやり取りを見てみると、
    > 1.WM_ACTIVATEAPP fActive = false で自分のApplicationがdeactiveになる
    > 2.WM_ACTIVATEAPP fActive = true で自分のApplicationがactiveになる
    >という流れになります。この流れでつらつきが発生しています。

    なるほどです。

    SpyでWindow Messageのやり取りをみればよかったのですね。

    恥ずかしながらSpyの存在をしらなかったため、とても参考になりました。

    >また、FormClosingでDisposeしてしまうと、
    >その後のShowDialog内の残りの処理(modal用のmessage loopから抜けた後の処理)で不整合が起きるため、
    >ShowDialogを抜けてからDisposeしてください。

    この点については、Azulean様にもご指摘いただきましたので、

    今後気をつけます。

    ありがとうございました。

    2011年8月1日 2:13