OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

ダイアログを終了させてもハンドルが1つ増加したまま。。。

  • すぐに回答を!
  • 質問No.102703
  • 閲覧数599
  • ありがとう数2
  • 気になる数0
  • 回答数2
  • コメント数0

お礼率 71% (83/116)

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() するとリークが発生します。

識者の方、原因、対策など、ご教授願います。
通報する
  • 回答数2
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.2
レベル8

ベストアンサー率 60% (20/33)

//メンバ変数として
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;
}
}
こんな感じでモードレスダイアログできますよ。
じゃ。
お礼コメント
nabezo-

お礼率 71% (83/116)

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

その他の回答 (全1件)

  • 回答No.1
レベル8

ベストアンサー率 60% (20/33)

TestDlgThread関数の戻り値がないからでは、ないですか? てゆうか、モーダルダイアログじゃなくて、モードレスダイアログを作ったらどうでしょう? ...続きを読む
TestDlgThread関数の戻り値がないからでは、ないですか?
てゆうか、モーダルダイアログじゃなくて、モードレスダイアログを作ったらどうでしょう?
補足コメント
nabezo-

お礼率 71% (83/116)

すいません、記述もれです。
スレッドの関数では「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:02


このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