#pragma twice

KAB-studio > プログラミング > #pragma twice > 042 Version 3.17 ダイアログの閉じ方

#pragma twice 042 Version 3.17 ダイアログの閉じ方

前のページへ 表紙・目次へ 次のページへ

 Version 3.17
ダイアログの閉じ方

今回からまたプログラミングの話に戻ります
ぶーぶー
って、ホントはそれが目的なんだから……
そういえば、リソース関係ってもういいってこと?
うん、後回しにしたところもあるけど、フリーウェアとしてリリースする
のに必要なとこは全部見たかな
ダイアログ、アイコン、ストリングテーブル、バージョン情報、ね
この4つを押さえれば大丈夫でしょ
ふーん
んじゃ、まずは簡単なテスト
ええっテスト!?
って火美ちゃんにじゃなくて、テスト用のプログラムを作るってこと
なぁんだ
そういえば、 Calc のプログラムの中で、実際に Calc ダイアログを表示
する部分がどこか憶えてる?
やっぱりテストじゃない!! えっとねぇ……はいヒット、CCalcApp クラ
スの InitInstance() ってメンバ関数の、定義、が書かれてるとこ
そう、 Ver 3.1 ( No.026 )で見たね。じゃ、その部分表示して
はーい。 File ……あ、クラスビューの方が早いかな。 ClassView の 
CCalcApp の InitInstance() で……

BOOL CCalcApp::InitInstance()
{
    // 略1。
    CCalcDlg dlg;
    m_pMainWnd = &dlg;

    int nResponse = dlg.DoModal();
    // 略2。
}

この dlg.DoModal(); ってとこでダイアログ表示してるんだよね
そうそう。で、この〈略2〉の直前に、この1行を追加して

    TRACE( "%d\n", nResponse );

なつかしー! これって確か、数字を見るのだよね
そう。ここでは nResponse の中身を見てみます
 nResponse ……って、すぐ上で作ってるのだね。んーと、なにやってる
んだろ
 dlg.DoModal(); の、戻り値を受け取ってるでしょ
戻り値……
関数を呼ぶと、その結果が〈戻り値〉って形で返ってくるでしょ。確か、
変数に置き換わるんだよとか教えたような……
 Ver 2.10 ( No.021 )で見たね。あ、こういうときは DoModal() のこ
と調べればいいんだよね
ちゃんと憶えてるじゃない
へへーん。 DoModal でダブルクリックして F1 っと。うぎゃ、いっぱい
出た!
さてどれでしょう
えーっと…… CCalcDlg ってないよ?
 DoModal() は CCalcDlg のメンバ関数じゃないでしょ。そのひとつ上
継承! そーそー、確か CDialog の DoModal() とかを使いたいから、継
承して CCalcDlg ってゆー……カスタマイズクラスを作ったんだ
思い出してきたね
まかせてよ! じゃ、 CDialog::DoModal() をダブルクリック!
 MSDN が開き、 CDialog::DoModal() のページが表示される。
戻り値は……〈ダイアログ ボックスを閉じる CDialog::EndDialog メン
バ関数の引数 nResult に渡す int 値を返します〉って、???
ま、世の中そんな甘くないよね
なんやとコラ
だからもっと調べないと。 CDialog::EndDialog は?
そっか、そーやってひとつずつ見てけばいいんだもんね。リンクたどって
 MSDN に CDialog::EndDialog() の情報が表示される。
えーっと、〈モーダル ダイアログ ボックスを終了します〉ってことは
〈モーダルダイアログ〉は普通のダイアログのこと。つまり
ダイアログを閉じるってこと?
そういうこと。んじゃ懐かしの、【=】ボタンを押したときの関数を開い

えっと、 CCalcDlg::OnBEqual()  だよね

void CCalcDlg::OnBEqual() 
{
    UpdateData( TRUE );
    m_iAns = m_iLh + m_iRh;
    UpdateData( FALSE );
}

これに1行書き加えて……

void CCalcDlg::OnBEqual() 
{
    UpdateData( TRUE );
    m_iAns = m_iLh + m_iRh;
    UpdateData( FALSE );

    EndDialog( 100 );   // この行を追加。
}

あ、結果想像できるかも。ビルドして実行! 数字書き込んで、【=】を
押すと……あ、 Calc ダイアログ閉じちゃった!
って感じに、 CDialog::EndDialog() を呼ぶとダイアログが閉じます。で、
ここでアウトプットウィンドウを見てみて
あれ、 100 って出てる
ここに、さっきの CDialog::EndDialog() に渡してる 100 って数字が出て
るわけ
???
ほら、 CDialog::DoModal() の戻り値の解説
あ、  CDialog::EndDialog の引数に渡してる……この 100 って数字が、 
CDialog::DoModal() の戻り値として返ってくるってことなんだ!
難しく書いてあったけど、そういうこと。で、この戻り値を
 TRACE() でアウトプットに出したってことねー
流れをまとめると

1: CDialog::EndDialog() を呼ぶとダイアログが閉じる。
2: CDialog::DoModal() から返ってくる。
3: そのときの戻り値が CDialog::EndDialog() に渡した数字。
4: それを TRACE() で出力してみた。

