MFCによるWindowsデスクトップアプリ保守の知識マップ(知識グラフ)
MFCはWin32 APIをC++のクラスとして扱いやすくするフレームワークで、CWinAppがアプリ全体の初期化を担い、メッセージマップがWindowsメッセージをハンドラー関数に結びつけ、Document/ViewアーキテクチャがデータとUIの表示を分離し、DDX/DDVがダイアログのコントロールとメンバー変数を対応づけて検証します。MFCを使うにはVisual Studio InstallerでMFCコンポーネントを個別にインストールする必要があり、共有DLLか静的リンクかも構成できます。記事は、完全新規の一般的なGUIアプリケーションではMFCの採用を慎重に判断すべきである一方、既存MFCアプリの保守・機能追加・段階的移行では現実的によく価値があるという位置づけを示しています。
MFC(Microsoft Foundation Classes)
C++でWindowsデスクトップアプリやCOMサーバーを作るためのマイクロソフト製クラスライブラリ。
Win32 API
Windowsのネイティブなアプリケーション開発向けAPI群。
CWinApp
アプリケーション全体の初期化と終了を担う、MFCのCWinApp派生クラス。通常1つのグローバルオブジェクトとして存在する。
CWinAppクラス
メッセージマップ
Windowsメッセージやコマンドをハンドラー関数に結びつける、MFCのBEGIN_MESSAGE_MAPからEND_MESSAGE_MAPまでの対応表の仕組み。
Document/Viewアーキテクチャ
アプリケーションが扱うデータ(CDocument)と、その表示(CView)を分離するMFCの構造。ドキュメントテンプレートがフレーム・ドキュメント・ビューを結びつける。
DDX/DDV
ダイアログ上のコントロールとC++のメンバー変数を対応づけるDDX(Dialog Data Exchange)と、その入力値を検証するDDV(Dialog Data Validation)からなるMFCの仕組み。
リソースファイル(.rc/resource.h)
ダイアログテンプレート、メニュー、アイコン、文字列テーブルなどを定義するWindowsの.rcファイルと、対応するリソースIDを定義するresource.hの組。
.rcファイル
リソーススクリプト
CString
MFC/ATL系のコードで多用される、可変長の文字列を扱うC++クラス。
CStringクラス
Visual Studio InstallerのMFCコンポーネント
Visual Studio Installerで個別に選択する、MFCのヘッダーとライブラリ(atlmfcフォルダー)を提供するコンポーネント。
MFCのリンク方式(Use of MFC)
MFCを共有DLLとして使うか、静的ライブラリとしてリンクするかを選ぶプロジェクト設定(Use of MFC)。
MFCモジュール状態
MFC拡張DLLなどで、どのモジュールのリソースを見に行くかを切り替えるためにAFX_MANAGE_STATEマクロで管理する状態。
モジュール状態
ActiveX
実務ではCOMベースのコントロールやその周辺資産をまとめて指す言葉として使われる技術群。特に.ocx形式のUIコントロールやIE/コンテナへ埋め込む部品を含むことが多い。
ActiveXコントロール
bitness一致要件
ネイティブモジュール(in-procのCOMコンポーネント、P/Invokeで呼ぶDLL、ベンダー提供SDKのDLLなど)を読み込むホストプロセスと、そのモジュールのビット構成(32bit/64bit)が一致していなければならないという制約。
32bit/64bitの一致
高DPI対応
アプリケーションがディスプレイの拡大率に応じて正しくレイアウト・描画されるようにする、DPI対応モードの明示を含む設計・実装。
高DPI
DPI対応
高解像度ディスプレイ対応
完全新規の一般的なGUIアプリ開発
既存資産との連携を前提としない、これから作る一般的なGUIアプリケーションの新規開発。
新規GUIアプリ開発
グリーンフィールド開発
既存MFCアプリの保守・段階的移行
既存MFCアプリの保守・機能追加・ビルド環境更新・別UIへの段階的移行といった、既存資産を対象にした作業。
既存資産の保守
段階的移行
MFCはWin32 APIをC++のクラスとして扱いやすくするためのライブラリであり、Win32 APIの考え方を土台にした薄いフレームワークである
MFCアプリケーションでは通常CWinAppから派生したグローバルオブジェクトが1つ存在し、アプリケーション全体の初期化と終了を担う
CWinAppはWinMain、ウィンドウクラス登録、メッセージループなど通常Win32 APIで直接書く処理の多くをフレームワーク側で引き受ける
MFCはWindowsメッセージやコマンドをハンドラー関数に結びつけるメッセージマップという仕組みの実装を担う
メッセージマップはWM_COMMANDなどのWindowsメッセージを前提とし、自クラスから基底クラスへ対応表をたどってハンドラーへ振り分ける
MFCはアプリケーションが扱うデータ(Document)と表示(View)を分離するDocument/Viewアーキテクチャの実装を担う
フレーム・ドキュメント・ビューを結びつけるドキュメントテンプレートは、CWinApp派生クラスのInitInstanceの中で登録される
ON_COMMANDで登録されたコマンドはアクティブビュー・ドキュメント・フレーム・アプリケーションの順に配送されるコマンドルーティングを持ち、Document/View構造を使っているかどうかで配送先が変わる
MFCはダイアログ上のコントロールとC++メンバー変数を対応づけるDDXと、入力値を検証するDDVの実装を担う
DoDataExchangeはDDX_TextなどでリソースIDとメンバー変数を対応づけるため、resource.hで定義されたコントロールIDと一致している必要がある
MFCはAPIやコントロールとの相性から、可変長文字列クラスであるCStringを多用する
Visual StudioでMFCを使うには、C++ MFC for latest build toolsなどのコンポーネントをVisual Studio Installerで個別にインストールする必要があり、入っていないとafxwin.hが見つからずビルドが止まる
MFCはプロジェクト設定のUse of MFCで、共有DLLとして使うか静的ライブラリとしてリンクするかを構成できる
MFC拡張DLLなどでリソースを読み込む場面では、公開関数の入口でAFX_MANAGE_STATEを呼び正しいモジュール状態に切り替える必要がある
古い業務アプリでは、OLE Automation・ActiveXコントロール・COMサーバーなどCOM/OLE関連の要素がMFCアプリに組み込まれていることがある
COM/ActiveXを利用するMFCアプリでは、32bit MFCアプリからは32bit COM、64bit MFCアプリからは64bit COMを使う必要があり、x64化の際はCOM/ActiveX依存のビット構成を確認する(COM/ActiveXを使わないMFCアプリには当てはまらない)
古いMFCアプリを現代のWindowsで正しく表示するには、アプリケーションがDPI対応モードを明示し、固定ピクセル描画を見直す必要がある
MFCのドキュメントには新機能追加やドキュメント更新が行われないという注記があり、完全新規の一般的なGUIアプリケーションでの採用は慎重に判断すべきとされる
既存MFCアプリの保守・機能追加・ビルド環境更新・別UIへの段階的移行では、MFCの知識が現実的によく必要になる
AFX_MANAGE_STATEを忘れると、DLL内のダイアログや文字列リソースなどresource.h/.rcで定義したリソースが正しいモジュールから読み込まれなくなる