概要


・MFC ライブラリは、Windows プログラミングのための、C++ で記述されたオブジェクト指向のアプリケーション フレームワークです。
・ドキュメント/ビュー アーキテクチャは、アプリケーション内部のデータに当たる「ドキュメント」と、そのデータを表示する「ビュー」とを分離して実装するアーキテクチャです。
データの格納や保守の処理を、データ表示の処理から分離することで、アプリケーションの柔軟性や保守性が向上します。
また、ここでいう「ドキュメント」とは、一般に言う「文書 (ドキュメント)」を実装するためのものというわけではなく、プログラムで扱うデータ全般に利用できます。
たとえば、クライアント アプリケーションとして、データベースから取り込んだデータを一時的にキャッシュする場所として利用したり、
アプリケーションの現在の状態 (ステート) を保持する場所として利用したりできます。
・一般に MFC アプリケーションに機能を追加する場合は、クラスのメンバー関数をオーバーライドしたり、イベント駆動型のハンドラーに当たる関数を実装したりします。
これらの関数は、ある一定の順序で呼び出され、この仕組みをうまく生かすには、それぞれの関数で行うべき役割や位置付けを理解しておく必要があります。

◆MFC 関連のヘッダーをインクルードする汎用的なヘッダー
ファイル名: stdafx.h (新規作成)に以下を記入↓
◆MFC ライブラリのために用いる標準的なヘッダー
・しゃーぷinclude

・しゃーぷinclude

プロジェクト内の各ソース ファイルでは、この stdafx.h をインクルードする記述を追加します

・MFC アプリケーションには、いわばアプリケーションの中核ともいえる「アプリケーションクラス」のオブジェクトが 1 つ必要になります。
アプリケーション クラスとは、MFC ライブラリが提供する CWinApp クラス (実際には、この派生クラスを使用) のことです。

・MFC では、WinMain 関数に相当する実装はライブラリ側に記述されているので、プログラマーが WinMain 関数を記述することはありません。
MFC ライブラリが持つ WinMain 関数では、初期化から後処理までの一連の流れを実現するため、
◆「アプリケーションクラス(CWinApp 派生クラス)」の 3 つのメンバー関数 (InitInstance、Run、および ExitInstance) を順に呼び出すように実装されています。
・InitInstance:アプリ初期化
・Run:メッセージループ
・ExitInstance:アプリ後処理

・MFC アプリケーション ウィザードが生成するアプリケーション クラスは、CWinApp クラスを継承し拡張した CWinAppEx クラスから派生しています。
・プログラマーは、CWinApp 派生クラスを定義する必要があります。3 つの関数は仮想関数であり、必要に応じて、これらのメンバー関数をオーバーライドします。
このうち、特別な理由がない限り、Run 関数についてはオーバーライドせずに、基本クラスに実装された既存のメッセージ ループを利用すればよいでしょう。
ExitInstance 関数の後処理も固有の処理を行う必要がなければ、オーバーライドする必要はありません。通常は、アプリケーション固有の振る舞いの準備のため、
InitInstance 関数はオーバーライドします。

◆インスタンス関数のオーバーライド
→ヘッダファイル
・しゃーぷpragma once
・しゃーぷinclude "resource.h" //←[7]リソース ID のシンボルを定義

class CSmallApp : public CWinApp //←[1]CWinApp 派生クラス (ここでは CSmallApp クラス) を定義
{
public:
virtual BOOL InitInstance(); //←[2]基本クラスの InitInstance 関数をオーバーライドすべく宣言
};

→cppファイル
・しゃーぷinclude "stdafx.h"
・しゃーぷinclude "SmallApp.h"
・しゃーぷinclude "MainFrm.h" //←[8]フレーム ウィンドウのヘッダーをインクルード

CSmallApp theApp; //←[3]WinMain 関数から呼び出してもらうために、↓のCSmallApp クラスのグローバル オブジェクト インスタンスも確保するよう定義(変数名は任意)

BOOL CSmallApp::InitInstance() //←[4]実際にオーバーライドした実装。この InitInstance 関数で行うべき主な初期化は、メイン ウィンドウを作成すること
{
CWinApp::InitInstance(); //←[5]作法として、CWinApp 基本クラスの InitInstance 関数に実装された既定の初期処理を禁止する特別な事情がない限り、
原則として、基本クラスの同名関数を呼び出しておくのがよい。

//ここでメインのフレームウィンドウを作成する 
CMainFrame* pMainFrame = new CMainFrame();  //←[9]インスタンスを作成
pMainFrame->LoadFrame( IDR_MAINFRAME );     //←[10]3 つのメンバー関数を順に呼び出し、ウィンドウを表示
pMainFrame->ShowWindow( m_nCmdShow );           引数にはリソース スクリプトのリソース ID が指定される
pMainFrame->UpdateWindow();  
m_pMainWnd = pMainFrame;  //←[11]必ずメンバー変数 m_pMainWnd に対して、フレーム ウィンドウのポインターを設定する。
                            この設定を行わずに、InitInstance 関数の戻り値として TRUE を返しても、メッセージ ループに進むことができず、アプリケーションが強制終了。


return TRUE;  //←[6]TRUE を返すことで、MFC ライブラリ内の WinMain 関数では、引き続きメッセージ ループ (Run 関数呼び出し) へと処理が続く。
InitInstance 関数内でダイアログ ボックスを表示してアプリケーションを終了したいような場合、
つまり、メッセージ ループを必要とするメインウィンドウを利用しない場合は、意図的に FALSE を返すコードを記述することもあります。

}

◆フレーム ウィンドウ(フレームを持ったメイン ウィンドウ)は、CFrameWnd クラスに実装されています。→ フレームを持たせたくない場合は?
ここではCFrameWnd から派生した CMDIFrameWnd クラス(SDI の場合は、CFrameWnd クラス)を使用します。
・CMDIFrameWnd は継承せずにそのまま利用できますが、ここでは MFC アプリケーション ウィザードが生成するコードに合わせて、
この CMDIFrameWnd クラスの派生クラスを定義しておきましょう。そのほうが、後から機能追加する際にも便利です。
→MainFrm.h
class CMainFrame : public CMDIFrameWnd
{

};

→MainFrm.cpp
・しゃーぷinclude "stdafx.h"
・しゃーぷinclude "MainFrm.h"

※ #pragma once→インクルードガード
ソースコードのinclude処理が重複して発生することを防ぐためのもの