定義済みのリソースの種類を次に示します。
| Constant/value | Description |
|---|---|
|
アクセラレータ テーブル。 |
|
アニメーションカーソル。 |
|
アニメーション化されたアイコン。 |
|
ビットマップ リソース。 |
|
ハードウェア依存カーソル リソース。 |
|
ダイアログ ボックス。 |
|
リソース編集ツールで文字列を .rc ファイルに関連付けることができます。 通常、文字列はシンボリック名を提供するヘッダー ファイルの名前です。 リソース コンパイラは文字列を解析しますが、それ以外の場合は値を無視します。 たとえば、 のように指定します。1 DLGINCLUDE "MyFile.h" |
|
フォント リソース。 |
|
フォント ディレクトリ リソース。 |
|
ハードウェアに依存しないカーソル リソース。 |
|
ハードウェアに依存しないアイコン リソース。 |
|
HTML リソース。 |
|
ハードウェアに依存するアイコン リソース。 |
|
サイド バイ サイド アセンブリ マニフェスト。 |
|
メニュー リソース。 |
|
メッセージ テーブル エントリ。 |
|
リソースプラグ アンド プレイします。 |
|
アプリケーション定義リソース (生データ)。 |
|
文字列テーブル エントリ。 詳細については 、以下の「解説 」を参照してください。 |
|
バージョン リソース。 |
|
VXD。 |
注釈
文字列テーブル リソース
EnumResourceNamesW などの関数を使用して String Table リソース (型 RT_STRING) を列挙する場合、システムは個々の文字列リソース ID を列挙しません。代わりに、リソースのブロックを列挙します。 これらのブロックを調べて、実際に含まれている文字列リソース ID を特定する必要があります。
文字列リソースはブロックにパッケージ化され、それぞれが 16 個の連続する ID を表す 16 個の長さのプレフィックス付き文字列を含みます (一部は使用できません。以下を参照)。 文字列リソース ID Xを指定すると、リソース ブロック番号 (X \ 16) + 1 に配置されます (ここで、 \ は整数除算を表します)。 そのブロック内で、リソースは N 番目のエントリ ( N = X % 16) として見つけることができます。
次の表は、文字列リソース ID の例と、それらが配置される場所のブロック番号 (およびオフセット) を示しています。
| リソース ID | ブロック# | Offset |
|---|---|---|
| 1 |
(1 \ 16) + 1 = 1 |
1 % 16 = 1 |
| 2 |
(2 \ 16) + 1 = 1 |
2 % 16 = 2 |
| 5 |
(5 \ 16) + 1 = 1 |
5 % 16 = 5 |
| 15 |
(15 \ 16) + 1 = 1 |
15 % 16 = 15 |
| 20 |
(20 \ 16) + 1 = 2 |
20 % 16 = 4 |
| 32 |
(32 \ 16) + 1 = 3 |
32 % 16 = 0 |
| 50 |
(50 \ 16) + 1 = 4 |
50 % 16 = 2 |
| 100 |
(100 \ 16) + 1 = 7 |
100 % 16 = 4 |
未使用の (不足している) リソース ID は、長さ 0 の文字列で示されます。 そのため、上の例では、ブロック #1 には ID 0、3、4、6 - 14 を表す長さ 0 の文字列があります。 文字列リソースに埋め込み NULL を含める許可があるため、ブロック内のどの文字列も NULL 文字を終了しません。 したがって、各文字列の値が "Hello world" (長さ 11 文字) で、山かっこ内の数値が整数 (リテラル文字ではない) を表していると仮定すると、ブロック 1 のメモリ レイアウトは次のようになります。
<0><11>Hello world<11>Hello world<0><0>
<11>Hello world<0><0><0><0><0><0><0><0>
<0><11>Hello world
次のコード スニペットは、ブロックではなく他の型 ( RT_ICON など) と同様に個々 のRT_STRING リソースを列挙する列挙コールバック関数を示しています。
// Number of entries in the string table.
constexpr UINT STRING_TABLE_SIZE{ 16 };
// Returns the original resource ID from a given block / offset.
inline UINT GetStringResourceIdFromStringTable(LPCWSTR lpName, const unsigned int index)
{
_ASSERT(index < STRING_TABLE_SIZE);
return ((reinterpret_cast<UINT>(lpName) - 1) * STRING_TABLE_SIZE) + index;
}
// Helper function that will enumerate string table blocks, looking for resources.
BOOL EnumerateResourceNamesWrapperForStrings(HMODULE hModule, LPWSTR lpName, LONG_PTR lParam, ENUMRESNAMEPROCW lpEnumFunc)
{
// No need to free or unlock resources in Win32, so OK to throw away intermediates
auto ptr = (wchar_t*)LockResource(LoadResource(hModule, FindResource(hModule, lpName, RT_STRING)));
if (ptr)
{
for (unsigned int i = 0; i < STRING_TABLE_SIZE; ++i)
{
wchar_t size = *ptr;
if (size > 0)
{
auto id = GetStringResourceIdFromStringTable(lpName, i);
// Invoke the callback for this string resource ID.
auto callbackResult = lpEnumFunc(hModule, RT_STRING, MAKEINTRESOURCE(id), lParam);
if (!callbackResult)
{
return callbackResult;
}
}
// Skip to next potential string in the block
ptr += size + 1;
}
return TRUE;
}
// Couldn't load the string table entry; something is wrong.
return FALSE;
}
// Wrapper function for EnumResourceNamesW that will enumerate individual string resources.
BOOL EnumResourceNamesIncludingStringsW(HMODULE hModule, LPCWSTR lpType, ENUMRESNAMEPROCW lpEnumFunc, LONG_PTR lParam)
{
struct param_wrapper { ENUMRESNAMEPROCW lpEnumFunc; LONG_PTR lParam; } params{ lpEnumFunc, lParam };
// Use a simple lambda to either call our String helper, or directly call the user's callback
return EnumResourceNamesW(hModule, lpType, [](auto hModule, auto lpType, auto lpName, auto lParam)
{
auto params = reinterpret_cast<param_wrapper*>(lParam);
if (lpType == RT_STRING)
{
return EnumerateResourceNamesWrapperForStrings(hModule, lpName, params->lParam, params->lpEnumFunc);
}
return params->lpEnumFunc(hModule, lpType, lpName, params->lParam);
}, reinterpret_cast<LONG_PTR>(¶ms));
};
//////////
// Sample callback that just increments a counter.
BOOL CountResources(HMODULE, LPCWSTR, LPWSTR, LONG_PTR lParam)
{
// Add one to the count...
(*(reinterpret_cast<UINT*>(lParam)))++;
return TRUE;
}
// Sample usage:
void CountStringsInExplorer()
{
auto lib = LoadLibraryExW(LR"(c:\windows\explorer.exe)", nullptr, LOAD_LIBRARY_AS_DATAFILE);
if (!lib)
{
return;
}
UINT nStringBlocks{ 0 };
UINT nStrings{ 0 };
// Count the number of string blocks using raw Win32 API.
EnumResourceNamesW(lib, RT_STRING, CountResources, (LONG_PTR)&nStringBlocks);
// Count the number of actual strings, using the wrapper.
EnumResourceNamesIncludingStringsW(lib, RT_STRING, CountResources, (LONG_PTR)&nStrings);
// Outputs something like:
//
// Explorer.exe contains 44 strings (in 17 blocks).
//
std::wcout << L"Explorer.exe contains " << nStrings << L" strings (in " << nStringBlocks
<< L" blocks)." << std::endl;
}
必要条件
| 要件 | 価値 |
|---|---|
| Header |
|