Tipos de recurso

Veja a seguir os tipos de recursos predefinidos.

Constant/value Description
RT_ACCELERATOR
MAKEINTRESOURCE(9)
Tabela de acelerador.
RT_ANICURSOR
MAKEINTRESOURCE(21)
Cursor animado.
RT_ANIICON
MAKEINTRESOURCE(22)
Ícone animado.
RT_BITMAP
MAKEINTRESOURCE(2)
Recurso bitmap.
RT_CURSOR
MAKEINTRESOURCE(1)
Recurso de cursor dependente de hardware.
RT_DIALOG
MAKEINTRESOURCE(5)
Caixa de diálogo.
RT_DLGINCLUDE
MAKEINTRESOURCE(17)
Permite que uma ferramenta de edição de recursos associe uma cadeia de caracteres a um arquivo .rc. Normalmente, a cadeia de caracteres é o nome do arquivo de cabeçalho que fornece nomes simbólicos. O compilador de recursos analisa a cadeia de caracteres, mas ignora o valor. Por exemplo
1 DLGINCLUDE "MyFile.h"
RT_FONT
MAKEINTRESOURCE(8)
Recurso de fonte.
RT_FONTDIR
MAKEINTRESOURCE(7)
Recurso de diretório de fonte.
RT_GROUP_CURSOR
MAKEINTRESOURCE((ULONG_PTR)(RT_CURSOR) + 11)
Recurso de cursor independente de hardware.
RT_GROUP_ICON
MAKEINTRESOURCE((ULONG_PTR)(RT_ICON) + 11)
Recurso de ícone independente de hardware.
RT_HTML
MAKEINTRESOURCE(23)
Recurso HTML.
RT_ICON
MAKEINTRESOURCE(3)
Recurso de ícone dependente de hardware.
RT_MANIFEST
MAKEINTRESOURCE(24)
Manifesto do assembly lado a lado.
RT_MENU
MAKEINTRESOURCE(4)
Recurso de menu.
RT_MESSAGETABLE
MAKEINTRESOURCE(11)
Entrada da tabela de mensagens.
RT_PLUGPLAY
MAKEINTRESOURCE(19)
Plug and Play recurso.
RT_RCDATA
MAKEINTRESOURCE(10)
Recurso definido pelo aplicativo (dados brutos).
RT_STRING
MAKEINTRESOURCE(6)
Entrada de tabela de cadeia de caracteres. Consulte Comentários abaixo para obter mais informações.
RT_VERSION
MAKEINTRESOURCE(16)
Recurso de versão.
RT_VXD
MAKEINTRESOURCE(20)
VXD.

Observações

Recursos de tabela de cadeia de caracteres

Ao enumerar recursos de Tabela de Cadeia de Caracteres (tipo RT_STRING) com funções como EnumResourceNamesW, o sistema não enumera cada ID de recurso de cadeia de caracteres individual; em vez disso, enumera blocos de recursos. Você deve inspecionar esses blocos para determinar quais IDs de recurso de cadeia de caracteres eles realmente contêm.

Os recursos de cadeia de caracteres são empacotados em blocos, cada um deles contém 16 cadeias de caracteres prefixadas de comprimento que representam 16 IDs consecutivas (algumas das quais podem não ser usadas; veja abaixo). Considerando uma ID Xde recurso de cadeia de caracteres, ela será colocada no número (X \ 16) + 1 do bloco de recursos (em \ que denota a divisão de inteiros). Dentro desse bloco, o recurso pode ser encontrado como a Nth entrada, em N = X % 16que .

A tabela a seguir mostra algumas IDs de recurso de cadeia de caracteres de exemplo e o número de bloco (e deslocamento) de onde elas estarão localizadas:

ID do recurso Bloquear # 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

Todas as IDs de recurso não utilizados (ausentes) são indicadas por cadeias de caracteres de comprimento zero. Portanto, no exemplo acima, o bloco nº 1 terá cadeias de caracteres de comprimento zero que representam as IDs 0, 3, 4 e 6 a 14. Nenhuma das cadeias de caracteres no bloco tem caracteres NULL encerrados, pois é permitido que os recursos de cadeia de caracteres contenham NULLs inseridos. Portanto, o layout de memória do bloco nº 1 tem esta aparência, supondo que o valor de cada cadeia de caracteres seja "Olá, mundo" (11 caracteres de comprimento) e onde os números entre colchetes angulares representam inteiros (não caracteres literais):

<0><11>Hello world<11>Hello world<0><0>
<11>Hello world<0><0><0><0><0><0><0><0>
<0><11>Hello world

O snippet de código a seguir mostra uma função de retorno de chamada de enumeração que enumerará recursos RT_STRING individuais, assim como outros tipos (como RT_ICON) em vez dos blocos:

// 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;
}

Requirements

Requirement Valor
Cabeçalho
Winuser.h