VC++5.0入門16
メニューとダイアログボックス中編 97/12/28

こんにちは。もう、ほんとに年の瀬ですね。今ごろ、このページを読んでいる方は、よっぽどの方でしょう。^^)

前回、メニューに「文字」「文字の変更」という項目を付け、「文字の変更」という項目を選ぶと、メッセージボックスが現れるようにNekoプロジェクトを改良(改造)しました。もちろん、メッセージボックスはとりあえずの処置だったので、今回はこの辺を直してみましょう!
その前に、一言、注意があります。VCでは同じ事をするのに、何通りものやり方が用意されています。私が解説するのはその中のひとつです。そして、それがベストということではありません。いろいろなやり方を試してみてください。
さて、「文字の変更」を選んだら、どうなるようにしたいのか、考えてみましょう。私は、文字の変更ダイアログボックスが開かれ、そこから「猫」にかわる新しい文字(列)を入力できるようにしたいのです。
では、前回までに作ったプロジェクトを開いてください。そして、リソースビューのタブをクリックし、Nekoリソースの前の「+」をクリックして、フォルダを展開してください。次に、Dialogのところを右クリックすると新たにメニューがでますから、Dialogの挿入を選んでください。するとIDD_DIALOG1というIDのついたダイアログボックスがプロジェクトに挿入されます。このIDは変更できるので、ちょっと、変更してみましょうか。表示された新しいダイアログボックスの中で右ボタンをクリックし、プロパティを選択してください。ここでプロパティダイアログが開くので、IDのところをIDD_LETTERとしてください。(前回のID_CHANGE_LETTERとは別のIDです。ちなみに、IDDの最後のDはダイアログという意味です。もちろん、どう定義し直しても同じですが、、、。)これで、プロパティダイアログを閉じてください。
このダイアログ(そろそろボックスは省略します^^)は、リソース(要するにこういうものをリソースと言います。これはC++とは関係無い、プロジェクトのための「資源」です)であるのですが、まだ、C++のコードに編入されたわけではありません。それをこれからやっていきましょう。(ダイアログを使える形に変更するのは後でやります。)
まず、このダイアログに対応したクラスを作ります。では、新規のダイアログが選択された状態(つまり、リソースビューのIDD_LETTERのまわりに青い枠ができた状態)で、メニューの「表示」のClassWizardを選んでください。(あるいは右ボタンクリックでも同様のことができます。)すると「クラスの追加」ダイアログが開くので、OKを選んでください。ここで、クラス名を聞かれるので、CLetterDlgとでも名づけましょう。このとき、ダイアログIDがちゃんと先に定義したIDD_LETTERになっていることを確認しつつ、OKとしてください。最後にClassWizardダイアログのOKを選べば、新しいクラスができています。確認のため、ビューをファイルビューに切り替えて見てください。LetterDlg.hとLetterDlg.cppという新しいファイルができているはずです。試しに、LetterDlg.hを開いてみてください。CLetterDlgがCDialogというMFCクラスから派生されていることがわかると思います。このコードを見ると、おそらく意味不明のことがたくさん書いてあるので、ちょっと嫌な気分になるかもしれませんが、良く見るとほとんどがコメントで、実質的内容はスカスカですね。(つまり、大部分はMFCのCDialogの中にあるのです。)このHPの読者なら、もう、こんなものでおたおたしないと思います。(ひとつだけ、virtual void DoDataExchange(CDataExchange* pDX); は気になるかもしれません。この説明はずっと後にさせてください。)
いよいよダイアログをメッセージハンドラに対応づけます。つまり、ID_CHANGE_LETTERというメッセージを受け取ったときに、今定義したダイアログを開くようにしたいのです。まず、ハンドラはどこにいるのでしょう?覚えていましたか?これはCNekoDocクラスのOnChangeLetterという関数のことです。ここにいくのに、ファイルビューを使ってもよいですが、ここでは練習のためClassWizardを使います。
メニューの「表示」(や右クリック)で、「ClassWizard」を選択し、ClassWizardダイアログを開いてください。そして、クラス名でCNekoDocを選び、オブジェクトIDでID_CHANGE_LETTERを選び、メッセージにCOMMANDを選んでから、「コードの編集」ボタンを押してください。これで、OnChangeLetterという関数の定義部分が表示されると思います。(繰り返しますが、ClassWizardを使わずに、別の方法でこの場所を見つけ出しても結果は同じです。)
ここで、
void CNekoDoc::OnChangeLetter() 
{
    MessageBox(NULL,"文字の変更は次回にしましょう","準備中",MB_OK);
}
となっているはずですが、これを
void CNekoDoc::OnChangeLetter() 
{
    CLetterDlg dlg;
    dlg.DoModal();
}
と直すのです。
まず、はじめのCLetter dlg;は、私たちが定義したダイアログのクラスのオブジェクトを生成しているのです。このクラスに対応づけたダイアログを使いたいのでこのクラスのオブジェクトを生成したのです。(確認しますが、画面に表示されるダイアログボックスとC++で書かれたダイアログクラスは一応別物と考えてください。もちろん、このふたつはClassWizardで対応づけられているのですが。)このオブジェクトが生成されても、ダイアログは表示されません。ダイアログを表示する方法は2通りあるのですが、ここでは簡単な方法をとります。これが次のdlg.DoModal();の意味です。つまり、このようにダイアログクラスのDoModal(という名前の)関数を呼び出せば、ダイアログが「モーダル」という状態で表示されるのです。この「モーダル」の意味は、「このダイアログが実行されている間は、他の操作ができない」という意味です。そういうダイアログは多いですよね。)
ところで、このCLetterというクラスは、CNekoDocなどではなくCLetterdlg.hで宣言されています。このクラスをCNekoDoc.cppで使うため、CNekoDoc.cppのファイルの上の方(#include "NekoDoc.h"の下あたりが適当でしょう)に、
#include "LetterDlg.h"
を書き込んでください。これは、LetterDlg.hというファイルをこのファイル(ここではCNekoDoc.cpp)に含ませよという命令です。こうすることで、LetterDlg.hに宣言されているCLetterDlgクラスがCNekoDocでも使えるのです。(そんなこと知っとるわい、という方、まあ、いいじゃないですか。)
それでは、プログラムを実行してみてください。こうしておいて、メニューで「文字」の「文字の変更」を選択すると、先ほど挿入した新しい(しかし何の役にもたたない)ダイアログが開くはずです。このダイアログには「OK」と「キャンセル」のふたつのボタンがあるだけで、何の役にもたたないのですが、OKやキャンセルのボタンを押せば、何もしないで、ちゃんと消えてくれます。
次に、このダイアログを改造し、ちゃんと仕事をするものにしましょう。というところですが、今回はここまでにさせてください。

NekoDoc.cppを載せます。例によってタブはめちゃめちゃでしょう。その点は注意してください!
NekoDoc.cpp

いつも書いていますが、いつもゆっくりですみません。これから冬休みというこで、次回は1月11日にします。
VC入門の方はスケジュールがズタズタになっていて、リアルタイムで読んでいる方には申し訳ないです。
みなさま、良いお年を。
目次のページ
前のページ
後のページ