#pragma twice

KAB-studio > プログラミング > #pragma twice > 046 Version 3.21 イベントハンドラ

#pragma twice 046 Version 3.21 イベントハンドラ

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

 Version 3.21
イベントハンドラ

さて前回は安全性について見てみました
そのネタは今回不可。さて問題。火美ちゃんが〈プログラムとして〉書き
込んだのはどこ?
プログラムとしてって?
つまり【バージョン情報】とか【ダイアログ】以外ってこと
あー。んっと、もーなんども使ってる CCalcDlg::OnBEqual() の中と、最
近よく使う CCalcApp::InitInstance() の中
そうでした。このふたつのメンバ関数ってどういう意味だっけ
 OnBEqual() はボタン押したとき、 InitInstance() は確か、アプリが実
行されたときに呼ばれるんだよね
そうそう。でもなんで InitInstance() にプログラムを書こうって決めた
のかな?
自分の頭で
そうそう物事は自分で決めなあかんねってそうじゃなくって
確か最初っから作られてたプログラムの中で、ほら、 CCalcDlg 作ったり、
戻り値チェックしてOKボタン押されたとかのプログラムがあったからじゃな
い?
そのとおり! つまり、火美ちゃんのプログラムは〈あらかじめ VC が作
ってくれたプログラムにちょっと手を加えただけ〉なわけ
ま、確かにそういうことになるよ、ねぇ
しかし!
しかし?
このふたつのメンバ関数、クラスが違うでしょ
うん違う。 CCalcDlg と CCalcApp だもんね
でも InitInstance() の中でしてる〈レジストリと変数のやりとり〉って、
本当はダイアログ側の仕事じゃない?
そう言われてみればそうかも。だって OnBEqual() ってボタン押したとき
のでしょ? なのに【OK】ボタンだけ特別扱いって変じゃない?
そこで今回は CCalcApp::InitInstance() に書いたプログラムを CCalcDlg
へと移します!
……ええっ!? そんなことできるの?
できるのって思うでしょ。それが大事
どゆこと?
プログラムって、実はとっても自由度が高いから、たいがいのことはでき
るんだけど、それが最初は分かんないんだよね
もちろん、知らないんだから。あ、つまり知ればできる?
そゆこと。ただ単に VC が作ったプログラムに書き加えるだけじゃなくて、
どういうプログラムが組めるのか、本当はどういう仕組みになっているのか、
ってことを知ることが大事
って前もそんなこと言ってたね
まーね、それが一番の柱だから。というわけで、具体的にプログラムを組
んで試してみましょう
おー!
さて、まず〈ダイアログを表示するときに【Ans】エディットボックスに 
10000 という数字を入れる〉ってことを考えてみます
レジストリは?
それはあと。プログラムは
簡単なことの積み重ね、だね
そゆこと
じゃーえっと、まず CCalcApp::InitInstance() の代わりになる CCalcDlg
のメンバ関数を……どうするの?
 CCalcApp::InitInstance() の中でも〈あらかじめ数字を入れとく〉って
いうのは、ダイアログが表示される直前でしょ。つまり〈ダイアログが表示
される直前に呼ばれるメンバ関数〉があればいいわけ
なるほど。アプリが実行されたら呼ばれる CCalcApp::InitInstance() 、
ボタンを押されたら呼ばれる CCalcDlg::OnBEqual() 、みたいにね
ちなみにこういう〈タラレバ〉を〈イベント〉、呼ばれるメンバ関数を
〈イベントハンドラ〉って言います

〈ダイアログが表示される〉とか〈ボタンが押される〉とかを〈イベント〉
って言います
あー、本日のメーンイベントーっ! ってヤツ?
そうそれ。日本語に訳せば〈出来事〉ってとこかな。で、そのイベントに
対応するメンバ関数を〈イベントハンドラ>って言います
ハンドラ?
英語で書けば Handler 。車のハンドルの er 付けたの。つまり〈操作す
るもの〉ってとこだね
ボタンを押したってイベントがあって、それを操作するメンバ関数、イベ
ントハンドラが CCalcDlg::OnBEqual() なんだ
そういうこと
……そう言えばさ
さて次
質問!
却下します
……ねー、前に〈ハンドル〉って出てきたじゃない、 HWND とか
あー……
あれとどういう関係が
ぜんっぜんありません!!
はひ?
確かに英語としての元の意味は同じだけど、ハンドルとハンドラはぜんっ
ぜん違うものです。ここんとこ絶対に間違えないように
は、はぁ……あ、だから触れたくなかったってこと?
まーそういうこと。プログラミングには〈似てるけど違うもの〉って多く
てね、そういうのを見分けるのが大事
だったらちゃんと教えてくれないと〜
……そうかも。さて話を戻して……
〈ダイアログが表示される直前に呼ばれるメンバ関数〉がなんなのか、で
しょ
そうそう。自分で調べてみ?
ってことは見つかりやすいってことなのかな。えっと、困ったときの 
MSDN! んーと、 CCalcDlg のを見ればあるかなぁ……
 MSDN を開き、キーワードに CCalcDlg と入力。
