#pragma twice

KAB-studio > プログラミング > #pragma twice > 043 Version 3.18 クラスを超えたおつきあい

#pragma twice 043 Version 3.18 クラスを超えたおつきあい

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

 Version 3.18
クラスを超えたおつきあい

前回は、なんでダイアログが閉じるのか見てみました
結局は EndDialog() ってのが呼ばれるかどーかよね
で、この関数に渡された値が
 CDialog::DoModal() の戻り値になって返ってくる!
【OK】ボタンと【キャンセル】ボタンの場合はどうなんだっけ
えっと、【OK】の方は IDOK 、【キャンセル】の方は IDCANCEL を 
EndDialog() に渡してたんだよね
ではそれを踏まえて、この前見た CCalcApp::InitInstance() をもう一度
見てみましょう

BOOL CCalcApp::InitInstance()
{
    // 略

    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: ダイアログが <OK> で消された時のコードを
        //       記述してください。
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: ダイアログが <キャンセル> で消された時のコードを
        //       記述してください。
    }

    // 略
}

あ、えーと、なんとなーく分かるような……
1行ずつ、ゆっくりと見ていけば分かると思うよ
んじゃゆっくりと。まず DoModal() んとこでダイアログ作ってるのよね
そう。ダイアログが閉じるまで、この関数から返ってきません
で、返ってきたときの戻り値が、 nResponse って変数に入って
ちなみに nResponse ってのは、〈整数〉って意味の n と〈反応〉って意
味の Response から来てます。ま、これがMFC流ってとこかな
……ちょっと静かにしてくんない?
はい……
で、 if ってことは、 nResponse が IDOK かどうかってのを見てるんだ
よね
……
参照くらい言っていーよ
はいはい。えっと、 if は Ver 2.8 ( No.019 )で、 == は Ver 2.6
( No.017 )に書いてあります
もし nResponse が IDOK なら、〈ダイアログが <OK> で〉とか書かれて
る、中カッコと中カッコ閉じの中に入って、そうでないなら次の else if
に……
 else if も Ver 2.8 ( No.019 )に書いてあります
 else if の方で、もし、 nResponse が IDCANCEL なら、〈ダイアログが 
<キャンセル> 〉とか書かれてる中カッコと中カッコ閉じに入る……
つまり?
つまり、戻り値が IDOK なら上の TODO んとこに、 IDCANCEL なら下の 
TODO んとこに行くってことでしょ?
もう少し言うと?
え?
その戻り値って、なんで返ってくるんだっけ
 EndDialog() の……あ、つまり【OK】ボタン押したら上の、【キャンセル】
押したら下のってことなんだ!
そういうこと。MFCがそういうプログラムを用意してくれてるってこと
だね
ほー
ちなみにこういう if の使い方はとーってもオーソドックスなものだから、
簡単に書けるようにね
こういうって?
関数の戻り値をチェックして、それに合わせて処理するって方法のこと
なるほど。書けなきゃダメ?
だめ。いくらなんでもこれくらいはそらで書けないと
ぶー
んじゃ今回の目的。今日は〈【OK】ボタンを押したらアウトプットに結果
を表示する〉ってプログラムを作ります
……〈【OK】ボタンを押したら〉は、上の TODO に書けばいいってのは分
かるけど、そのあとが……ねぇ
〈アウトプットに表示する〉のは分かるでしょ?
 TRACE() 使えばいいんだよね。ってことは、〈結果〉が分かればいいんだ
じゃ、ここで先週に引き続き CCalcDlg::OnBEqual() を見てみましょう

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

これは何してるんだっけ?
えーっと、確か、 m_iAns とかは、ダイアログに張り付いてるエディット
ボックスとくっついてるんだよね
 Ver 3.11 ( No.036 )だね
