特集

Vista時代のVisual C++の流儀(中編)

MFCから.NETへの実践的移行計画

επιστημη(えぴすてーめー)
2007/03/06

●.NET移行前のMFCサンプル・アプリケーション

 VC++&MFC&SDIで、簡単なサンプル・アプリケーション(MFCStringStack)を作ってみました。文字列のスタックです。

文字列をスタック構造により保存するMFCで構築されたサンプル・アプリケーション(MFCStringStack)

 右上にあるテキストボックスに入力された文字列は[Push]ボタンでスタックに積まれます。[Pop]ボタンは文字列をスタックから取り出してテキストボックスへ移し、[Clear]ボタンはスタックを空にします。左のリストボックスはスタックに積まれている文字列を表示します。

 このサンプル・プログラムはここ(MFCStringStack.zip)からダウンロードできます。

●Documentの実装内容

 Documentには、Viewからの処理要求を受け付けるPush、Pop、Clearというメソッドを、そしてスタックの内容を表示するために必要なSizeメソッド(文字列の数を返す)およびAtメソッド(指定した位置の文字列を返す)を用意しました。そのヘッダ・コード(MFCStringStackDoc.hファイル)は以下のとおりです。

// MFCStringStackDoc.h
……省略……
class CMFCStringStackDoc : public CDocument {
  ……省略……
public:
  void    Push(const CString& str);
  CString Pop(void);
  void    Clear(void);
  bool    Empty(void) const;
  int     Size() const;
  CString At(int index) const;

private:
#ifdef USE_MFCCONTAINER
  CArray<CString> container_;
#else
  std::vector<CString> container_;
#endif
};
文字列スタックを実装するMFCによるDocumentのヘッダ・コード(MFCStringStackDoc.h)

 Document内での文字列スタックは「container_」という可変長配列を用いています。MFCが提供するCArrayクラス、もしくは標準C++ライブラリのvectorクラスのどちらを使うかを「USE_MFCCONTAINER」マクロで切り替えています。

 各メソッドの実装は以下のとおりです。

// MFCStringStackDoc.cpp
……省略……
#ifdef USE_MFCCONTAINER
void CMFCStringStackDoc::Push(const CString& str) {
  container_.Add(str);
  UpdateAllViews(0);
}

CString CMFCStringStackDoc::Pop() {
  INT_PTR position = container_.GetCount() - 1;
  CString result = container_.GetAt(position);
  container_.RemoveAt(position);
  UpdateAllViews(0);
  return result;
}
……省略……
#else /* USE_MFCCONTAINER */

void CMFCStringStackDoc::Push(const CString& str) {
  container_.push_back(str);
  UpdateAllViews(0);
}

CString CMFCStringStackDoc::Pop() {
  CString result = container_.back();
  container_.pop_back();
  UpdateAllViews(0);
  return result;
}
……省略……
#endif /* USE_MFCCONTAINER */
文字列スタックを実装するMFCによるDocumentのソース・コード(MFCStringStackDoc.cpp)

 メソッドPush/Pop/Clearはスタックの内容が変化するため、いずれも処理が完了し次第UpdateAllViewsメソッドを呼び出しています。

●Viewの実装内容

 View側はとても単純です。[Push][Pop][Clear]の各ボタンに対するイベント・ハンドラで、それぞれに応じたDocumentのメソッドを呼び出すだけです。

// MFCStringStackView.cpp
……省略……
void CMFCStringStackView::OnBnClickedPush() {
  CString str;
  GetDlgItem(IDC_STRING)->GetWindowText(str);
  GetDocument()->Push(str);
}

void CMFCStringStackView::OnUpdate(CView*, LPARAM, CObject*) {
  CListBox* box = static_cast<CListBox*>(GetDlgItem(IDC_STACK));
  box->ResetContent();
  for (int index = GetDocument()->Size() - 1; index >= 0; --index) {
    box->AddString(GetDocument()->At(index));
  }
}
文字列スタックを実装するMFCによるViewのソース・コード(MFCStringStackView.cpp)

 OnUpdateメソッドはDocumentのSizeメソッドとAtメソッドを使って文字列スタックから文字列を読み出し、リストボックスに流し込みます。

 実際にコンパイルする前には、以下の画面を参考に、このMFCによるプロジェクトがUnicode文字列ベースに設定されていることを確認してください。VC++ 6.0以前のプロジェクトではマルチバイト文字列ベースになっているはずです。

プロジェクト・プロパティでの文字列セット(文字列ベース)の確認
プロジェクトのプロパティを表示して、MFCプロジェクトがUnicode文字列ベースに設定されているかを確認しているところ。プロジェクト・プロパティのダイアログは、ソリューション・エクスプローラのプロジェクトを右クリックして、表示されるコンテキスト・メニューから[プロパティ]を選択すると表示される。「構成プロパティ」−「全般」の[文字列セット]で「Unicode 文字セットを使用する」を指定する(選択肢には、このほかに「設定なし」や「マルチ バイト文字セットを使用する」などがある)。

 Unicode文字列ベースにプロパティ設定を変更し、ビルド/実行/テストを行って正しく動作することを確認しておいてください。この設定が正しくなされていれば、MFCのCStringクラスを.NETのStringクラス(System名前空間)に置き換えることができ、Unicode⇔マルチバイト変換を必要とする個所が少なくなります。

●MFCのDocument/Viewアーキテクチャの.NET化

 ではこのMFCアプリケーションの.NET化を試みましょう。前述のとおり、View側はC++/CLIではなくC#を使うことにします。


 INDEX
  [特集]
  Vista時代のVisual C++の流儀(前編)
  Vista到来。既存C/C++資産の.NET化を始めよう!
    1.Vista時代にC/C++はもはやお払い箱なのか?
    2.C/C++資産をどこまで生かせる?
    3.ネイティブ・オブジェクトをマネージ・コードでくるむ
    4.文字コード変換
 
  Vista時代のVisual C++の流儀(中編)
  MFCから.NETへの実践的移行計画
    1.C++/CLIによるWindowsフォーム・アプリケーション
    2.言語をまたいだDocument/Viewアーキテクチャ
  3..NET移行前のMFCサンプル・アプリケーション
    4.MFCのDocument/Viewアーキテクチャの.NET化
    5.MFCで書かれたDocumentを.NET化する2つの方法
 
  Vista時代のVisual C++の流儀(後編)
  STL/CLRによるDocument/Viewアーキテクチャ
    1.STL/CLRとは
    2.STL/CLRの特徴
    3.Visual Studio 2005で試す
    4.おまけ:NUnitの活用


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間