ないじゃん
おいおーい
あ、はいはいはい、 CCalcDlg は CDialog から作ったカスタマイズクラ
スだもんね。えっと、 CDialog っと
 【CDialog クラスメンバ】のページを表示する。
んー……ああっ!! OnInitDialog() なんてそれっぽくない? 【ダイ
アログ ボックスの初期化】とか書いてあるし!
大当たり! 実はそれが、初期化用の関数です
でもなに、〈オーバーライド〉とかって。どう使えばいいのかな……
思い出してみれば?
思い出す、ってことは使ったことがあると。えーっと……あ
 エディタに CalcDlg.cpp を表示させスクロール。
あった! なんだ、最初っからあるんだ
ダイアログにアイコンをセットする処理とか用に、 VC が作ってたわけ
いたれりつくせり。んじゃプログラム書いちゃおう! って……
なにすんだっけ?
答に数字入れる! えーっと、 CCalcApp::InitInstance() の時は

    dlg.m_iAns = GetProfileInt( cDialogStr, cAnsStr, 0 );

って感じになってて、これを 10000 に置き換えると……

    dlg.m_iAns = 10000;

だよね
そうそう
で、 CCalcDlg::OnInitDialog() を眺めてみるとですねぇ……

BOOL CCalcDlg::OnInitDialog()
{
// 略
    // TODO: 特別な初期化を行う時はこの場所に追加してください。

    return TRUE;  // TRUE を返すと(略)。
}

ってことはやっぱこの TODO んとこでしょ!
おおっ分かってきたねー
じゃーそのまんま書いて……

    // TODO: 特別な初期化を行う時はこの場所に追加してください。
    dlg.m_iAns = 10000;

かな?
ふたつ間違い
ええっ!?
ま、とりあえずビルドしてみるとか
ぶー

error C2065: 'dlg' : 定義されていない識別子です。

定義されてない、ってことは……
 dlg なんて変数どこにもないでしょ
あそっか、 dlg って CCalcApp::InitInstance() の中で作ったんだもん
ね。……ってことはどうすればいいのぉ!?
 dlg ってなに?
 CCalcDlg の変数
 CCalcDlg::OnInitDialog() は?
 CCalcDlg のメンバ関数
さらに、 CCalcDlg::OnBEqual() をもう一度見てみましょう

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

 m_iAns ……あーっそう言えば、 m_iAns と dlg.m_iAns って同じもんな
んだもんね!
思い出した? Ver 3.18 ( No.043 )で見たでしょ
見たってゆーか、あのときは逆に考えてたんだよね。 CCalcDlg の中のメ
ンバ変数を、外からどうすればいいのかって
この辺って、何気なく考えると普通だけど、よく考えるとこんがらがるで
しょ
うんなるー
考えるコツは、 CCalcDlg なんてない、ってとこかな
どゆこと?
 CCalcDlg はただの鋳型、つまり原型。実際に存在するのは dlg とかの
変数ってこと
つまり?
つまり CCalcDlg::OnBEqual() の中だったら、〈 CCalcDlg の中〉じゃな
くて〈 dlg の中〉って考えれば分かりやすいってこと
 CCalcDlg::OnInitDialog() も、ついさっき CCalcApp::InitInstance() 
で作られた dlg って変数の中って考えればいいってことね。だったらそんな
かの m_iAns も dlg.m_iAns も同じはずってことか
そういうふうに考えれば、あんまり混乱せずに済むかな。さてプログラム
の方は?
あ、ってことは……

    // TODO: 特別な初期化を行う時はこの場所に追加してください。
    m_iAns = 10000;

って感じに dlg は要らないってことね。でももうひとつの間違いって?
もう1行追加

    // TODO: 特別な初期化を行う時はこの場所に追加してください。
    m_iAns = 10000;
    UpdateData( FALSE );

あ、 UpdateData( FALSE ) って、メンバ変数のを、ダイアログに書き込
むのだよね
 CCalcDlg::OnInitDialog() が呼ばれる前にセットすれば自動的に書き込
まれるんだけど、呼ばれたあとは UpdateData( FALSE ) を呼ばないとダメ
なんかめんど。ま、ビルドして実行! うん、答に 10000 !

/*
    Preview Next Story!
*/
あとはレジストリの移せばいいから簡単ねー
それはどうかな?
げげ。なんか最近水希ちゃんいじわるだよ?
そう?
というわけで次回
< Version 3.22 参照を作ろう! >
につづく!!
意地悪イジワル〜
だって火美ちゃん教えがいあるから
〈調教しがい〉の間違いじゃない?
だからそーゆーの禁止〜

 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。