自分自身のリソースからアプリケーション名とバージョン番号を取得する
C++Builderの[プロジェクト|オプション|バージョン番号]で設定したバージョン番号を取得するには、GetFileVersionInfoとVerQueryValueを使用してアプリケーションの情報を取得する。VerQueryValueで戻ってくるサイズは文字数。
UnicodeString GetApplicationNameAndVersion()
{
// 自分自身のフルパス
const TCHAR* ExeName = Application->ExeName.t_str();
// リソース領域のサイズを取得
DWORD Size = GetFileVersionInfoSize(ExeName, NULL);
// リソース領域を取得
BYTE *pVersionInfo = new BYTE[Size];
GetFileVersionInfo(ExeName, NULL, Size, pVersionInfo);
// アプリケーション名を取得
VOID* pProductName; // アプリケーション名へのポインタ
UINT ProductNameLength; // アプリケーション名の文字列長さ
VerQueryValue(pVersionInfo, _T("\\StringFileInfo\\041103A4\\ProductName"),
&pProductName, &ProductNameLength);
UnicodeString strProductName((TCHAR*)pProductName, ProductNameLength);
// バージョン番号を取得
VOID* pVersion;
UINT VersionLength;
VerQueryValue(pVersionInfo, _T("\\StringFileInfo\\041103A4\\ProductVersion"),
&pVersion, &VersionLength);
UnicodeString strVersion((TCHAR*)pVersion, VersionLength);
UnicodeString AppVersion;
// 本当は、VerQueryValueで戻ってきた文字列長を考慮して、ヌルターミネーターの処理をすべきかも。
AppVersion.printf(L"%s Version %s", pProductName, pVersion);
// 後始末
delete pVersionInfo;
return AppVersion;
}
マジックナンバー"041103A4"の意味は、"0411"は日本語のロカールIDで"03A4"はコードページ。C++BuilderはSHIFT-JIS(0x03a4=932)となっている。VisualC++の例だとUTF-16LE(0x04b0=1200)の場合もある。
もしかしたら、言語ロカールIDとコードページをマジックナンバーで決め打ちするのではなく、リソース領域からLANGANDCODEPAGEでロカールIDを列挙するのが正式な作法かもしれない。