っていうテストをしてみたってことね
あ、さっき追加した行削除しておいてね
そりゃあれで閉じちゃったら計算機になんないもんね
さて、もう少し突っ込んで考えてみます。なんで、最初から付いてた【OK】
と【キャンセル】のボタンは、押すとダイアログが閉じるんでしょうか
そーいえば。【=】ボタンは押したって閉じないんだもんねぇ
じゃ、今度は Calc ダイアログをダイアログエディタで開いて
えーっと、 ResourceView の IDD_CALC_DIALOG っと
そしたら【OK】ボタンのプロパティを表示して
表示したら?
【ID】を IDOK から IDOK2 にしてビルドして実行
 IDOK2 にしてビルドして実行! 【OK】ボタン押してもダイアログ閉じ
なくなっちゃった
んじゃ元に戻して
 Calc ダイアログ閉じて……元に戻す、で、戻ったね。で、ビルドして実
行、今度はちゃんと閉じるよ
というわけで、実はボタンのIDが IDOK だから、自動的に閉じるんです
おー。ってことは【キャンセル】ボタン…… IDCANCEL ってIDだから
自動的に閉じるんだ
そういうこと。これが鍵になってます
これってウィンドウズの仕組み?
ううん、MFCの仕組み。それをこれから見てみるから。全文検索のこと
思い出してみて
えーっとねぇ、 Ver 3.8 ( No.033 )で使ったね。あのときはMFCの
プログラムの中から CWnd を探したんだよね。今度は?
今度は、同じMFCの中から IDOK を探してみて
はーい。メニューの【編集】−【ファイルから検索】っと、 IDOK を書き
込んで、フォルダをMFCのプログラムがあるとこにして、検索開始!
 アウトプットに結果が次々と表示される。
あ”、いっぱい引っかかっちゃった
でも見てくと、知ってる単語があると思うよ
知ってる単語ねぇ……あー!!

C:\(略)\MFC\SRC\DLGCORE.CPP(703): EndDialog(IDOK);

 EndDialog() ! これ?
これ。この行をダブルクリックして
 DLGCORE.CPP が表示される。 CDialog::OnOK() というメンバ関数の定義。
あ、こーゆーメンバ関数があるんだ
その下に CDialog::OnCancel() っていうのもあるよ
あらホント。もしかして、IDが IDOK のボタンだと、このメンバ関数が
呼ばれるってこと?
じゃ、試してみましょう。こういうときはどうすればいいと思う?
あ、えーと、 TRACE() を書き込む
MFCのプログラムなんだから書き換えちゃダメ! こういうときは、ブ
レークポイントをセットするの
あ、そうすればこの関数が呼ばれるか分かるもんね!
 EndDialog(IDOK); の行をクリックしたあと、ツールバーの【手のひら】
を押す。さらに EndDialog(IDCANCEL); にも同じことをする。行の頭に丸。
手慣れてきたね
こういうのって、ちょっとしてないと逆にできるようになんのかも。で、
ビルドして実行、【OK】ボタンを押す……あ、矢印出た!
 EndDialog(IDOK); の丸の上に矢印が表れ、プログラムが止まる。
はー、この EndDialog() が呼ばれるから、ダイアログが閉じるんだ。
ねー、まとめてみていい?
いいよ

1: OK ボタンが押される。
2: IDが OK のボタンが押されると、 CDialog::OnOK() が呼ばれる。
3: CDialog::OnOK() の中で、 CDialog::EndDialog() が呼ばれる。
4: だからダイアログが閉じる。

って感じ?
そういうこと。だから……
だから?
IDが OK なら、ボタンの名前はなんだっていいし、あとで貼り付けたボ
タンでも、IDが IDOK ならちゃんと閉じるから
なるほど
あと、なんで普通のボタンは呼ばれなくて、 IDOK とかは特別なのか
そうそう、それはどーして?
ってのはちょっと難しいからかなりあと
あらら
ただ、たとえば火美ちゃんが作った【=】が CCalcDlg::OnBEqual() を呼
び出すようになってるように、〈押されたボタンで呼び出されるメンバ関数
が選ばれる〉システムが備わってるってこと
【OK】ボタンのは最初からあって、【=】ボタンのは私があとから作った
ってことね
そういうこと
このシステムは、MFCの?
そう。だからもっとプログラムが読めるようになれば、そのシステムも直
接見られるようになるから
はー、かなり先っぽいけど……
さて最後。 CDialog::OnOK() では EndDialog(IDOK); 、 
CDialog::OnCancel() では EndDialog(IDCANCEL); が呼ばれてます
あ、ってことは CDialog::DoModal() の戻り値ってボタンのIDが返って
くるってことね
それを踏まえて次回に続く!

/*
    Preview Next Story!
*/
久しぶりのプログラミングだけど、どう?
んー、前の復習ばっかりだからそんなに難しくなかったかな
忘れる、ってことがないのは便利だなぁ……
というわけで次回
< Version 3.18 レジストリに保存しよう! >
につづく!!
どしたの?
ううん、なんかあっという間に追い抜かれそうな気が……
だからこんなのんびりなんだ
違いますっ!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。