Visual C++ 6.0(VC6)時代のプロジェクトを現代の環境(VS2022/2026など)へ移行し,ビルドを通すためには,ビルド設定だけでなくソースコード(C++)自体の修正が不可欠です.
特に「マルチバイト文字セット(MBCS)からUnicode(_UNICODE)への移行」と「32bit(x86)から64bit(x64)への対応」は,ほぼすべてのプロジェクトで直面する大きな壁となります.本記事では,長年蓄積されたレガシーコードを現代基準へ適応させるための,主要なコード変更ポイントの備忘録です.
1. 互換性のための古いコードの整理と文字セット対応
まずは古い環境依存の関数を整理し,現代の標準であるUnicode文字セットで正しく処理できるように文字列周りを修正します.
■ 古い3Dコントロール関数の削除
- アプリケーションクラス(CWinApp)の
InitInstance内にある,Enable3dControls 関連(あるいは Enable3dControlsStatic)の条件分岐および呼び出しをすべて削除します.現代のOSやMFCではこれらは不要です.
■ 文字・文字列リテラルのマクロ保護
- 文字や文字列の直接記述(マルチバイト前提のコード)は,Unicode環境でのビルド時に型不整合の原因になります.文字リテラルや文字列リテラルはすべて
_T()マクロで括るように修正します.
■ CString変数のポインタ解釈エラーの回避
- マルチバイト環境(_MBCS)では暗黙的に通っていたコードが,Unicode環境に変わることで CString 型の変数が意図しない型として解釈されるケースがあります.その場合は,明示的に
LPCTSTR()でキャスト(括る)して文字列ポインタとして渡すように修正します.
■ 文字列操作関数の汎用化と安全対策
- 文字列操作関数を,Unicodeとマルチバイトの双方に対応できる
_tで始まる汎用関数(TCHARマクロ系関数)に置き換えます. - コンパイラのバージョン(_MSC_VER)に応じて,セキュア版(_s版)関数と以前の関数を柔軟に切り替えられるラッパーを用意しておくと,移植性が向上します.
2. 64bit(x64)対応に伴う型と引数の修正
現代のOS環境に合わせてx64ターゲットでビルドする場合,データ型のサイズ変更に伴う型エラーや不整合が発生します.
■ MFCコレクションクラスやサイズの変数型の変更
- CArray::GetSize など,MFCの各所でデータ個数やサイズを返す関数の戻り値が
intからINT_PTRに変更されています. - これまで
int型で受けていた箇所は,すべてINT_PTR型で受けるように書き換えます.これはダイアログベース等のプロジェクトでも同様の対応が必要です.
■ タイマーイベント等の引数変更
- ウインドウメッセージに関連するコールバック関数(OnTimerなど)も,識別子を受け取る引数の型が
UINTからUINT_PTRに変更されています.メッセージマップのエントリとシグネチャを正しく一致させる必要があります.
■ 可変長引数(sprintfなど)を使用している部分の修正
- 独自の古い実装で可変長引数を扱っている部分などは,必要に応じてプリプロセッサマクロによる切り分けや,現代的な安全な書式化関数へのリプレースを検討します.
3. ビジュアルスタイルの有効化(マニフェスト依存関係の追加)
コントロールの見た目を現代のWindowsスタイル(コモンコントロール バージョン6.0)に適応させるため,ヘッダーファイル(stdafx.h など)の終端付近にリンクオプション(manifestdependency)を補足します.
コンパイラバージョンおよびターゲットアーキテクチャ(x86 / x64等)に応じて,適切なコモンコントロールを読み込むためのプラグマ(pragma comment)を記述することで,古いMFCアプリのUIが現代的な綺麗な見た目に変化します.
ソースコードの詳細や文字列操作の逆引きマニュアル
Cスタイル文字列から CString への安全な相互変換手順や,gccなど異種コンパイラでのビルドを通すための汎用マクロ定義ファイル(_tdefine.hxx)の具体的な構造,さらに各アーキテクチャ向けのマニフェスト依存関係記述の正確なテキストについては,私のブログにて詳しく公開しています.
実際のコード書き換え手順や定義ファイルをそのまま活用してマイグレーションを進めたい方は,ぜひご参照ください.
詳細記事はこちら:VC6 プロジェクトのコードの移行 - IwaoDev