VC++5.0入門8
続・はじめてのAppWizard 97/9/1

こんにちは。前回の説明はちょっとわかりにくかったというコメントを複数いただきました。今回は特にあまり進めませんが、復習からいきましょう。
前回はAppWizardを使うと、ウインドウズアプリケーションに必要なコードが自動的に生成されるというところを見ました。(しばらくは、SDIと呼ばれる形式のアプリケーション、つまりウインドウが見た目ひとつしかないアプリケーションを考えます。)ここで、私が特に言いたいことは、気の持ちようです。
AppWizardが生成してくれるコードは、初心者には、ヘビーです。しかし、極論すると、この部分は本来、初心者は理解できなくても良いところです。理解できなくてもある程度のことはすぐできるようになるのです。ただ、プログラミングをやろうという人たちなら、わからなくて良いと言われて、そのまま引き下がれないものもあるでしょう。もちろん、将来的には深い理解が必要にもなってきますから、今の内に少しでも理解しておいた方が良いとも言えます。
そういう理由で、この講座(のこの部分)では、本質的なところだけをつかまえておこうというのです。全てを理解しようとはしないでください。そして、非常に大事なことですが、前回と今回の内容がわからなくても、とりあえず、先に進んでください。まだ、あまりコードを書いていないのでわかりにくいという側面もあります。次回以降で少し経験を積んでから、またこの辺の解説を読み直した方が良い場合もあると思うのです。そういう人は今回の内容はざっと読んでおけば十分です。
さて、前回は、AppWizardは本質的に4つのクラスを生成してくれているという話をしました。これらが何をするクラスなのか、考えてみましょう。
そこで、VC入門4を思い出してください。ここで、ウインドウズアプリケーションには、少なくともふたつのクラスが必要だという話をしました。それは、アプリケーションそのものとウインドウ(ズは付かないのでしたね。^^)のクラスです。この基本的な仕組みは、AppWizardでも同じです。ただ、少し拡張してあるのです。前回のskeltonプログラムの例を使って、答えを先に書いてしまいましょう。

クラス名        クラスの意味
CSkeltonApp     アプリケーションを表すクラス
CMainFrame      フレームウインドウを表すクラス
CSkeltonView    ビュー(ウインドウ)を表すクラス
CSkeltonDoc     データを表すクラス
まず、CSkeltonAppは上の表にあるように、アプリケーションそのものを表すクラスです。VC入門3のCMyAppに相当するクラスです。実際、ファイルビュー(実はクラスビューも使えますが)で、skelton.hというファイルを見てみると、
class CSkeltonApp : public CWinApp
{
public:
CSkeltonApp();
...
という部分が見えます。CSkeltonAppは、CWinAppの派生クラスなのです。(その他にたくさんあるコードはこれからゆっくり見ていきますから、最初は気にしないでください。本質をつかむのが第一だと思います。)VC入門4によると、このクラスのインスタンス(オブジェクト)を生成すれば、アプリケーションが開始されるのでした。実際、skelton.cppには、
// 唯一の CSkeltonApp オブジェクト
CSkeltonApp theApp;
なんていう個所があります。もう見つけていた人は優秀です。まだだった人は、今見つけておいてください。これがあるから、このプログラムは実行されるのです。
さて、次にウインドウです。VC入門4で、ウインドウズアプリケーションにはウインドウが必要で、それはアプリケーションのクラスに登録される。その登録の場所は、InitInstanceというメンバ関数の中だと話ました。
実はAppWizardが(SDI用に)生成するコードには、ウインドウがふたつ登場します。ひとつは、フレームウインドウというもので、もうひとつはビューウインドウというものです。VC入門3、4ではウインドウがひとつしか登場しませんでしたが、これはどうしたことでしょう。
VC入門3でのウインドウも、実は、フレームウインドウという名前でしたが、実際には、普通のウインドウとして使いました。今回のコードで使われるフレームウインドウは、ウインドウのフレーム部分だけを表しています。(つまり、タイトルバーや枠などのフレーム部分です。)アプリケーションの(普通は白い)ウインドウの中心部分には、そのアプリケーションの内容が表示されるわけですが、この部分がビュー(ウインドウ)なのです。SDIとMDIでちょっと違いますが、要するに、データなどアプリケーションの内容が表示されるところで、SDIの場合には、一番大きな(普通は白い)四角の部分(クライアント部分)です。
フレームの部分だけでもウインドウなの?白い部分だけでもウインドウなの?と思ってしまいますが、イメージとしては、(枠のついていない)ビューウインドウが(ちゃんとしたウインドウであるところの)フレームウインドウ(のクライアント部分)に乗っかっているという感じです。(ビューウインドウ自身には、フレームが無いのです。)このように、ウインドウをふたつ使うのは、まあ、こうするとあとあと便利だと、マイクロソフトの人たちが判断したから、、、でしょう。
そういうわけで、ウインドウがふたつあるのですが、それが、CMainFrameとCSkeltonViewなのです。MainFrame.hには、
class CMainFrame : public CFrameWnd
{
...
とあり、skeltonView.hには
class CSkeltonView : public CView
{
....
とあります。
CMainFrameはVC入門3のCMyWindowに相当することがわかると思います。(忘れた人はちょっと入門3を見てください。)CSkeltonViewの方は、はじめて出てきたものですね。後で少しづつ見ていきますが、ちょっと元気な人は、VCにおまけで付いてきている、MFCの表を見てください。(ちょっと大き目の紙がありますよね。)この表が、MFCの関係図なのですが、右の真ん中辺にWndというクラスが書いてあると思います。これがウインドウクラスの基本なのですが、CFrameWndはCWndのすぐ下に書いてありますね。つまり、CFrameWndはウインドウの基本クラスCWndの派生クラスなのです。また、CViewも探して見てください。わかりましたか?これもCWndの派生クラスなのですね。
ところでこの表を見て、ぎゃーっと思いましたか?私は、昔、これを見たときに、、、じゃなくて今でも、ぎゃーっと思ってます。こんなに他人様(ひとさま)が書いたクラスを勉強しなければならないのか、、、と。でも、プロになるのでなければ全部勉強する必要は無いと思います。たぶん。(プロの人も、かな?)
めげないように気を持ち直して、話をもどしましょう。えーと、4つの基本クラスの内、3つ終わりました。最後のCSkeltonDocは、アプリケーション独自のデータを保持したり、処理したりするクラスです。つまり、ある意味、CSkeltonDocが背後にあって、その中身(の一部)をビューで表示する、という仕組みになっているのです。ただ、これまでの私のサンプルにはデータが無かったので、必要なかったのです。
AppWizardが生成したスケルトンプログラムにもデータが無いので、必要ないようなものですが、いずれ必要になるので、とりあえずAppWizardが書いてくれているのです。今は、とりあえず、気にしないことにしましょう。(本当は、重要なクラスなんですが、それは、必要になったときに説明しましょう。)
ここまで説明したことは、VCのチュートリアルにそれらしい絵付きで説明されているので、それを見てください。HPに絵を描かなくてすみません。チュートリアルは何にしても、いずれは、読まなければいけないものです。今のうちに、少しでも見ておいてください。

これで、AppWizardの作るコードを理解するための最初のとっかかりの説明はほぼ終わりです。まだまだわかった気にはならないと思いますが、これから少しづつコードを書いていくとわかったような気分になっていくと思います。決して、今の段階であきらめないでください。 ちょっと、補足ですが、VC入門3のコードには、アプリケーションクラスのInitInstanceの定義が次の様に書いてありました。
BOOL CMyApp::InitInstance()
{
    m_pMainWnd=new CMyWindow();
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();
    return TRUE;
}
説明はVC入門4を見てください。AppWizardのコードでこれに対応しているのは、skelton.cppの以下のコードです。(コメントは一部削除します。)
// CSkeltonApp クラスの初期化

BOOL CSkeltonApp::InitInstance()
{
#ifdef _AFXDLL
    Enable3dControls(); 
#else
    Enable3dControlsStatic(); 
#endif
    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    LoadStdProfileSettings();  
    // アプリケーション用のドキュメント テンプレートを登録します。
    //  ドキュメント テンプレート
    //  はドキュメント、フレーム ウィンドウとビューを結合するために機能します。

    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CSkeltonDoc),
        RUNTIME_CLASS(CMainFrame),       // メイン SDI フレーム ウィンドウ
        RUNTIME_CLASS(CSkeltonView));
    AddDocTemplate(pDocTemplate);

