VC5.0入門9
新しいプロジェクト 97/10/16

こんにちは。リアルタイムで読んでいるみなさん、ご無沙汰しました。ご無沙汰している間にもたくさんの励ましのメールをいただき感謝しています。
そんなみなさんの期待を裏切ってしまっているようで、大変申し訳ないのですが、ペースは相変わらずゆっくりなのをお許しください。それで、少し雑談、、、。
実はご無沙汰した理由の出張はJICAのお招きで中国に行ってC++を教えてきたのでした。教えるといっても私自身勉強になることもあり、また、中国の人との相性も良く、とても楽しい出張でした。(もちろん、ホストの方の配慮が良かったことは言うまでもありません。)いずれ暇ができたらそのときの写真でもHPに載せようかと思っています。

さて、前回にAppWizardが生成するスケルトン(骨組み、枠組み)コードを見ました。細かいことはともかく、流れがわかったところで、少し簡単なプログラムNekoでも作って見ましょう。と言っても、チュートリアルにあるScribbleというプログラムの簡単バージョンです。前にも書きましたがチュートリアルを読んでわかっちゃう人はしばらく読まなくても良い内容になります。

それでこれから作るプログラムは簡単に言うと、マウスのボタンをクリックすると「猫」という文字を画面に書くプログラムです。なんだ前にやったやつかと思った人はお目が高い、その通りです。その通りですが、AppWizardなどを使って、VCの機能を学びながらやってみることにします。結果は前のものよりずっと「良いもの」になるでしょう、、、。って、言ってもそもそも役に立たないプログラムですが。何の役に立つかというと、私の説明を読んだ後にチュートリアルを読むと、なんとか読める!というものにしたいのです。(うまくいかなければゴメンナサイ。)
ただ、チュートリアルのプログラムがそもそもつまらないという批判もあります。実は私もそんな気っはするのですが、何かもっと面白いものを作るためにも基本は必要で、その基本はScribbleにかなり含まれているのです。そのScribbleを理解するためのNekoです。

はじめる前に言い訳をまたひとつ。私は自分が理解したと思うことを書きますが、常に効率の良い方法を選択しているとは限りません。また、なるべく、そんなことは無いようにしたいのですが、誤解していることもあるかもしれません。(致命的な誤解は無いと思いますが、、、。^^;)不審なことがありましたら、遠慮無く御質問ください。(とは言えけんか腰にはならないでね。)よろしくお願いします。

