AfxMessageBoxのモーダル化について教えてください。
現在、ダイアログクラスのOnTimerでAfxMessageBoxを使っているのですが、モーダレス状態で表示されてしまいます。
OnTimerではスレッドが立てるフラグを監視しており、フラグの値によってメッセージの内容を変更しています。
スレッドはダイアログから起動しています。
そもそもAfxMessageBoxはモーダルだと思っていたのですが、スレッドから呼び出すとモーダレスになるということを知りました。
AfxMessageBoxでOKを押すまでは他の処理を行えないようにしたいのでモーダルで表示したいのですが、何かいい方法はないでしょうか?
宜しくお願いします。
> スレッドから呼び出すとモーダレスになる
この文脈におけるスレッドという文言の解釈が不能なのだが
・ worker thread を作って
・その中から AfxMessageBox を呼んだ
ということかな?それなら VS2005 で試してみた。モーダルに動く。
void CHogeApp::OnTest() { // menu ハンドラ
AfxBeginThread(&CHogeApp::ThreadFuncSugar, this);
}
static UINT CHogeApp::ThreadFuncSugar(void* p) {
return reinterpret_cast<CHogeApp*>(p)->thread_func();
}
UINT CHogeApp::thread_func() {
AfxMessageBox(_T("TEST"));
return 0U;
}
// 例は SDI だが Dialog ベースでも同等の動きをしている
何か特殊なことをしているに違いない、に1票。
OnTimer云々というところを信じてみると、
1)OnTimer内でメッセージボックス表示
2)ここでモーダルで処理待ち
3)表示中にタイマーイベントが入ってくる
4)OnTimerの処理が走る
で、モーダルでは出ているけどまたタイマー処理が
走るのでモードレスと勘違いしている可能性あり。
ホントにこの現象ならメッセージボックス表示前に
KillTimer、表示から抜けたところで再度SetTimer。
1.スレッドはDLGが起動した。
2.メッセージボックスもDLGが起動した(みいさん説を支持)。
3.この状態でスレッドが停止することを期待している(誤り)。
というシナリオもあるかも。
この場合はtetrapodさんのコードが正解。
DLG、スレッド、タイマー、MsgBoxの関係を
もちっと詳しく説明してみてはどうでしょう。
みなさんコメントありがとうございます。
説明不足で申し訳ありません。
処理の流れは以下の様になっています。
ダイアログがスレッド起動
↓
タイマーで開始
↓
スレッド処理終了→処理終了フラグ設定
↓
タイマーで処理終了フラグの値をみてメッセージボックス表示
・タイマーに入った際処理終了フラグを見てるのですが、終了フラグを判定した時点でタイマーは止めています。
・メッセージボックスはOnTimerの中で表示しています。
・スレッド処理中は処理中画面の別ダイアログを表示していますが、このダイアログはKillTimerのあと、メッセージボックスを表示する前にメッセージを飛ばして閉じています。
昨日から調べているのですが、処理中ダイアログを閉じるタイミングとメッセージボックスを表示するタイミングが絡んでいるような気配です。
#処理中ダイアログが完全に閉じられてない状態で表示しようとしている?
この辺、調べてまた報告させていただきます。
具体的にどのような状況になっている事を問題視している?
メッセージボックスを出している最中なのに、他のウィンドウ(例えばメッセージボックスの親ウィンドウ)に触れてしまう?
メッセージボックスを出している最中なのに、OnTimer が再度処理されてメッセージボックスが複数出てしまう?
等。
>#処理中ダイアログが完全に閉じられてない状態で表示しようとしている?
閉じること自体は成功してるのかな?
それとも、成功できずに、
「処理中」と「Afx〜でつくる」の2つのダイアログが立ち
それがどっちも操作(マウスでドラッグ移動など)ができるので
モードレスになってると判断されたという感じでしょうか?
>そもそもAfxMessageBoxはモーダルだと思っていたのですが、
>スレッドから呼び出すとモーダレスになるということを知りました。
これ、OnTimer()内で呼び出しているのであり、先の発言は完全に無しでいいのでしょうか?
それとも、何か(勘違いとしてもその要因になるような作業)あるのでしょうか?
ツイート | ![]() |