Ressourcentypen

Im Folgenden sind die vordefinierten Ressourcentypen aufgeführt.

Constant/value Beschreibung
RT_ACCELERATOR
MAKEINTRESOURCE(9)
Accelerator-Tabelle.
RT_ANICURSOR
MAKEINTRESOURCE(21)
Animierter Cursor.
RT_ANIICON
MAKEINTRESOURCE(22)
Animiertes Symbol.
RT_BITMAP
MAKEINTRESOURCE(2)
Bitmapressource.
RT_CURSOR
MAKEINTRESOURCE(1)
Hardwareabhängige Cursorressource.
RT_DIALOG
MAKEINTRESOURCE(5)
Dialogfeld.
RT_DLGINCLUDE
MAKEINTRESOURCE(17)
Ermöglicht es einem Ressourcenbearbeitungstool, eine Zeichenfolge einer RC-Datei zuzuordnen. In der Regel ist die Zeichenfolge der Name der Headerdatei, die symbolische Namen bereitstellt. Der Ressourcencompiler analysiert die Zeichenfolge, ignoriert aber andernfalls den Wert. Beispiel:
1 DLGINCLUDE "MyFile.h"
RT_FONT
MAKEINTRESOURCE(8)
Schriftartressource.
RT_FONTDIR
MAKEINTRESOURCE(7)
Schriftartverzeichnisressource.
RT_GROUP_CURSOR
MAKEINTRESOURCE((ULONG_PTR)(RT_CURSOR) + 11)
Hardwareunabhängige Cursorressource.
RT_GROUP_ICON
MAKEINTRESOURCE((ULONG_PTR)(RT_ICON) + 11)
Hardwareunabhängige Symbolressource.
RT_HTML
MAKEINTRESOURCE(23)
HTML-Ressource.
RT_ICON
MAKEINTRESOURCE(3)
Hardwareabhängige Symbolressource.
RT_MANIFEST
MAKEINTRESOURCE(24)
Paralleles Assemblymanifest.
RT_MENU
MAKEINTRESOURCE(4)
Menüressource.
RT_MESSAGETABLE
MAKEINTRESOURCE(11)
Meldungstabelleneintrag.
RT_PLUGPLAY
MAKEINTRESOURCE(19)
Plug & Play Ressource.
RT_RCDATA
MAKEINTRESOURCE(10)
Anwendungsdefinierte Ressource (Rohdaten).
RT_STRING
MAKEINTRESOURCE(6)
Zeichenfolgentabelleneintrag. Weitere Informationen finden Sie weiter unten in den Anmerkungen .
RT_VERSION
MAKEINTRESOURCE(16)
Versionsressource.
RT_VXD
MAKEINTRESOURCE(20)
VXD.

Hinweise

Ressourcen für Zeichenfolgentabellen

Beim Aufzählen von Zeichenfolgentabellenressourcen (Typ RT_STRING) mit Funktionen wie EnumResourceNamesW listet das System nicht jede einzelne Zeichenfolgenressourcen-ID auf; Stattdessen werden Blöcke von Ressourcen aufgezählt. Sie müssen diese Blöcke überprüfen, um zu bestimmen, welche Zeichenfolgenressourcen-ID(n) sie tatsächlich enthalten.

Zeichenfolgenressourcen werden in Blöcke verpackt, von denen jede 16 längepräfixierte Zeichenfolgen enthält, die 16 aufeinander folgende IDs darstellen (einige davon können nicht verwendet werden; siehe unten). Bei einer Zeichenfolgenressourcen-ID Xwird sie in die Ressourcenblocknummer (X \ 16) + 1 eingefügt (wobei \ eine ganzzahlige Division bezeichnet wird). Innerhalb dieses Blocks kann die Ressource als Nth-Eintrag gefunden werden, wobei N = X % 16.

Die folgende Tabelle zeigt einige Beispiel-Zeichenfolgenressourcen-IDs und die Blocknummer (und den Offset) der Position, an der sie sich befinden:

Ressourcen-ID Blockierung # 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

Nicht verwendete (fehlende) Ressourcen-IDs werden durch leere Zeichenfolgen gekennzeichnet. Im obigen Beispiel enthält Block #1 also Zeichenfolgen der Länge Null, die IDs 0, 3, 4 und 6 - 14 darstellen. Keiner der Zeichenfolgen im Block beendet NULL-Zeichen , da Zeichenfolgenressourcen eingebettete NULLs enthalten dürfen. Daher sieht das Speicherlayout von Block #1 wie folgt aus, vorausgesetzt, der Wert jeder Zeichenfolge ist "Hello world" (11 Zeichen lang) und wobei die Zahlen in winkeln Klammern ganze Zahlen (nicht Literalzeichen) darstellen:

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

Der folgende Codeausschnitt zeigt eine Enumerationsrückruffunktion, die einzelne RT_STRING Ressourcen genau wie andere Typen (wie RT_ICON) und nicht die Blöcke aufzählt:

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

Anforderungen

Anforderung Wert
Kopfzeile
Winuser.h