    // DDE、file open など標準のシェル コマンドのコマンドラインを解析します。
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    // コマンドラインでディスパッチ コマンドを指定します。
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;
    
    // メイン ウィンドウが初期化されたので、表示と更新を行います。
    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();

    return TRUE;
}
かなり複雑になっていますね。
さて、このコードの最初の方にある
#ifdef _AFXDLL
    Enable3dControls(); 
#else
    Enable3dControlsStatic(); 
#endif
    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    LoadStdProfileSettings();  
や、真ん中にある
    // DDE、file open など標準のシェル コマンドのコマンドラインを解析します。
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    // コマンドラインでディスパッチ コマンドを指定します。
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;
はそのうち考えましょう。 残りの部分はVC入門3のコードとほぼ対応しています。違いは、VC入門3の「m_pMainWnd=new CMyWindow();」が、今回は無くなり、代わりに「CSingleDocTemplate* pDocTemplate; ... AddDocTemplate(pDocTemplate);」となったことです。VC入門3のアプリケーションはウインドウがひとつだけだったので単純でした。今回はウインドウがふたつあって、それがちょっと複雑な位置関係になっています。また、今回使わないとは言えSkeltonDocという新しいタイプのクラスも絡んでいます。これらアプリケーションに必要なクラスをまとめてアプリケーションに登録しなければならないと思っていた人はカンのいい人です。それがこの「CSingleDocTemplate* pDocTemplate; ... AddDocTemplate(pDocTemplate);」部分なのです。そう思ってみると「RUNTIME_CLASS(CSkeltonDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CSkeltonView));」はそれらしいですね。これがあるおかげで、ここでは「m_pMainWnd=new CMyWindow();」は要らないのです。
まじめに考えるとこんなのわけがわかりません。とても嫌なところかもしれません。しかし、まあ、そうなっているのです。こういうところを初心者が書き換えることは、(まだ)あまり無いと思います。だから知らなくても良いくらいなのです。気にし過ぎないでください。ただ、ああ、そんなもんか、くらいに思っておけば、その内、次の飛躍へとつながるのではないでしょうか。
これで、AppWizardの生成するコードのはじめの説明を終わりにします。まだ、よくわからないとしたら、あなたはまともな人です。これから、具体的なコードを見て考えていくことにしましょう。はじめに書きましたが、とにかく、先に進んでください
ところで、VC入門1で書いたように、今月は出張があるので、これ以上続けるのは無理です。(それと、メールも読めなくなります。したがって返事もしばらくできなくなります。すみません。)次回は、10月中旬となります。もし、万一、私の講座を楽しみにしている方がいらっしゃいましたら、どうも、ありがとうございます。そして、どうも、すみません。
では、次は10月に、、、。
目次のページ
前のページ
後のページ