可変長配列を使いたい!と思ったらどういう選択肢があるだろうか。
私は、コードは出来る限りネイティブに書く。 つまり、マクロをあまり使わずに、出来る限りC/C++の書式通りに書くという事だ。 Windows上で開発しているので、windows.hで定義されているのも 勝手にネイティブに含まれるとみなす。そしてLPCTSTRやUINT等も使っている。 しかし、これでは上で述べたような可変長配列は使えない。 よって、さらに範囲を広げて、MFCを使ったコードもネイティブとみなすことにする。 STLではなくてMFCを使っているあたりが「腐ったWindows開発者」とも言えそうだが。 STLとMFCのどちらか片方を選ぶとしたら、私はGUIの領域までカバーしているMFCを選ぶ。 本来STLで書ける場所はSTLで書いてそれで無理なところはMFCを使うべきなのかも しれないが、(多少機能が重なった)ライブラリを2つも使うのがイヤだ、という 理由もある。
このようにして、MFCのほかには、出来る限り余計なものを使わず、作らずにコードを 書くわけだ。なんでこうしているかと言うと、こうやって書かれたコードは、 同じMFCの他のプロジェクトに移植した場合、恐ろしい移植性を誇る。(Windows限定) MFCしか使われていないので、余計なものも必要なく、 ただ対象のコードだけを移せば完了するからである。これは結構便利だと思う。 ちなみにMFCを使っているとWindows以外のOSに移植しようとすると地獄をみると思うので 注意しましょう。
MFCのMDIで、既に開かれているドキュメントにもう1つビューを追加する方法です。 ウィンドウ分割を使用する方法は、MSDNにサンプルもあるので、 もう1つウィンドウとしてビューを追加する方法を考えてみます。 メニューから何かコマンドを選ぶと、 現在開かれているドキュメントに新しいビューウィンドウが1つ追加される、という方針とします。
まず、Viewクラスを作成します。クラスウィザードを用いると簡単でしょう。 しかし、クラスウィザードを用いると、CxxxApp::InitInstanceに 余計なコードを加え、起動時にどのビューを用いるか選択を迫られるようなアプリになることがあります。 それで良いというのならば構わないのですが、方針と違いますので CxxxApp::InitInstanceに追加されたコードを削除しておきましょう。 |
次に、CxxxAppクラスにメンバ変数を追加します。 |
CMultiDocTemplate* m_lpxxxTemplate; |
コンストラクタでNULLに初期化しておきましょう。 |
CxxxApp::CxxxApp() { m_lpxxxTemplate = NULL; } |
次に、CxxxApp::InitInstanceでCMultiDocTemplateクラスのオブジェクトを作成します。 CxxxViewには、新しく作成したViewクラスの名前を入れましょう。 |
BOOL CxxxApp::InitInstance() { ... m_lpxxxTemplate = new CMultiDocTemplate( IDR_XXX, RUNTIME_CLASS(CxxxDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CxxxView)); ... } |
ExitInstanceで解放しておきましょう。 |
CxxxApp::ExitInstance() { if (m_lpxxxTemplate != NULL)delete m_lpxxxTemplate; } |
それでは最後に、実際に新しいビューを開くコードを書きましょう。 CxxxDocクラスの、何かのコマンドハンドラに書く事にします。 |
CxxxDoc::Onxxx() { CFrameWnd* pNewFrame = ((CxxxApp*)AfxGetApp())->m_lpxxxTemplate->CreateNewFrame(this, NULL); pNewFrame->InitialUpdateFrame(this, TRUE); } |