Types de ressources

Voici les types de ressources prédéfinis.

Constant/value Description
RT_ACCELERATOR
MAKEINTRESOURCE(9)
Table accélérateur.
RT_ANICURSOR
MAKEINTRESOURCE(21)
Curseur animé.
RT_ANIICON
MAKEINTRESOURCE(22)
Icône animée.
RT_BITMAP
MAKEINTRESOURCE(2)
Ressource bitmap.
RT_CURSOR
MAKEINTRESOURCE(1)
Ressource de curseur dépendante du matériel.
RT_DIALOG
MAKEINTRESOURCE(5)
Boîte de dialogue.
RT_DLGINCLUDE
MAKEINTRESOURCE(17)
Permet à un outil d’édition de ressources d’associer une chaîne à un fichier .rc. En règle générale, la chaîne est le nom du fichier d’en-tête qui fournit des noms symboliques. Le compilateur de ressources analyse la chaîne, mais ignore sinon la valeur. Par exemple,
1 DLGINCLUDE "MyFile.h"
RT_FONT
MAKEINTRESOURCE(8)
Ressource de police.
RT_FONTDIR
MAKEINTRESOURCE(7)
Ressource de répertoire de polices.
RT_GROUP_CURSOR
MAKEINTRESOURCE((ULONG_PTR)(RT_CURSOR) + 11)
Ressource de curseur indépendante du matériel.
RT_GROUP_ICON
MAKEINTRESOURCE((ULONG_PTR)(RT_ICON) + 11)
Ressource d’icône indépendante du matériel.
RT_HTML
MAKEINTRESOURCE(23)
Ressource HTML.
RT_ICON
MAKEINTRESOURCE(3)
Ressource d’icône dépendante du matériel.
RT_MANIFEST
MAKEINTRESOURCE(24)
Manifeste d’assembly côte à côte.
RT_MENU
MAKEINTRESOURCE(4)
Ressource de menu.
RT_MESSAGETABLE
MAKEINTRESOURCE(11)
Entrée de table de messages.
RT_PLUGPLAY
MAKEINTRESOURCE(19)
Plug-and-Play ressource.
RT_RCDATA
MAKEINTRESOURCE(10)
Ressource définie par l’application (données brutes).
RT_STRING
MAKEINTRESOURCE(6)
Entrée de table de chaînes. Pour plus d’informations, consultez les remarques ci-dessous.
RT_VERSION
MAKEINTRESOURCE(16)
Ressource de version.
RT_VXD
MAKEINTRESOURCE(20)
VXD.

Remarques

Ressources de table de chaînes

Lors de l’énumération des ressources de table de chaînes (type RT_STRING) avec des fonctions telles que EnumResourceNamesW, le système n’énumère pas chaque ID de ressource de chaîne individuelle ; Au lieu de cela, il énumère les blocs de ressources. Vous devez inspecter ces blocs pour déterminer les ID de ressource de chaîne qu’ils contiennent réellement.

Les ressources de chaîne sont empaquetées en blocs, chacune contenant 16 chaînes avec préfixe de longueur représentant 16 ID consécutifs (dont certaines peuvent ne pas être utilisées ; voir ci-dessous). Étant donné un ID Xde ressource de chaîne, il est placé dans le numéro (X \ 16) + 1 de bloc de ressources (où \ désigne la division entière). Dans ce bloc, la ressource se trouve en tant qu’entrée N, où N = X % 16.

Le tableau suivant présente un exemple d’ID de ressource de chaîne et le numéro de bloc (et offset) de l’emplacement où ils se trouvent :

ID de ressource Bloquer # Décalage
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

Tous les ID de ressource inutilisés (manquants) sont indiqués par des chaînes de longueur nulle. Ainsi, dans l’exemple ci-dessus, le bloc #1 aura des chaînes de longueur nulle représentant les ID 0, 3, 4 et 6 - 14. Aucune des chaînes du bloc n’a de caractères NULL de fin, car elle est autorisée pour que les ressources de chaîne contiennent des valeurs NULL incorporées. Ainsi, la disposition de la mémoire du bloc #1 ressemble à ceci, en supposant que la valeur de chaque chaîne est « Hello world » (11 caractères longs) et où les nombres entre crochets représentent des entiers (et non des caractères littéraux) :

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

L’extrait de code suivant montre une fonction de rappel d’énumération qui énumère des ressources RT_STRING individuelles comme d’autres types (comme RT_ICON) plutôt que les blocs :

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

Exigences

Requirement Valeur
Header
Winuser.h