VC++5.0入門18
プロジェクトNeko 補足 97/1/18

こんにちは。みなさんいかがお過ごしでしょう。東京は大雪だったようですね。私の生活圏では、ほとんど雪は降りませんでしたが、、、。
プロジェクトNekoはお世辞にも完成品ではありません(完成するとどうなるんでしょう?)が、この辺で終わりにしようと思います。ただ、それにしても、いくつか言い残したことがあります。今回はそれを片づけましょう。

まず、前回の後半のシリアライズの話を思い出してください。マウスのドラッグで何という文字を書くかは、最初に「猫」としますが、後はユーザに(文字変更ダイアログで)入力させ、保存の際には文字の位置だけでなく、どの文字か(つまり「猫」とか「犬」とか)も記録させることにしたのです。
そうすると、CNekoStrokeのコンストラクタでstr="猫";とする必要はなくなったのです。これは、書くべき文字が指定されなかった場合に使われる文字(正確には日本語1文字の文字列)を指定しているのですが、もう、指定されないことはなくなったのです。
ここで、私はちょっと悩みます。この1行はもう不要なので、消すべきかどうかです。将来、何かの拡張で、また、こういう文字(つまり、デフォルトの文字ですね)が必要になるかもしれないからです。しかし、使われていないコードを残すと、後で見た時、たぶん、混乱するでしょう。このコンストラクタの「猫」はドコデツカワレルんだっけ、と。
後者の方が有りそうなので、この部分は消去し、引数無しのコンストラクタ(デフォルトのコンストラクタと呼ばれることもあります。ただし、プログラマがコンストラクタを定義しなかった場合にコンパイラが勝手にやってくれる処理のことではありません。)を、次のようにしましょう。
    CNekoStroke(){}  //つまり「何もしないコンストラクタ」です。
これはNekoDoc.hのCNekoStrokeの宣言の中の1行「CNekoStroke(){str="猫";}」を書き換えたものです。
ちょっと、待て。何もしないコンストラクタが必要なのか、と思うでしょうか?必要です。シリアライズには必要だとVC入門13で書きました。(ここはそういうもんだと納得してください。また、コンテナ(配列のようなオブジェクトの入れ物)にオブジェクトを格納するときにも普通は必要です。)
そういうわけなので、ここは、そうします。(ちょっと強引?)

