前回 リソースリスト(CRESLIST)クラスをファイル出力ベースから文字列ベースに変更したので、後残っていることは、
(1)「種類」、「言語」の出力を、人間にとって分かり易い文字出力に変更
(2)コンソール用のコードを削除してヘッダーファイル(CRESLIST.h)とし、BCCSkeltonの器に落とし込む
だけです。
(1)については、単純にリソースの種類が出ているここ と言語が出ているここ (注)をコピペして、構造体にしちゃいましょう。
注:すべてコピーするのは面倒なので、街中の指示標識用言語位にしておきました。そして(2)については"printf(...)"文等のコンソール関連部分を総て削除して、CRESLIST.hというヘッダーファイルを作りました。以下(1)関連は水色 で解説します。
【CRESLIST.h】
//////////////////////////////////////////////////////////
// CRESLIST.h
// CRESLISTクラス定義ファイル
// 概要:実行可能ファイルのリソースを調べ、一覧を出力する
//////////////////////////////////////////////////////////
#include <strsafe.h>
#define RTTMAX 21 //種類テーブル配列数(開発時の暫定値、増やしていただいて結構です。)
#define LTMAX 6 //言語テーブル配列数(Ditto)
/////////////
//構造体定義
/////////////
typedef struct _RT_TABLE { //リソースタイプ(RT)-種類テーブル
TCHAR* macro;
UINT id;
TCHAR* name;
} RT_TABLE, *PRT_TABLE;
typedef struct _LOC_TABLE { //ローカライゼィション-言語テーブル
TCHAR* area;
TCHAR* tag;
UINT id_hex;
UINT id;
} LOC_TABLE, *PLOC_TABLE;
///////////////////////////////
// CRESLISTクラス定義ファイル
// Copyright (c) August, 2024
// By Ysama
///////////////////////////////
class CRESLIST
{
private:
HMODULE m_hExe; //EXEファイルのハンドル
TCHAR m_ResFileName[MAX_PATH] = {'\0'}; //リソースファイル名(拡張子前FileName + "_resinfo.txt")
TCHAR* m_Data; //リソースリストのデータポインター
size_t m_DataLen; //m_Dataの長さ
RT_TABLE m_rtt[RTTMAX] = {
// マクロ名 整数ID 説明
{"RT_CURSOR", 1, "ハードウェア依存カーソル"},
{"RT_BITMAP", 2, "ビットマップ"},
{"RT_ICON", 3, "ハードウェア依存するアイコン"},
{"RT_MENU", 4, "メニュー"},
{"RT_DIALOG", 5, "ダイアログボックス"},
{"RT_STRING", 6, "ストリングテーブル"},
{"RT_FONTDIR", 7, "フォントディレクトリ"},
{"RT_FONT", 8, "フォント"},
{"RT_ACCELERATOR", 9, "アクセラレータ"},
{"RT_RCDATA", 10, "アプリケーション定義リソース"},
{"RT_MESSAGETABLE", 11, "メッセージテーブル"},
{"RT_VERSION", 16, "バージョン"},
{"RT_DLGINCLUDE", 17, "文字列関連付け"},
{"RT_PLUGPLAY", 19, "プラグアンドプレイ"},
{"RT_VXD", 20, "Vxd"},
{"RT_ANICURSOR", 21, "アニメーションカーソル"},
{"RT_ANIICON", 22, "アニメーションアイコン"},
{"RT_HTML", 23, "HTML"},
{"RT_MANIFEST", 24, "アセンブリ マニフェスト"},
{"RT_GROUP_CURSOR", (ULONG_PTR(RT_CURSOR) + 11),"ハードウェア非依存カーソル"},
{"RT_GROUP_ICON", (ULONG_PTR(RT_ICON) + 11), "ハードウェア非依存アイコン"}
};
LOC_TABLE m_lt[LTMAX] = {
// 言語/地域 言語/地域タグ 言語/地域ID 言語/地域10進ID
{"中国語 (繁体字、台湾)", "zh-TW", 0x0404, 1028},
{"英語 (米国)", "en-US", 0x0409, 1033},
{"日本語 (日本)", "ja-JP", 0x0411, 1041},
{"韓国語 (韓国)", "ko-KR", 0x0412, 1042},
{"中国語 (簡体字、中国)", "zh-CN", 0x0804, 2052},
{"英語 (英国)", "en-GB", 0x0809, 2057}
};
public:
CRESLIST(); //コンストラクター1
CRESLIST(LPCTSTR); //コンストラクター2
~CRESLIST(); //デストラクター
void Init(); //初期化処理
bool BeginResList(LPCTSTR); //実行可能ファイル名を与えて開始
bool AddData(LPCTSTR, size_t); //m_Dataに長さsize_tの文字列を追加する
LPCTSTR GetData() {return m_Data;} //m_Dataをコピーする(呼び出し側でdelete [] destが必須)
bool SaveList(); //現在開いているファイルのリソースリストを保存する
static bool EnumTypesFunc(HMODULE, LPCTSTR, LONG); //リソース種類取得用コールバック関数
static bool EnumNamesFunc(HMODULE, LPCTSTR, LPCTSTR, LONG); //リソース名取得用コールバック関数
static bool EnumLangsFunc(HMODULE, LPCTSTR, LPCTSTR, WORD, LONG); //リソース言語取得用コールバック関数
};
//コンストラクター1
//コンストラクター2
//デストラクター
//初期化処理
//実行可能ファイル名を与えて開始
bool CRESLIST::BeginResList(LPCTSTR FileName) {
//m_Dataに文字列を追加する
//現在開いているファイルのリソースリストを保存する
//ここまでは変更がないため、前回 を参照ください。
//リソース種類取得用コールバック関数EnumTypesFunc(HMODULE, LPCTSTR, LONG)
bool CRESLIST::EnumTypesFunc(HMODULE hModule, LPCTSTR lpType, LONG lParam) {
TCHAR szBuffer[MAX_PATH] = {'\0'}; //infoファイル用プリントバッファ
size_t cbString; //szBufferの文字列長
HRESULT hResult; //結果判定用変数
//szBufferにリソース種類を書き込む
//種類は文字列または符号なし整数であり、事前にテストを行う
if(!IS_INTRESOURCE(lpType)) { //解説:リソースが文字列の場合はそのまま表示します。
hResult = StringCchPrintf(szBuffer, MAX_PATH, TEXT("種類:%s\r\n"), lpType);
if(FAILED(hResult))
return FALSE;
}
else //解説:リソース種類が整数の場合は、該当文字列を検索して表示し、該当が無い場合は数字を表示します。
{
//m_rrt配列内リソース種類検索
for(int i = 0; i < RTTMAX; i++) { //解説:リソーステーブルのIDを検索します。
if((UINT)lpType == ((CRESLIST*)lParam)->m_rtt[i].id) {
StringCchCopy(szBuffer, MAX_PATH, TEXT("種類:"));
StringCchCat(szBuffer, MAX_PATH, ((CRESLIST*)lParam)->m_rtt[i].name);
StringCchCat(szBuffer, MAX_PATH, TEXT("\r\n"));
break;
}
}
if(!*szBuffer) { //szBuffer[0]が初期値(NULL)の場合( 解説:即ち該当がない場合)
hResult = StringCchPrintf(szBuffer, MAX_PATH, TEXT("種類:%u\r\n"), (USHORT)lpType);
if(FAILED(hResult))
return FALSE;
}
}
hResult = StringCchLength(szBuffer, MAX_PATH, &cbString);
if(FAILED(hResult))
return FALSE;
//m_Dataの更新
((CRESLIST*)lParam)->AddData(szBuffer, cbString);
//同種のリソースを総て検索する
EnumResourceNames(hModule, lpType, (ENUMRESNAMEPROC)EnumNamesFunc, lParam);
return TRUE;
}
//リソース名取得用コールバック関数EnumNamesFunc(HMODULE, LPCSTR, LPCSTR, LONG)
bool CRESLIST::EnumNamesFunc(HMODULE hModule, LPCTSTR lpType, LPCTSTR lpName, LONG lParam) {
TCHAR szBuffer[MAX_PATH] = {'\0'}; //infoファイル用プリントバッファ
size_t cbString; //szBufferの文字列長
HRESULT hResult; //結果判定用変数
//szBufferにリソース名を書き込む
//リソース名は文字列または符号なし整数であり、事前にテストを行う
if(!IS_INTRESOURCE(lpName)) {
hResult = StringCchPrintf(szBuffer, MAX_PATH, TEXT("\tリソース名:%s\r\n"), lpName);
if(FAILED(hResult))
return FALSE;
}
else
{
hResult = StringCchPrintf(szBuffer, MAX_PATH, TEXT("\tリソース名:%s\r\n"), (USHORT)lpName);
if(FAILED(hResult))
return FALSE;
}
hResult = StringCchLength(szBuffer, MAX_PATH, &cbString);
if(FAILED(hResult))
return FALSE;
//m_Dataの更新
((CRESLIST*)lParam)->AddData(szBuffer, cbString);
//同種のリソースの言語を総て検索する
EnumResourceLanguages(hModule, lpType, lpName, (ENUMRESLANGPROC)EnumLangsFunc, lParam);
return TRUE;
}
//リソース言語取得用コールバック関数EnumLangsFunc(HMODULE, LPCTSTR, LPCTSTR, WORD, LONG)
bool CRESLIST::EnumLangsFunc(HMODULE hModule, LPCTSTR lpType, LPCTSTR lpName, WORD wLang, LONG lParam) {
HRSRC hResInfo; //リソース情報ハンドル
TCHAR szBuffer[MAX_PATH] = {'\0'}; //infoファイル用プリントバッファ
size_t cbString; //szBufferの文字列長
HRESULT hResult; //結果判定用変数
hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);
//szBufferへリソース情報を書き込む
//m_lt配列内リソース種類検索
for(int i = 0; i < LTMAX; i++) { //解説:言語テーブルのIDを検索します。
if((UINT)wLang == ((CRESLIST*)lParam)->m_lt[i].id) {
StringCchCopy(szBuffer, MAX_PATH, TEXT("\t\tリソース言語: "));
StringCchCat(szBuffer, MAX_PATH, ((CRESLIST*)lParam)->m_lt[i].area);
StringCchCat(szBuffer, MAX_PATH, TEXT("\r\n"));
break;
}
}
if(!*szBuffer) { //szBuffer[0]が初期値(NULL)の場合( 解説:即ち該当がない場合)
hResult = StringCchPrintf(szBuffer, MAX_PATH, TEXT("\t\tリソース言語: %u\r\n"), (USHORT) wLang);
if(FAILED(hResult))
return FALSE;
}
hResult = StringCchLength(szBuffer, MAX_PATH, &cbString);
if(FAILED(hResult))
return FALSE;
//m_Dataの更新
((CRESLIST*)lParam)->AddData(szBuffer, cbString);
//リソースハンドルとサイズをバッファーに書き込む
hResult = StringCchPrintf(szBuffer, MAX_PATH, TEXT("\t\tリソースハンドル:%lx、サイズ:%lu\r\n\r\n"), hResInfo, SizeofResource(hModule, hResInfo));
if(FAILED(hResult))
return FALSE;
hResult = StringCchLength(szBuffer, MAX_PATH, &cbString);
if (FAILED(hResult))
return FALSE;
//m_Dataの更新
((CRESLIST*)lParam)->AddData(szBuffer, cbString);
return TRUE;
}
これでウィンドウズプログラムに使えるCRESLISTクラスのヘッダーファイルが出来ました。後はそれをウィンドウの器に入れてやるだけです。
(種類、言語が文字列で表示されている。)
次回からはBCCSkelton(注 )版のResourceListの開発手順を示します。
注 :BCCSkelton版はANSIベースになります。UNICODEベースにしたい場合は、一旦BCCSkeltonのファイルをSkeltonWIzardで作り、その後BCC2ECCユーティリティを使ってECCSkeltonのファイルに変換してください。この話は次回以降また説明します。