リソースの種類

定義済みのリソースの種類を次に示します。

Constant/value Description
RT_ACCELERATOR
MAKEINTRESOURCE(9)
アクセラレータ テーブル。
RT_ANICURSOR
MAKEINTRESOURCE(21)
アニメーションカーソル。
RT_ANIICON
MAKEINTRESOURCE(22)
アニメーション化されたアイコン。
RT_BITMAP
MAKEINTRESOURCE(2)
ビットマップ リソース。
RT_CURSOR
MAKEINTRESOURCE(1)
ハードウェア依存カーソル リソース。
RT_DIALOG
MAKEINTRESOURCE(5)
ダイアログ ボックス。
RT_DLGINCLUDE
MAKEINTRESOURCE(17)
リソース編集ツールで文字列を .rc ファイルに関連付けることができます。 通常、文字列はシンボリック名を提供するヘッダー ファイルの名前です。 リソース コンパイラは文字列を解析しますが、それ以外の場合は値を無視します。 たとえば、 のように指定します。
1 DLGINCLUDE "MyFile.h"
RT_FONT
MAKEINTRESOURCE(8)
フォント リソース。
RT_FONTDIR
MAKEINTRESOURCE(7)
フォント ディレクトリ リソース。
RT_GROUP_CURSOR
MAKEINTRESOURCE((ULONG_PTR)(RT_CURSOR) + 11)
ハードウェアに依存しないカーソル リソース。
RT_GROUP_ICON
MAKEINTRESOURCE((ULONG_PTR)(RT_ICON) + 11)
ハードウェアに依存しないアイコン リソース。
RT_HTML
MAKEINTRESOURCE(23)
HTML リソース。
RT_ICON
MAKEINTRESOURCE(3)
ハードウェアに依存するアイコン リソース。
RT_MANIFEST
MAKEINTRESOURCE(24)
サイド バイ サイド アセンブリ マニフェスト。
RT_MENU
MAKEINTRESOURCE(4)
メニュー リソース。
RT_MESSAGETABLE
MAKEINTRESOURCE(11)
メッセージ テーブル エントリ。
RT_PLUGPLAY
MAKEINTRESOURCE(19)
リソースプラグ アンド プレイします。
RT_RCDATA
MAKEINTRESOURCE(10)
アプリケーション定義リソース (生データ)。
RT_STRING
MAKEINTRESOURCE(6)
文字列テーブル エントリ。 詳細については 、以下の「解説 」を参照してください。
RT_VERSION
MAKEINTRESOURCE(16)
バージョン リソース。
RT_VXD
MAKEINTRESOURCE(20)
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>(&params));
};

//////////

// 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
Winuser.h