さて、このプログラムを実行してください。動作は変わりませんね。めでたし、めでたし、、、なんですが、ちょっと慣れてくると気になることはありませんか?
文字変更のダイアログを開いてください。なんか、ちょっと嫌じゃないですか?私は嫌です。
何が嫌かと言うと、(普通にやってきた人のプログラムでは)ダイアログの入力場所にフォーカスが当たっていないということです。つまり、ダイアログを開いてキーボードを叩くだけでは、入力できないのです。キーボードを叩く前に、入力位置(つまりエディットボックス内)で一度クリックをし、カーソルを出さなければならないのです。
これはどういうことか、というと、つまり、フォーカスがエディットボックス以外の別の所にあるからです。
実は、ダイアログ内にはいくつものコントロールがありますが、これらには、タブオーダー(タブの順番)という番号が付いています。これは、ダイアログが開かれてから、タブキーを押すとフォーカスが移っていく順番を表しています。(フォーカスの意味がわからない人はとりあえず以下を実行してみてください。)
ウインドウズでマウスに慣れて、あまりキーボード操作をしなくなりましたが、実はタブキーを押してフォーカスを動かしていくという、通っぽい、ちょっとかっこいい使い方もあります。実際に、もう一度Nekoを起動して、文字変更ダイアログを開いて、タブキーを何度か(何度も)押して、フォーカスがどう移っていくか見てください。
何度かタブキーを押すと、エディットボックスにもフォーカスが行き、そのときだけ、カーソルが点滅するでしょう。私が嫌だと思ったのは、このタブオーダーが嫌っだのです。つまり、エディットボックスのタブオーダーを1番にしておけば、ここに(1番に)フォーカスが来るのですが、そうなっていないのです。
タブオーダーを変更するのは、実は簡単です。まず、リソースビューを開いて、文字変更ダイアログの編集画面にしてください。(つまり、DeveloperStudioのResouceViewのタブをクリックして$DialogのIDD_LETTERをダブルクリックしてください。)
メニューを見ると、レイアウトという項目が有ります。ここでタブオーダーを選んでください。すると、編集中のダイアログに数字が3つ現れるでしょう。1、2、3です。これが、つまりコントロールのタブの順なのです。ここで、コントロール(つまり、ふたつのボタンとエディットコントロールをいろいろクリックして見てください。いろいろやってみると、タブオーダーが変わることがわかると思います。(基本的には、クリックした順に数字が付きます。)どうにか、エディットボックスを1、OKボタンを2、キャンセルボタンを3にしてください。そうなったら、後は、別の場所でクリックでもするとその番号が確定します。これで、エディットボックスに最初のフォーカスが来るようになりました。これで、ダイアログを開いたときに、エディットボックスにフォーカスが来て、すぐ入力できるようになったのです。。実際に、試して見てください。

ところで、キーボードでの操作というと、もうひとつあります。例えば、普通のソフトでメニューの所を見ると「編集」という項目があると思いますが、良く見ると「編集(E)」などとアルファベットがついていますね。これは、Altキーを押しながらEキーを押すと、メニューのその項目が開けるということです。私個人はあまり使わないのですが、こういう使い方もできるようにしておくのが、標準のようです。というわけで、そうします。、、、実は簡単です。リソースビューでMenuのIDR_MAINFRAMEをダブルクリックしてメニューの編集画面を開き、「文字」の項目をダブルクリック(あるいは右クリックしてプロパティを選択)してください。開いたプロパティウインドウでキャプションを「文字」から「文字(&L)」にしてください。(新しい入力部分は半角文字であることに注意してね。Lという文字を使ったのは、文字の英語Letterからですが、もちろん、別の文字でも他の項目とバッティングしていなければかまいません。)これで終わりです。できたら、実行して試してみてください。Altキー+Lキーで文字の項目がドロップダウンすると思います。^^)

うまくいきましたか?それから、文字変更ダイアログを開いたときに、現在の文字がエディットボックスに表示されると、かっこいいですね。現在の文字は、CNekoDocのm_CurLettに保持されているので、これを文字変更ダイアログのエディットボックスに表示すれば良いわけです。
そのためには、CNekoDocのOnChangeLetterを次のように書き換えてください。(というか1行加えるだけですが、、、。)
void CNekoDoc::OnChangeLetter() 
{
    CLetterDlg dlg;
    dlg.m_letter=m_CurLett;  //加えた1行
    if(dlg.DoModal()==IDOK){
        m_CurLett=dlg.m_letter;
    }        
}
感の良い人なら、書き加えた1行が何を意味するか、分かるでしょう。これは、ダイアログ(dlg)のエディットボックスを表す文字列(m_letter)にm_CurLettを代入しているのです。前に書きましたが、dlg.DoModalでダイアログが表示されるので、その前にエディットボックスに書き込んでおけば、ダイアログが表示された時には、それが表示されるわけです。

これで、ずいぶん、格好は付きました。後、何でしょう。、、、よく、データをちょっと書き換えた後に、保存せずにアプリケーションを終了しようとしたりすると「保存しなくて良いか?」と聞いてくることがありますね。ああするには、どうすれば良いのでしょう。
実はこれも簡単です。データを書き換えた時にCDocumentのSetModifiedFlagという関数を呼び出せば良いのです。すると「データは書き換えられた」と記録され、必要な時に「保存しなくて良いか?」と聞いてくれるようになるのです。ここのところは自動です。(つまり、MFCに組み込まれているのです。)そこで、CNekoViewのOnLButtonDowを次のように書き換えてください。
void CNekoView::OnLButtonDown(UINT nFlags, CPoint point) 
{
    SetCapture();  //マウスをキャプチャ(補足)する
    m_pCurStroke=new CNekoStroke;
    CNekoDoc *pDoc=GetDocument();
    m_pCurStroke->str=pDoc->m_CurLett;
    pDoc->m_strokes.AddTail(m_pCurStroke);
    pDoc->SetModifiedFlag();  //書き加えた1行 
}
できたら実行して、文字を書いた後に保存せずにNekoプログラムを閉じようとすると(あるいは新規作成をしようとすると)、保存確認のダイアログが開くようになったことを見ておいてください。
1行書き加えるだけで、こんな機能が付いてしまうのは、やはり便利です。そう思いませんか?

