トップ回答者
サブウィンドウからの戻る際のちらつきについて

質問
-
初めまして。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を行った場合に、
ちらつきが発生する根本的な原因がわかりません。
根本的な原因を分かる範囲で教えて頂けないでしょうか?よろしくお願い致します。
回答
-
現象が発生する状態にして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
すべての返信
-
細かいメカニズムは忘れたと言うより、調べてなかったかもしれませんが、基本的に ShowDialog から抜けてくる前に Dispose すると問題が起きます。
基本的に、ShowDialog から抜ける前に Dispose を呼ぶのは NG と考えてください。以下は推測です。
たぶん、Dispose を呼んだ場合は、親 or オーナーフォームをアクティブにしようとするのだと思われますが、この時点でそのフォームはまだ無効状態なので、アクティブにできず、別のアプリケーションなどにアクティブが移るのではないでしょうか。
質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。 -
現象が発生する状態にして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
-
返信ありがとうございます。
Azulean様
>細かいメカニズムは忘れたと言うより、調べてなかったかもしれませんが、基本的に ShowDialog から抜けてくる前に Dispose すると問題が起きます。
>基本的に、ShowDialog から抜ける前に Dispose を呼ぶのは NG と考えてください。了解しました。
漏れがないように、親にも子にもDisposeを記述していたのですが、今後気をつけます。
>以下は推測です。
>たぶん、Dispose を呼んだ場合は、親 or オーナーフォームをアクティブにしようとするのだと思われますが、この時点でそのフォームはまだ無効状態なので、アクティブにできず、別のアプリケーションなどにアクティブが移るのではないでしょうか。
なるほどです。参考になります。
-
返信ありがとうございます。
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様にもご指摘いただきましたので、
今後気をつけます。
ありがとうございました。