モーダルなのに、処理が終わるまで表示されえない

[戻る]
なおぞう 2016/09/10(土) 18:11:16
いつもお世話になっております。
VS2010 VC++ MFC スタティックライブラリ マルチバイト 共通言語サポートしない
OS Win7 で開発をしております。

普通にプロジェクトを作って表示されたダイアログをそのまま使い、
OKボタンを押したらメインの処理ダイアログを表示させるプログラムです。

以下のように、TestListダイアログを呼んでいるのですが、
処理が終わるまでTestListダイアログが表示されませんでした。
TestListダイアログでは、Listbox Controlを使って、処理内容を随時表示しているの
で、画面が見えないと困ってしまいます。
TestListダイアログ処理内ではOnInitDialog()内を全てコメントにして、Sleep(20000)
で確認しても、やっぱり画面表示されなかったので、ここが悪いとしか思えないです。
この短文でどこが悪いのでしょうか?

分かるようでしたら教えていただけますようお願いします。
void TestDlg::OnBnClickedOk()
{
    // TODO: ここにコントロール通知ハンドラー コードを追加します。

    TestList listdlg;
    listdlg.DoModal();
    CDialogEx::OnOK();
}

瀬戸っぷ [E-Mail] 2016/09/12(月) 08:05:05
>TestListダイアログ処理内ではOnInitDialog()内を全てコメントにして、Sleep(20000)
>で確認しても、やっぱり画面表示されなかったので、ここが悪いとしか思えないです。


TestListダイアログのOnInitDialog()内で
>Listbox Controlを使って、処理内容を随時表示している
のでしょうか?

その場合、OnInitDialog()から抜けてこないとTestListダイアログのダイアログプロシー
ジャが先に進めませんが……。

なおぞう 2016/09/12(月) 11:04:41
> 瀬戸っぷさま

返信ありがとうございます。
まさに、OnInitDialog()の中で他の関数を呼び出していました…。
OnInitDialog()を抜けないと駄目だとはまったく知らず。

Formを作るのはやっていたのですが、ダイアログでの作業は今回が初めてなのですが
OnInitDialog()関数に処理内容を記述する以外にどうしたらよいのか分からないのです。

最初、1つめのダイアログ内で2個目のダイアログの関数を呼ぶように書いたのですが、
コールしなかったので、OnInitDialog()関数に記載してました。
すみませんが、どのように記載すれば、OnInitiDialog()を抜けて、かつ2個目のダイアロ
グ内で処理をする関数を呼び出すことができるのか教えていただけますようお願いします。

void TestDlg::OnBnClickedOk()
{
    // TODO: ここにコントロール通知ハンドラー コードを追加します。

    TestList listdlg;
    listdlg.DoModal();

>> listdlg.LoadFile(); <<

    CDialogEx::OnOK();
}

瀬戸っぷ [E-Mail] 2016/09/12(月) 12:33:16
MFCでのやり方についてはちょっとよく判りませんが…。

>どのように記載すれば、OnInitiDialog()を抜けて、かつ2個目のダイアロ
>グ内で処理をする関数を呼び出すことができるのか教えていただけますようお願いします。

OnInitDialog()でスレッドを作成して、そのスレッド内でもろもろの処理を実施する。
というところでしょうか。
ダイアログ上の表示などを更新する為にメッセージを飛ばすこともあるかと。

ダイアログを閉じた時など、スレッドを途中で(安全に)中断できるようにしておく必要も
あるので注意が必要かも知れません。

なおぞう 2016/09/12(月) 14:01:41
>瀬戸っぷ様
早速の回答ありがとうございます。
スレッドですかぁ…苦手です。
調べてみてやってみます。
アドバイスありがとうございます。

ITO 2016/09/12(月) 21:29:14
>スレッドですかぁ…苦手です。
処理の大小に関連しますね。
また、処理が終わりダイアログが表示されるまで、
メインダイアログで、「お待ちください!!」と表示して待つ方法もありますね。
まぁ、処理に時間がかかるならスレッドしかないですね。

なおぞう 2016/09/13(火) 12:55:29
>ITO様
書き込みありがとうございます。
処理に時間がかかるのです…。
ネットでスレッドの書き方について調べてみたのですが、自分のケースはどんなふうに書
けばよいのか分からなくて、保留して他のコーディング進めてます。

ダイアログがない場合のスレッド(DLLの作成)は、やった事あるのですけど(確か、そ
の時もこのサイトでお世話になりましたが)

AR 2016/09/14(水) 10:06:02
 とりあえず画面が出ればいいという事であれば、子ダイアログからWM_TIMERを使って遅
延実行すると良いかもしれません。
 OnInitDialog()でSetTimer()を用いてタイマーをセットし、OnTimer()内で遅延実行す
ることで実現できます。

 極めて単純な方法ですが、一般的には素直にモーダレスダイアログを使うべきだと思い
ますよ。

なおぞう 2016/09/14(水) 11:41:07
>ARさま

書き込みありがとうございます。
モードレスでもいいか。とためしてみたんです、投稿前に。
でも、なぜか一瞬で消えてしまう。
これに関しては数名がネットで質問してるのですが、回答がいろいろあって良く分からな
くて、モードレスも止めてしまったのでした。
やっぱりスレッドについてちゃんと調べないと駄目ですね。今後の勉強にもなりますし。
とはいえ、モードレスも今までは使った事がないのですがいずれは使うでしょうし、こっ
ちもいつかは理解しなくてはいけない内容です。

ITO 2016/09/15(木) 09:44:55
モードレスダイアログ説明

本家
https://support.microsoft.com/ja-jp/kb/403848

-1
http://www.page.sannet.ne.jp/mtoga/lang/cv/bih-m_57.htm

-2
http://www7b.biglobe.ne.jp/~makandat/VC/Group5/Modeless.htm

ITO 2016/09/15(木) 11:18:54
あと、リソースの設定で、「表示する」にしないとだめですね。

なおぞう 2016/09/15(木) 15:18:58
>ITO さま

分かりやすい説明のサイトを教えていただきありがとうございます。
活用させていただきます。

なおぞう 2016/10/03(月) 14:58:41
[[解決]]
モードレスダイアログを作成してなんとか要望通りの動きにすることができました。

いろいろありがとうございました。
閉じます。

古いスレッドには追加発言できません。