DoModal中のダイアログを別スレッドから閉じる方法 – プログラミング – Home

DoModal中のダイアログを別スレッ...
 
通知
すべてクリア

DoModal中のダイアログを別スレッドから閉じる方法


ぽちこう
 ぽちこう
(@ぽちこう)
ゲスト
結合: 14年前
投稿: 5
Topic starter  

お世話になります。

OS : WinServer 2003
開発環境 : VS2008

現在MFCにてダイアログアプリケーションを作成しています。

プログラム中に重い処理が存在するため、その処理を別スレッドにて実行し、
その処理が完了するまでメッセージダイアログをDoModal()にて表示する。
重い処理が終了後、別スレッドからメッセージダイアログのEndDialog()を呼び出すこと
でメッセージダイアログを閉じる、といった実装を考えています。

//サンプルコード
static UINT AFX_CDECL ThreadProc(LPVOID pParam)
{
CSampleDlg* pDlgSample = (CSampleDlg*)pParam;

//重い処理
execute();

//メッセージダイアログを閉じる
pDlgSample->EndDialog(1);

return 0;
}
void SampleFunc(){
CSampleDlg dlgSample; //メッセージダイアログ

//スレッドを生成
AfxBeginThread(ThreadProc, &dlgSample);

//メッセージダイアログを表示
dlgSample.DoModal();
}

上記コードを実行すると、
//メッセージダイアログを閉じる
pDlgSample->EndDialog(1);
の箇所でアクセス違反が発生してしまいます。

上記方法でダイアログを閉じるのは適切ではないのでしょうか?
また、適切な方法があれば教えて頂けると有難いです。

宜しくお願いします。


引用解決済
トピックタグ
ホウジョウウサギ
 ホウジョウウサギ
(@ホウジョウウサギ)
ゲスト
結合: 17年前
投稿: 73
 

スレッドはダイアログに何かメッセージをポストして終る
→ダイアログ側がそのメッセージのハンドラでEndDialog()

ではどうでしょうか.
あと,提示コードの場合だと,
dlgSample.DoModal()の前にスレッドが終わってしまったりすると
どうなるのだろうか? とか個人的に不安になります.


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

CWnd でなく HWND に対して WM_CLOSE を送ればいけるはず。

> dlgSample.DoModal()の前にスレッドが終わってしまったりすると
御意。
全体的に堅牢性に不安が残るので、もっと安全に実装したほうがいいと思う。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

 メッセージ用ダイアログは、モードレスにしたほうがいいですね。
 
 すべてのボタンを「なし」に設定するといいと思います。

  WM_TIMERでフラグを監視して、重い処理が終了したら
   DestroyWindow();を実行して終了する。
 でどうでしょうか?


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
 

CSampleDlg の OnInitDialogでスレッドをm_AutoDeleteをFALSEで開始して,
あとはタイマで待つ(WaitForMultipleObjectsなんか)
でシグナルで自分(CSampleDlg)をEndDialog
なんかどうでしょ?
DoModal前にスレッドが終わることもないし,
確実にダイアログも終わらせそうです

で,いかがでしょうか


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

自分の発言は補足です。
CWndは「それを生成したスレッドに依存」してます。
従ってCWndのインスタンスをスレッドをまたいだ処理で利用することはできません。
つまりスレッド関数にCWnd *を渡す方法は、一般にはやってはいけないことです。
ただし、tetrapod さんの発言どおりHWNDを使用した処理は有効ですので、
その目的だけならOKです。


返信引用
ツPツAツTツIツO
 ツPツAツTツIツO
(@ツPツAツTツIツO)
ゲスト
結合: 14年前
投稿: 3
 

CWndクラスから派生したインスタンスをスレッド間で
やり取りしてはいけないと言うのはマイクロソフトが
はっきりとMSDN内で書いているのでそれを確認してください。
解決手段としては既にHWNDを使った話が出ているので
そちらを使います。

あと、やり方論としてモーダルダイアログの方で
ワーカースレッドを上げて自分自身のHWNDを渡しておいて
ワーカースレッドはモーダルダイアログにユーザー定義の
ウインドウメッセージを送って動作完了を通知する。
モーダルダイアログはウインドウメッセージを受け取ったら
ワーカースレッドの終了を確認して自分自身のEndDialogを
呼び出すでも良さそうな気がしました。
まあ、ワーカースレッドに渡す情報が必要な場合に
一旦、モーダルダイアログに引き渡すような処理が必要に
なるかもしれませんけれど。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

がーん、Firefox4にしてからオートコンプリートが
化けるようになっていたの忘れてた。

上の投稿は、私の投稿です。
あしからず。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました