Version 3.7
ハンドルとメンバ変数
「ここまで〈ハンドル〉について見てきました」
『アイコンやウィンドウの出席番号だったよね』
「で、今回からは〈ハンドル〉と〈クラス〉の関係について見てみます」
『なんか関係あんの?』
「MFCではとーっても関係があります。と、その前に〈メンバ変数〉って
ものについて見てみましょう」
『メンバ変数って、メンバ関数の変数版ってこと?』
「そんな感じ。えっと、とりあえず Calc を実行してみて」
『あ、えっと、ビルドはしてるんだから、実行だけっと』
「そしたらダイアログの左上のアイコンをクリックして【Calc のバージョ
ン情報】を選んで」
『はーい。ダイアログ出たよ』
「このダイアログには左上のアイコンがないけど、Calc ダイアログには左
上にあるでしょ、アイコン」
『ホントだ! バージョン情報の方はないね。なんで?』
「普通はないんだよね。Calc ダイアログにアイコンがあるのは、わざわざ
セットしたから」
『CWnd::SetIcon() とかで?』
「そう! じゃ、ダイアログふたつとも閉じて」
『閉じたよ』
「そしたら CalcDlg.cpp の中から CWnd::SetIcon() を呼び出している部分
を探してみましょう!」
『え〜?? なんかめんどくさー』
「というわけで、検索方法について教えておこうか」
『なんだ、そーゆーのがあるんだ』
「まずメニューの【編集】−【検索】を選んで」
『なんだ、そのまんまね』
【検索ダイアログ】が表示される。
「で、【検索文字列】の中に SetIcon って入れて【次を検索】をクリック」
『あった! って、CCalcDlg::OnBEqual() のだからあたしが書いたのだ』
「そう言うときはもう一度」
『あれ、SetIcon じゃなくなってる』
「ドロップダウンリストの中にあると思うよ」
『あ、あった。でもめんどくさー』
「それはそうだね。ツールバーの〈双眼鏡に時計回り矢印〉だと次々と検索
していけるから」
『なんだ、そーゆーのがあるんだ』
「もしなかったら【カスタマイズ】で加えておくと便利だし、キーに割り
振っても便利かな。あと検索の【すべて設定】を選ぶと見つけた単語にブッ
クマークをセットするから。これも便利」
『なんか色々あるよねー』
「言っとくけど、こーゆーことは全部教えきれないから、暇なときに遊びが
てら色々試すんだよ」
『でもちゃっかり教えてるし』
「ま、VC講座だしね。で、見つかった?」
『えっと……』
BOOL CCalcDlg::OnInitDialog()
{
// 略。
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
// 略。
}
『CCalcDlg::OnInitDialog() にあったよ。あれ? このメンバ関数、どっか
で見たような……』
「CCalcApp::InitInstance() のことかな?」
『そうそう、それそれ。 〈いにっと〉継ながりだよねー』
「Init っていうのは initialize の略。〈初期化〉って意味だね」
『初期化?』
「そう。CCalcApp::InitInstance() がなんのイベントだったか憶えてる?」
『えっとね、確か〈アプリができるぞー!〉っていうイベントだよね。あ、
アプリができるから、そのための準備をしときなさいってゆー意味!?』
「そういうこと! 同じく、CCalcDlg::OnInitDialog() も〈ダイアログが
できるぞ〉ってイベントで、初期化をするためのプログラムをこのメンバ関
数に書き込むわけ」
『このときにアイコンをセットするんだー』
「そんなに簡単に信じちゃっていいの?」
『それって確かめろってこと?』
「そういうこと」
『じゃ、これをコメントアウトして……』
BOOL CCalcDlg::OnInitDialog()
{
// 略。
// SetIcon(m_hIcon, TRUE);
// SetIcon(m_hIcon, FALSE);
// 略。
}
『ビルドして実行。あ、アイコンがない!』
「というわけ。確認することは大事だからね」
『大丈夫、水希ちゃんの言うことなんか誰も信じないから』
「う”」
『ところでさ、この……』
SetIcon(m_hIcon, TRUE); // 大きいアイコンを設定
『 m_hIcon ってなに? この前使ったときは、アイコンのハンドル渡して
たし、変数の名前もそれっぽいけど、でも……』
「でも?」
『CCalcDlg::OnInitDialog() の中で、この変数作ってないよ?』
「よくぞ気付いた!!」
『?? はっ、いつものパターンでいくとこれがメンバ変数じゃない!?』
「そう、これがメンバ変数なのです!」
『そうなんだ! ってよく分かってないんだけど……』
「というわけで、まずは CCalcDlg.h を見てみて」
『【FileView】から【CCalcDlg.h】っと。CCalcDlg があるんだよね』
「そう。この CCalcDlg の中を見ていくと……」
class CCalcDlg : public CDialog
{
// 略。
HICON m_hIcon;
// 略。
};
『あ、あった! これって変数作ってるの? HICON 型の』
「そう。関数の中じゃなくて、クラスの中で持つ変数、それがメンバ変数」
『クラスの中で持つ?』
「そう。さっきの CCalcDlg::OnInitDialog() をこう書き換えてみて」
BOOL CCalcDlg::OnInitDialog()
{
// 略。
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
TRACE( "%X\n", m_hIcon ); // この行を追加してください。
// 略。
}
『あ、この TRACE() で、m_hIcon の……出席番号を表示してるんだよね』
「詳しくは Ver 3.4( No.29 )を見てくださいってことで、さらにこう書
き換えて」
void CCalcDlg::OnBEqual()
{
TRACE( "%X\n", m_hIcon ); // この行を追加してください。
}
『あ、これはいつもの【ボタンを押したとき】メンバ関数だね。あれ? こ
れ、さっきのと同じじゃない』
「つまり、同じことができるってことを確認してもらいたいってこと」
『?? ま、とりあえずビルドして実行。あ、アウトプットに……』
25AF
「ハンドルは実行するたびに値が違うからねってことに注意。で、まずダイ
アログが作られる直前に CCalcDlg::OnInitDialog() が呼び出されて」
『そのときこの、m_hIcon の出席番号が表示されたんだよね』
「そう。で、=ボタンを押してみて」
『ぽちっと。あ!』
25AF
『同じだ! ってことはつまり……』
「つまり?」
『つまり、CCalcDlg::OnInitDialog() のと CCalcDlg::OnBEqual() のとじゃ、
同じ m_hIcon を使ってるってこと?』
「その前に CCalcDlg::OnBEqual() の中で m_hIcon が使えるってことに驚
いて欲しいんだけど……」
『あ、そういえば』
「CCalcDlg::OnInitDialog() も CCalcDlg::OnBEqual() も、CCalcDlg のメ
ンバ関数だから、CCalcDlg のメンバ変数 CCalcDlg::m_hIcon が使えるって
わけ」
『全部 CCalcDlg:: が付いてるんだもんね』
「そう。その証拠に……」
// 下の関数を追加してください。
void ErrorFunc()
{
TRACE( "%X\n", m_hIcon );
}
void CCalcDlg::OnBEqual()
{
ErrorFunc();
}
『あ、久しぶりのメンバ関数じゃない関数だ。ってことは、この ErrorFunc()
からは m_hIcon って使えないんじゃない?』
「そう」
『そうって……』
「使えないことを確認するために、ビルドするんだから」
『ああ、なるほどねー。ビルド、あ、止まった』
error C2065: 'm_hIcon' : 定義されていない識別子です。
「つまり同じクラスのメンバ関数じゃないと m_hIcon は見えないわけ」
『同じクラスじゃないと?』
「そう。じゃ Calc.cpp を開いて CCalcApp::InitInstance() に次の行を追
加してみて」
BOOL CCalcApp::InitInstance()
{
TRACE( "%X\n", m_hIcon ); // この行を追加してください。
// 略。
}
『ビルド……あ、さっきと同じエラーだ』
「つまり CCalcApp から CCalcDlg のメンバ変数は使えないってことだね」
『CCalcDlg のメンバ変数だから、CCalcDlg のメンバ関数からしか使えない
ってことねー』
/*
Preview Next Story!
*/
『今日は地味よねー』
「ま、今回なんかは言語の勉強だからね」
『やっぱ実践的な方が楽しいよねー』
「というわけで計算機っぽくなるまであと数回!」
『やっとねー』
「というわけで次回」
< Version 3.8 MFCとハンドル >
『につづく!!』
「っていうか、年内に完成できるかなー」
『ま、この際思いっきりゆっくり行こうよ』
「それもいいかもね」
『さて、次のお便り』