これでおしまいです。ただ、あとひとつ。以下のことは別のやり方をすればもっとずっと簡単にできるので、今疲れた人は、とばしてください。
例えばメモ帳で何か書いてそれを保存する時には、勝手に拡張子txtがファイル名の後につきましたよね。大抵のソフトでも同じようになっています。
それで、まあ、私たちのNekoで作ったファイル達にも拡張子がほしいですね。しかも、保存する時には、自動で付くようにしたい、、、。実は、これは、今からやるのは、簡単ではありません。しかし、簡単に言うと、次のような手順になります。1.リソースビューを開く 2.String TableのString Tableをダブルクリックする。こうして開かれるのは、プログラムに使う文字情報を編集する画面です。この画面は今はちょっと馴染めない感じがするでしょう。が、とりあえず、IDのIDR_MAINFRAMEをダブルクリックしてください。すると、プロパティダイアログが開くはずですが、キャプションというエディットボックスに
Neko¥n¥nNeko¥nNekoファイル(*.nek)¥n.nek¥nNeko.Document¥nNeko Document
と入力してください。この文字列は、このNekoアプリケーションが使う文字列を表しています。特に、真ん中辺にあるのが、保存時の表示と拡張子です。上のようにするとNekoで作ったファイルにはnekという拡張子が付くようになるのです。ただ、この詳しい説明は今は許してください。実際、拡張子などは、最初にプロジェクトを作るときに設定する場所があって、そこで設定すれば簡単なのです。
繰り返しますが、AppWizardの起動後すぐに拡張子を設定するところがあって、そこで設定するのは、こんなわけのわからない文字の並びではありません。はじめからそこを使えば簡単なのです。では、なぜ、私たちは、そのとき設定しなかったのか、と言うと、それは、あまり重要でなさそうな話で初心者を混乱させたくなかったからです。この設定の話はチュートリアルのはじめの方に書いてあります。安心してください。

これで、プロジェクトNekoはとりあえず終了とします。みなさんご苦労様でした。
これでチュートリアルを読むための基礎はできました。あとは、チュートリアルを読むのが一番だと思います。
それで、今後のことなんですが、少し、WWW上チュートリアル読書会(会?)をやろうかと思います。つまり、VCのチュートリアルを少しずつ読んで、気が付いたことなどをここに掲載しますので、参考にしてください。もちろん、チュートリアルの内容をそのまま書くことはありません。
これは明らかに手抜きで、以後しばらく(ずっと?)、私のタイプ量が激減すると思いますが、許してください。
ということで、次回はチュートリアルの1〜3章へのコメントです。
お願い1
ここまで、ちゃんと読んでくれれば、問題はなかったと思うのですが、一応、ここまででできたソースファイルを掲載したいと思っていました。でも、困ってしまいました。もう、ご存知のようにファイルの数が多くて、アップロードする気力がでないのです。したとしても、みなさんの方がダウンロードする気にならないでしょう。どうしましょう。いわゆる圧縮とかアーカイブとかいうやつを使うのが良いのでしょうか。(私は詳しくありません。)希望する読者が誰でも合法的に無料で閲覧でき、私の手間もほとんど無いGOODな方法(サイト?)があれば教えてください。(私が希望者1人1人にメールで送るとかいうのは無しです。^^;)
お願い2
VC入門のふたつ目の区切り(ひとつ目は基礎知識、ふたつ目がNekoでした)が終わりました。C++入門には今だにコメントをくれる方が多い(返事が遅れたりしてすみませんm(__)m)のですが、VC入門の方へはあまりコメントが来ません。訪問者数は相変わらず伸びているので、読者はいると思うのですが、、、。もしよろしければ、どうだったか感想をください。今後の参考にさせていただきます。
目次のページ
前のページ
後のページ