VC++のMFCを使ってダイアログベースのEXEを造っています。
ハンドルのリークが発生し、困っています。

<動作内容>
メインのダイアログで、ボタン押下により別のダイアログを表示します。
DoModal()でモーダルダイアログを作成します。
別のプロセスからブロードキャストされるメッセージを処理したいため、
ボタン押下のルーチンで DoModal() せずに、スレッドを作成し、
そのスレッドで DoModal() を実行しています。
スレッド作成は AfxBeginThread() を使用しています。

<サンプルソース>
●メインダイアログ
// ボタン押下のルーチン
void CTestModalDlg::OnButton1()
{
AfxBeginThread( TestDlgThread, (LPVOID)this,
THREAD_PRIORITY_NORMAL );
}

// スレッド
static UINT TestDlgThread(LPVOID pThis)
{
CTestDlg1 Dlg;
Dlg.DoModal();
}

●DoModal() で表示されるダイアログ
何も手を加えてない、デフォルトのまま。

<結果>
DoModal() で表示されたダイアログを CDialog::OnCancel() で終了させ、
メインのスレッドが終了しても、ハンドルカウントが1つ増加しています。
Sleep() を入れて値をみてみると、
・スレッド作成:2増加
・DoModal() でダイアログ表示:1増加
・OnCancel() で終了:増減なし
・スレッド終了:2減少
=>結果、1増加となっていました。

以下のパターンでは問題ありませんでした。
・スレッドを作成+終了(ダイアログ表示しない)
・スレッドを作成せずに、ボタン押下ルーチンから
DoModal() でダイアログ表示+終了

ということで、AfxBeginThread()、DoModal() 自体は問題ないのですが、
スレッドを作成して DoModal() するとリークが発生します。

識者の方、原因、対策など、ご教授願います。

A 回答 (2件)

//メンバ変数として


CDialog* m_pDlg;

void CTestModalDlg::OnButton1()
{
if(m_pDlg==NULL){
m_pDlg=new CDialog;
m_pDlg->Create(IDD_DIALOG1);
m_pDlg->ShowWindow(SW_SHOW);
}
}

void CTestModalDlg::OnDestroy()
{
CDialog::OnDestroy();

if(m_pDlg!=NULL){
delete m_pDlg;
}
}
こんな感じでモードレスダイアログできますよ。
じゃ。
    • good
    • 0
この回答へのお礼

アドバイスありがとうございました。
なぜか、Create()、ShowWindow()してもダイアログが表示されませんでした。
メインのダイアログはアクティブな状態だったので、仕方なくキャンセルボタンを
押したらアプリケーションエラーになってしまいました。
デバッグしようと思ってステップ実行させたら、ちゃんとダイアログが表示されました。
不思議。。。
頑張ってやってみます。
いつも適切なアドバイスありがとうございます。

お礼日時:2001/07/13 19:04

TestDlgThread関数の戻り値がないからでは、ないですか?


てゆうか、モーダルダイアログじゃなくて、モードレスダイアログを作ったらどうでしょう?

この回答への補足

すいません、記述もれです。
スレッドの関数では「return(0);」しています。
スレッドからモーダルダイアログを作成しているのは以下の理由です。
・操作できるダイアログは一番上の(DoModalで作成された)ダイアログだけ
・DoModalで作成されたダイアログが閉じられたタイミングで(Domodal関数が
戻ってきた時)、処理をしたい。
・メインのスレッドでは、他のプロセスからのメッセージを受信したい

#「スレッド+モーダル」だけNGというのが解せないです。。。

あと、追加の質問のようになってしまい申し訳ないのですが、
モードレスダイアログの作成についてご存知でしたら教えてください。

サンプルソースを以下のようにしました。
IDD_DIALOG1 は、DoModal で表示しようとしていた CTestDlg1 クラスの
ダイアログのIDです。

void CTestModalDlg::OnButton1()
{
CDialog::Create( IDD_DIALOG1, NULL );
}

しかし、実行したところ Create() で落ちてしまいました。
単純に Create() だけでは駄目でしょうか?

補足日時:2001/07/12 10:13
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード


このカテゴリの人気Q&Aランキング

おすすめ情報

カテゴリ