さて、まず、VCを立ち上げ、ファイル−>新規作成で、MFC AppWizard (exe)を選んで、プロジェクト名をNekoにし、位置は適当に決め、OKとしてください。ステップ1ではSDI(ウインドウがアプリケーションにひとつというスタイル)を選んで「次へ」、その後はずっと「次へ」をおし続け、最後に「終了」そして、ファイルを作るよ、という問いかけにOKを押してください。、、、あっというまにAppWizardは枠組みを作ってくれます。
そうしたら、とりあえず、ビルド−>実行、としてみましょう。必要はありませんが、チェックのためです。「ビルドしますか?」の問いにはいと答えるとビルド(要するにコンパイルとリンク)がはじまり、ビルド終了後に、空のプログラムNekoが実行されます。もちろん、ここでは何もできないウインドウが開くだけです、、、。
きょうはまずマウスの左ボタンを押すと「猫」という字が出るようにしてみましょう。まず、クラスビューで見えるCNekoViewというクラスをちょっと書き換えます。(エクスプローラ風の小窓の中にCNekoViewがありますね。)このクラスは、アプリケーションのビューウインドウ(クライアントウインドウ)を表すクラスでした。ビューウインドウ上でマウスをクリックするとどうにかなる、というプログラムを作りたいのですから、このクラスを書き換えるのです。やることは「マウスの左ボタンが押されたというウインドウズからのメッセージを受け取ったら、その場所に猫と書く関数」を宣言・定義するということです。このようにウインドウズからのメッセージを受けて何かする関数をメッセージハンドラというのでした。
さて、CNekoViewの上で、マウスの右ボタンを押して見てください。すると、ポップアップメニューの中に「メッセージハンドラの追加」という項目があります。どうもこれっぽいですね。というわけでここを選択するとダイアログボックスが開きます。ダイアログボックスの中にはいくつか小窓がありますが、左の小窓にはWM_なんたら、という文字が並んでいます。実は、これがウインドウズから送信されるメッセージなのです。この中でそれっぽいのを探すと、あります、あります、WM_LBUTTONDOWNですね。これがマウスの左ボタンを押す(押し下げる)とウインドウズから送信されるメッセージです。これを選択して、右の方にある「ハンドラの追加」というボタンを押してみましょう。これでメッセージハンドラ(略して単にハンドラということも多いです)に必要なコードの枠組みが、AppWizardが生成したコードの中に書き込まれるのです。ただ、これだけでできるのは単に枠組みだけなので、猫と書くように実際の定義も書き込む必要があります。ここで、このダイアログボックスの「既存の編集」を選びます。「既存の編集」とはたぶん「既存のハンドラの編集」という意味だと思います。どうして「既存」かと言うと、もう「ハンドラの追加」でその(空の)ハンドラを追加しているからです。(ということは「ハンドラの追加」「既存の編集」と2度手間をかけずに「追加と編集」で一発でやれるということですね。まあ、今は、2度手間の方を使いました。)
まあ、とにかく、「既存の編集」を選ぶといきなり画面が変わります。はじめたばかりの頃は本当にまごつきました。これはどこのコードなんだぁ、と。私は慌てまくったので、そういう人こそまともだと思うのですが、冷静な人ならわかったかもしれません。これはNekoView.cppの一部が表示されているのです。先ほどのダイアログボックスがしたことは、ハンドラの枠組みをNekoView.cpp(とNekoView.h 後述)に書き込み、その場所を表示しただけなのです。
この仕組みをマイクロソフトはClassWizardと呼んでいる様です。初心者の頃の私自身もそうでしたし、他の初心者の感想でも同じことを聞いたのですが、ClassWizardを使ってコードを書くと、何をやっているのかわからない気分になるかもしれません。私は、何か自分の知らない特殊なことをVC(のClassWizard)はやっているのではないか、自分のような素人はClassWizard様(さま)のお邪魔をしないように気を付けなければいけないのではないか、例えば、変なところに変なコードを手で書き込んだりしたらVC様のお怒りをかってそのプログラムは暴走をはじめるのではないだろうか、、、、というようなことを心配しました。これらの心配は、ほとんど必要の無いものでした。
ClassWizardがやっていることは、単に、人間が書く手間を省くだけのことなのです。もし、証拠が見たい人はこの段階でNekoView.cppをプリントアウトして、前にプリントアウトした(かもしれないVC入門7の)skeltonView.cppと見比べて見てください。ハンドラ部分が書き加えられているだけですね。(ところで骨組みskeltonはスペルミスでskeletonが正しいんですね。勝ち誇る妻に指摘されるまで気が付きませんでした。すみません。後でこっそり直しておきます。えれー恥ずかしいっす。)プリントアウトはしなくてもこのファイルとNekoView.hをちょっとながめまわしておくと良いと思います。NekoView.hを見るには、例えば、ファイルビューでNekoView.hをダブルクリックすると開けます。(他にもたくさんの方法があります。ぼちぼち試してみてください。)
NekoView.hはごちゃごちゃしていますが、
    //{{AFX_MSG(CNekoView)
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    //}}AFX_MSG
なんてところがあって、必要なOnLButton関数が定義されているではないですか。(この関数を忘れた人はVC5入門6を見てください。)ちょっと(というかだいぶ)気になるのは、まわりの//{{AFX_MSG(CNekoView)や//}}AFX_MSGやafx_msgです。(それに色も灰色だったりしますね。色が灰色なのはエディタがそういう設定になっているからで、何も心配はいりません。)これらについては後でまとめて話しますので、ちょっと待ってください。
NekoView.cppにもどると、メッセージマップの中にちゃんとON_WM_LBUTTONDOWN()があります。そしてこのファイルの一番最後にOnLButton関数の定義を書く場所ができているのです。
メッセージハンドラを書くということを思い出してください。それは処理するメッセージを決め(ここではマウスの左ボタン押し下げによりウインドウズから送られるメッセージ)、それに対応した名前の決まった関数(ここではOnLButton関数)を宣言し定義し、同時に、メッセージを受け取るようにメッセージマップに登録するのでした。(VC5入門6を見てね。)ひとつのハンドラを(機能するように)作るのにずいぶんと手間がかかりました。この手間を簡単にやってくれるのがClassWizardなんです。(他の仕事もありますが。)とても便利な機能ですね。ただ、便利だから使うのであって、絶対使わなければいけないというものでもないのです。すべてを手で書いても良いのです。ただ、面倒ですから、やっぱりClassWizardを使いましょう。
さて、//{{AFX_MSG(CNekoView)や//}}AFX_MSGやafx_msgなんかを説明しましょう。実は、これらはClassWizardやAppWizrad(の機能)が、俺達が書いたんだよ、とつけた印なのです。これらの印はC++言語とは何の関係もありません。C++にない記号が出てきて、こりゃまた新しい言語かいと思ったりもしましたが、これらの記号はClassWizardなどが使うだけなので、人間は読まないで良いのです。(すくなくとも初心者のうちは。)コンパイラも読まないはずです。まあ、気にしないようにしましょう。
いろいろごちゃごちゃ書きましたが、要するに、メッセージハンドラの枠組みができたのです。では、NekoView.cppの
void CNekoView::OnLButtonDown(UINT nFlags, CPoint point) 
{
    // TODO: この位置にメッセージ ハンドラ用のコードを...

    CView::OnLButtonDown(nFlags, point);
}
の//TODO:の所を削除して次のように書き換えてください。
void CNekoView::OnLButtonDown(UINT nFlags, CPoint point) 
{
    CClientDC dc(this);
    dc.TextOut(point.x, point.y, "猫");
}
そして、もう一度実行して、マウス左ボタンをクリックして遊んでみてください。なんのことはない、VC5.0入門6のプログラムですね。入門6ではpと書いていた引数がここでは(ClassWizardによって)pointになっていることに注意してください。
前に書いたプログラムと同じようなものですが、AppWizardやClassWizardに慣れていれば、前よりずっと簡単にここまで来れるということを確認しておきましょう。そして、さらに先にも簡単に行けるのです。それは次回以降にしましょう。ゆっくりですね。
目次のページ
前のページ
後のページ