で、UpdateData( TRUE ) でエディットから m_iAns とかに数字を渡して、
UpdateData( FALSE ) でその逆に m_Ans とかからエディットに渡すんだよね
そう。で?
で……あ、で、真ん中の行で足し算して、 m_iAns の中に答を入れて、そ
れが次の行でエディットに書き込まれるって仕組みだったよね、確か
そういうこと。ってことはつまり、計算結果は m_iAns に入ってるってこ
とでしょ
あ、そっか! この m_iAns の中身が分かれば、結果が表示できるんだ。
でもどうやって?
 m_iAns ってなんだっけ
えーっと、エディットボックスと結びつけられてる変数
なに変数だっけ
あ、メンバ変数!
そう。 CalcDlg.h の中に……

class CCalcDlg : public CDialog
{
// 略
    int     m_iAns;
    int     m_iLh;
    int     m_iRh;
// 略
};

こういうふうにすると、 CCalcDlg のメンバ変数になります
 CCalcDlg のどんなメンバ関数からでも使えるんだよね
メンバ変数については Ver 3.7 ( No.032 )を見てください。で、 m_iAns
は CCalcDlg のメンバ変数でしょ
うん
で、表示したいのは CCalcApp::InitInstance() の中
あ、クラスが違うんだ!
そう、今回の鍵はまさにそこにあるわけ。 CCalcApp::InitInstance() を
もう一度見てみると……

BOOL CCalcApp::InitInstance()
{
    // 略

    CCalcDlg dlg;
    m_pMainWnd = &dlg;

    int nResponse = dlg.DoModal();

    // 略
}

あ、この CCalcDlg の変数 dlg を使って、ダイアログを表示してるんだ
から……
つまり、この dlg って変数の中に m_iAns が入ってるってこと。これが
取り出せれば
取り出せれば目的完了! でもどうやって?
ところで dlg.DoModal() って何してると思う?
ダイアログ表示してるんでしょ?
いや、もっと細かく言うと……
えっと、 CDialog の DoModal() ってメンバ関数を……あ
んじゃ思う通りに作ってみてみ?
んっと……

    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: ダイアログが <OK> で消された時のコードを
        //       記述してください。
    }

の TODO のとこに、あ、えーっと
細かく細かく、だよ
あ、じゃあとりあえずいつもの TRACE() を

        TRACE( "%d\n",  );

その2番目の引数に、数字にあたる変数を入れればいいんだから
……もうひとつ変数作っていい?
もちろん

        int i;
        TRACE( "%d\n", i );

で、この i に……あってますように

        int i = dlg.m_iAns();
        TRACE( "%d\n", i );

って感じに、メンバ変数もメンバ関数と同じふーに
変数なんだから小カッコはいらないでしょう
あ、そっか。ってことは当たり?
そういうこと!

        int i = dlg.m_iAns;
        TRACE( "%d\n", i );

って書き直してビルドして実行、左に 100 、右に 250 、【+】ボタン押
して結果は 350 、そして【OK】ボタンを押すと……
 アウトプットに 350 と表示される。
やったー!! なんだ楽勝じゃん
またそーゆーことを……。ま、こんなふうに、メンバ関数と同じようにメ
ンバ変数にアクセスできるってことは分かった?
うん分かった!
んじゃ問題
げげ!
ダイアログが表示されたときに、答の部分に 100 が表示されるようにす
るにはどうすればいいでしょう
おんなじふーにすればいーの?
そうだよ。ダイアログが表示する前に、値を入れとかないといけないから
 DoModal() を呼ぶ前ってことでしょ、ってことは……

    dlg.m_iAns = 100;   // ここに追加。
    int nResponse = dlg.DoModal();

って感じじゃない?
正解! 結構分かってきたかな?

/*
    Preview Next Story!
*/
レジストリってよく聞くよね
照り焼きにして食べるとおいしいんだ
あたしはカレーがいーな
照り焼き!
カレー!
というわけで次回
< Version 3.19 レジストリに保存しよう! >
につづく!!
でも〈なんとかとり〉って名前の鳥ってあんまいないけど
コウノトリ?
コウノトリ食うんかい
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。