FormatMessage-Funktion (winbase.h)

Formatiert eine Nachrichtenzeichenfolge. Die Funktion erfordert eine Nachrichtendefinition als Eingabe. Die Nachrichtendefinition kann aus einem Puffer stammen, der an die Funktion übergeben wird. Sie kann aus einer Nachrichtentabellenressource in einem bereits geladenen Modul stammen. Oder der Aufrufer kann die Funktion bitten, die Nachrichtentabellenressourcen des Systems nach der Nachrichtendefinition zu durchsuchen. Die Funktion sucht die Nachrichtendefinition in einer Nachrichtentabellenressource basierend auf einem Nachrichtenbezeichner und einem Sprachbezeichner. Die Funktion kopiert den formatierten Nachrichtentext in einen Ausgabepuffer und verarbeitet bei Bedarf alle eingebetteten Einfügesequenzen.

Syntax

DWORD FormatMessage(
  [in]           DWORD   dwFlags,
  [in, optional] LPCVOID lpSource,
  [in]           DWORD   dwMessageId,
  [in]           DWORD   dwLanguageId,
  [out]          LPTSTR  lpBuffer,
  [in]           DWORD   nSize,
  [in, optional] va_list *Arguments
);

Parameter

[in] dwFlags

Die Formatierungsoptionen und die Interpretation des lpSource-Parameters . Das Byte mit niedriger Ordnung von dwFlags gibt an, wie die Funktion Zeilenumbrüche im Ausgabepuffer verarbeitet. Das Byte mit niedriger Ordnung kann auch die maximale Breite einer formatierten Ausgabezeile angeben.

Dieser Parameter kann einen oder mehrere der folgenden Werte aufweisen.

Wert Bedeutung
FORMAT_MESSAGE_ALLOCATE_BUFFER
0x00000100
Die Funktion weist einen Puffer zu, der groß genug ist, um die formatierte Nachricht aufzunehmen, und platziert einen Zeiger auf den zugeordneten Puffer an der von lpBuffer angegebenen Adresse. Der lpBuffer-Parameter ist ein Zeiger auf eine LPTSTR; Sie müssen den Zeiger auf eine LPTSTR -Instanz umstellen (z. B. (LPTSTR)&lpBuffer). Der nSize-Parameter gibt die Mindestanzahl von TCHARs an, die einem Ausgabemeldungspuffer zugeordnet werden sollen. Der Aufrufer sollte die LocalFree-Funktion verwenden, um den Puffer frei zu geben, wenn er nicht mehr benötigt wird.

Wenn die Länge der formatierten Nachricht 128.000 Bytes überschreitet, schlägt FormatMessage fehl, und ein späterer Aufruf von GetLastError gibt ERROR_MORE_DATA zurück.

In früheren Versionen von Windows war dieser Wert beim Kompilieren von Windows Store-Apps nicht verfügbar. Ab Windows 10 kann dieser Wert verwendet werden.

Windows Server 2003 und Windows XP:

Wenn die Länge der formatierten Nachricht 128.000 Bytes überschreitet, schlägt FormatMessage nicht automatisch mit dem Fehler ERROR_MORE_DATA fehl.

FORMAT_MESSAGE_ARGUMENT_ARRAY
0x00002000
Der Arguments-Parameter ist keine va_list-Struktur , sondern ein Zeiger auf ein Array von Werten, die die Argumente darstellen.

Dieses Flag kann nicht mit ganzzahligen 64-Bit-Werten verwendet werden. Wenn Sie eine ganze 64-Bit-Zahl verwenden, müssen Sie die va_list Struktur verwenden.

FORMAT_MESSAGE_FROM_HMODULE
0x00000800
Der lpSource-Parameter ist ein Modulhandle, das die zu durchsuchenden Nachrichtentabellenressourcen enthält. Wenn dieses lpSource-HandleNULL ist, wird die Anwendungsimagedatei des aktuellen Prozesses durchsucht. Dieses Flag kann nicht mit FORMAT_MESSAGE_FROM_STRING verwendet werden.

Wenn das Modul über keine Nachrichtentabellenressource verfügt, schlägt die Funktion mit ERROR_RESOURCE_TYPE_NOT_FOUND fehl.

FORMAT_MESSAGE_FROM_STRING
0x00000400
Der lpSource-Parameter ist ein Zeiger auf eine null-beendete Zeichenfolge, die eine Nachrichtendefinition enthält. Die Nachrichtendefinition kann Einfügesequenzen enthalten, genau wie der Nachrichtentext in einer Nachrichtentabellenressource. Dieses Flag kann nicht mit FORMAT_MESSAGE_FROM_HMODULE oder FORMAT_MESSAGE_FROM_SYSTEM verwendet werden.
FORMAT_MESSAGE_FROM_SYSTEM
0x00001000
Die Funktion sollte die Systemnachrichtentabellenressourcen nach der angeforderten Nachricht durchsuchen. Wenn dieses Flag mit FORMAT_MESSAGE_FROM_HMODULE angegeben wird, durchsucht die Funktion die Systemmeldungstabelle, wenn die Nachricht nicht in dem von lpSource angegebenen Modul gefunden wird. Dieses Flag kann nicht mit FORMAT_MESSAGE_FROM_STRING verwendet werden.

Wenn dieses Flag angegeben ist, kann eine Anwendung das Ergebnis der GetLastError-Funktion übergeben, um den Nachrichtentext für einen systemdefinierten Fehler abzurufen.

FORMAT_MESSAGE_IGNORE_INSERTS
0x00000200
Einfügesequenzen in der Nachrichtendefinition wie %1 sollen ignoriert und unverändert an den Ausgabepuffer übergeben werden. Dieses Flag ist nützlich, um eine Nachricht zur späteren Formatierung abzurufen. Wenn dieses Flag festgelegt ist, wird der Arguments-Parameter ignoriert.
 

Das Low-Order-Byte von dwFlags kann die maximale Breite einer formatierten Ausgabezeile angeben. Im Folgenden sind mögliche Werte des Byte mit niedriger Ordnung aufgeführt.

Wert Bedeutung
0
Es gibt keine Einschränkungen für die Breite der Ausgabezeilen. Die Funktion speichert Zeilenumbrüche, die sich im Nachrichtendefinitionstext befinden, im Ausgabepuffer.
FORMAT_MESSAGE_MAX_WIDTH_MASK
0x000000FF
Die Funktion ignoriert regelmäßige Zeilenumbrüche im Nachrichtendefinitionstext. Die Funktion speichert hartcodierte Zeilenumbrüche im Nachrichtendefinitionstext im Ausgabepuffer. Die Funktion generiert keine neuen Zeilenumbrüche.
 

Wenn das Byte mit niedriger Ordnung ein anderer Wert als FORMAT_MESSAGE_MAX_WIDTH_MASK ist, gibt es die maximale Anzahl von Zeichen in einer Ausgabezeile an. Die Funktion ignoriert regelmäßige Zeilenumbrüche im Nachrichtendefinitionstext. Die Funktion teilt niemals eine durch Leerzeichen getrennte Zeichenfolge über einen Zeilenumbruch auf. Die Funktion speichert hartcodierte Zeilenumbrüche im Nachrichtendefinitionstext im Ausgabepuffer. Hartcodierte Zeilenumbrüche werden mit der Escapesequenz %n codiert.

[in, optional] lpSource

Der Speicherort der Nachrichtendefinition. Der Typ dieses Parameters hängt von den Einstellungen im dwFlags-Parameter ab.

Dwflags Einstellung Bedeutung
FORMAT_MESSAGE_FROM_HMODULE
0x00000800
Ein Handle für das Modul, das die zu durchsuchende Nachrichtentabelle enthält.
FORMAT_MESSAGE_FROM_STRING
0x00000400
Zeiger auf eine Zeichenfolge, die aus unformatiertem Nachrichtentext besteht. Es wird auf Einfügevorgänge überprüft und entsprechend formatiert.
 

Wenn keines dieser Flags in dwFlags festgelegt ist, wird lpSource ignoriert.

[in] dwMessageId

Der Nachrichtenbezeichner für die angeforderte Nachricht. Dieser Parameter wird ignoriert, wenn dwFlagsFORMAT_MESSAGE_FROM_STRING enthält.

[in] dwLanguageId

Der Sprachbezeichner für die angeforderte Nachricht. Dieser Parameter wird ignoriert, wenn dwFlagsFORMAT_MESSAGE_FROM_STRING enthält.

Wenn Sie eine bestimmte LANGID in diesem Parameter übergeben, gibt FormatMessage nur eine Nachricht für diese LANGID zurück. Wenn die Funktion keine Nachricht für diese LANGID finden kann, legt sie Last-Error auf ERROR_RESOURCE_LANG_NOT_FOUND fest. Wenn Sie null übergeben, sucht FormatMessage nach einer Nachricht für LANGIDs in der folgenden Reihenfolge:

  1. Sprachneutral
  2. Thread LANGID, basierend auf dem Gebietsschemawert des Threads
  3. Benutzerstandard-LANGID, basierend auf dem Standardgebietsschemawert des Benutzers
  4. Systemstandard-LANGID, basierend auf dem Systemstandardgebietsschemawert
  5. Englisch (USA)
Wenn FormatMessage keine Nachricht für eine der vorherigen LANGIDs findet, gibt es eine beliebige sprachbasierte Nachrichtenzeichenfolge zurück, die vorhanden ist. Wenn dies fehlschlägt, wird ERROR_RESOURCE_LANG_NOT_FOUND zurückgegeben.

[out] lpBuffer

Ein Zeiger auf einen Puffer, der die NULL-endende Zeichenfolge empfängt, die die formatierte Nachricht angibt. Wenn dwFlagsFORMAT_MESSAGE_ALLOCATE_BUFFER enthält, ordnet die Funktion einen Puffer mithilfe der Funktion LocalAlloc zu und platziert den Zeiger auf den Puffer an der in lpBuffer angegebenen Adresse.

Dieser Puffer darf nicht größer als 64.000 Bytes sein.

[in] nSize

Wenn das flag FORMAT_MESSAGE_ALLOCATE_BUFFER nicht festgelegt ist, gibt dieser Parameter die Größe des Ausgabepuffers in TCHARs an. Wenn FORMAT_MESSAGE_ALLOCATE_BUFFER festgelegt ist, gibt dieser Parameter die Mindestanzahl von TCHARs an, die einem Ausgabepuffer zugeordnet werden sollen.

Der Ausgabepuffer darf nicht größer als 64.000 Byte sein.

[in, optional] Arguments

Ein Array von Werten, die als Einfügewerte in der formatierten Nachricht verwendet werden. Ein %1 in der Formatzeichenfolge gibt den ersten Wert im Argumentarray an. ein %2 gibt das zweite Argument an; Und so weiter.

Die Interpretation der einzelnen Werte hängt von den Formatierungsinformationen ab, die der Einfügung in der Nachrichtendefinition zugeordnet sind. Standardmäßig wird jeder Wert als Zeiger auf eine null-endende Zeichenfolge behandelt.

Standardmäßig ist der Arguments-Parameter vom Typ va_list*. Hierbei handelt es sich um einen sprach- und implementierungsspezifischen Datentyp zum Beschreiben einer variablen Anzahl von Argumenten. Der Zustand des va_list-Arguments ist beim Zurückgeben von der Funktion nicht definiert. Um den va_list erneut zu verwenden, löschen Sie den Variablenargumentlistenzeiger mit va_end , und initialisieren Sie ihn mit va_start erneut.

Wenn Sie keinen Zeiger vom Typ va_list* haben, geben Sie das flag FORMAT_MESSAGE_ARGUMENT_ARRAY an, und übergeben Sie einen Zeiger an ein Array von DWORD_PTR Werten. Diese Werte werden in die Nachricht eingegeben, die als Einfügewerte formatiert ist. Jede Einfügung muss über ein entsprechendes Element im Array verfügen.

Rückgabewert

Wenn die Funktion erfolgreich ist, ist der Rückgabewert die Anzahl der im Ausgabepuffer gespeicherten TCHARs , mit Ausnahme des abschließenden NULL-Zeichens.

Wenn die Funktion fehlerhaft ist, ist der Rückgabewert null. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Hinweise

Innerhalb des Nachrichtentexts werden mehrere Escapesequenzen zum dynamischen Formatieren der Nachricht unterstützt. Diese Escapesequenzen und ihre Bedeutungen werden in den folgenden Tabellen dargestellt. Alle Escapesequenzen beginnen mit dem Prozentzeichen (%).

Escapesequenz Bedeutung
%0 Beendet eine Nachrichtentextzeile ohne nachfolgendes neues Zeilenzeichen. Diese Escapesequenz kann verwendet werden, um lange Zeilen zu erstellen oder die Nachricht selbst ohne ein nachfolgendes neues Zeilenzeichen zu beenden. Es ist nützlich für Eingabeaufforderungsmeldungen.
%n! Formatzeichenfolge! Identifiziert eine Einfügesequenz. Der Wert von n kann im Bereich von 1 bis 99 liegen. Die Formatzeichenfolge (die von Ausrufezeichen umgeben werden muss) ist optional und wird standardmäßig auf !s! , wenn die Angabe fehlt. Weitere Informationen finden Sie unter Formatspezifikationsfelder.

Die Formatzeichenfolge kann einen Breiten- und Genauigkeitsspezifizierer für Zeichenfolgen und einen Breitenbezeichner für ganze Zahlen enthalten. Verwenden Sie ein Sternchen (), um die Breite und Genauigkeit anzugeben. Beispiel: %1!. *s! oder %1!*u!.

Wenn Sie die Breiten- und Genauigkeitsspezifizierer nicht verwenden, entsprechen die Einfügezahlen direkt den Eingabeargumenten. Wenn die Quellzeichenfolge beispielsweise "%1 %2 %1" lautet und die Eingabeargumente "Bill" und "Bob" sind, lautet die formatierte Ausgabezeichenfolge "Bill Bob Bill".

Wenn Sie jedoch einen Breiten- und Genauigkeitsspezifizierer verwenden, entsprechen die Einfügenummern nicht direkt den Eingabeargumenten. Die Einfügenummern für das vorherige Beispiel können sich beispielsweise in "%1!*.*s! ändern. %4 %5!*s!".

Die Einfügenummern hängen davon ab, ob Sie ein Argumentarray (FORMAT_MESSAGE_ARGUMENT_ARRAY) oder eine va_list verwenden. Bei einem Argumentarray ist die nächste Einfügenummer n+2 , wenn die vorherige Formatzeichenfolge ein Sternchen enthält, und n+3 , wenn zwei Sternchen angegeben wurden. Bei einem va_list lautet die nächste Einfügenummer n+1 , wenn die vorherige Formatzeichenfolge ein Sternchen enthält, und n+2 , wenn zwei Sternchen angegeben wurden.

Wenn Sie wie im vorherigen Beispiel "Bill" wiederholen möchten, müssen die Argumente zweimal "Bill" enthalten. Beispiel: Die Quellzeichenfolge lautet "%1!*.*s! %4 %5!*s!" könnten die Argumente sein, 4, 2, Bill, Bob, 6, Bill (bei Verwendung des flags FORMAT_MESSAGE_ARGUMENT_ARRAY ). Die formatierte Zeichenfolge wäre dann "Bi Bob Bill".

Wiederholte Einfügenummern, wenn die Quellzeichenfolge Breiten- und Genauigkeitsspezifizierer enthält, liefern möglicherweise nicht die gewünschten Ergebnisse. Wenn Sie %5 durch %1 ersetzt haben, würde die Funktion versuchen, eine Zeichenfolge an Adresse 6 zu drucken (was wahrscheinlich zu einer Zugriffsverletzung führt).

Gleitkommaformatbezeichner (e, E, f und g) werden nicht unterstützt. Die Problemumgehung besteht darin, die StringCchPrintf-Funktion zu verwenden, um die Gleitkommazahl in einen temporären Puffer zu formatieren, und dann diesen Puffer als Einfügezeichenfolge zu verwenden.

Einfügungen, die das I64-Präfix verwenden, werden als zwei 32-Bit-Argumente behandelt. Sie müssen verwendet werden, bevor nachfolgende Argumente verwendet werden. Beachten Sie, dass es für Sie möglicherweise einfacher ist, StringCchPrintf anstelle dieses Präfixes zu verwenden.

 

Alle anderen Zeichen, die auf ein Prozentzeichen folgen, werden in der Ausgabemeldung ohne das Prozentzeichen formatiert. Hier einige Beispiele.

Formatzeichenfolge Resultierende Ausgabe
%% Ein einzelnes Prozentzeichen.
%B Ein einzelnes Leerzeichen. Diese Formatzeichenfolge kann verwendet werden, um die angemessene Anzahl von nachgestellten Leerzeichen in einer Nachrichtentextzeile sicherzustellen.
%. Ein einzelner Punkt. Diese Formatzeichenfolge kann verwendet werden, um einen einzelnen Punkt am Anfang einer Zeile einzuschließen, ohne die Nachrichtentextdefinition zu beenden.
%! Ein einzelnes Ausrufezeichen. Diese Formatzeichenfolge kann verwendet werden, um ein Ausrufezeichen unmittelbar nach einer Einfügung einzuschließen, ohne dass er für den Anfang einer Formatzeichenfolge verwechselt wird.
%n Ein harter Zeilenumbruch, wenn die Formatzeichenfolge am Ende einer Zeile auftritt. Diese Formatzeichenfolge ist nützlich, wenn FormatMessage reguläre Zeilenumbrüche angibt, damit die Nachricht in eine bestimmte Breite passt.
%r Ein harter Wagenrücklauf ohne nachfolgendes Zeilenumbruchzeichen.
%t Eine einzelne Registerkarte.
 

Sicherheitsbemerkungen

Wenn diese Funktion ohne FORMAT_MESSAGE_IGNORE_INSERTS aufgerufen wird, muss der Arguments-Parameter genügend Parameter enthalten, um alle Einfügesequenzen in der Nachrichtenzeichenfolge zu erfüllen, und sie müssen den richtigen Typ aufweisen. Verwenden Sie daher keine nicht vertrauenswürdigen oder unbekannten Nachrichtenzeichenfolgen mit aktivierten Einfügungen, da sie mehr Einfügesequenzen enthalten können, als Arguments bereitstellt, oder solche, die möglicherweise den falschen Typ aufweisen. Insbesondere ist es unsicher, einen beliebigen Systemfehlercode zu verwenden, der von einer API zurückgegeben wird, und FORMAT_MESSAGE_FROM_SYSTEM ohne FORMAT_MESSAGE_IGNORE_INSERTS zu verwenden.

Beispiele

Die FormatMessage-Funktion kann verwendet werden, um Fehlermeldungszeichenfolgen für die von GetLastError zurückgegebenen Systemfehlercodes abzurufen. Ein Beispiel finden Sie unter Abrufen des Last-Error Codes.

Das folgende Beispiel zeigt die Verwendung eines Argumentarrays sowie der Breiten- und Genauigkeitsspezifizierer.
#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>
#include <stdio.h>

void main(void)
{
    LPWSTR pMessage = L"%1!*.*s! %4 %5!*s!";
    DWORD_PTR pArgs[] = { (DWORD_PTR)4, (DWORD_PTR)2, (DWORD_PTR)L"Bill",  // %1!*.*s! refers back to the first insertion string in pMessage
         (DWORD_PTR)L"Bob",                                                // %4 refers back to the second insertion string in pMessage
         (DWORD_PTR)6, (DWORD_PTR)L"Bill" };                               // %5!*s! refers back to the third insertion string in pMessage
    const DWORD size = 100+1;
    WCHAR buffer[size];


    if (!FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                       pMessage, 
                       0,
                       0,
                       buffer, 
                       size, 
                       (va_list*)pArgs))
    {
        wprintf(L"Format message failed with 0x%x\n", GetLastError());
        return;
    }

    // Buffer contains "  Bi Bob   Bill".
    wprintf(L"Formatted message: %s\n", buffer);
}


Im folgenden Beispiel wird gezeigt, wie Sie das vorherige Beispiel mithilfe von va_list implementieren.

#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>
#include <stdio.h>

LPWSTR GetFormattedMessage(LPWSTR pMessage, ...);

void main(void)
{
    LPWSTR pBuffer = NULL;
    LPWSTR pMessage = L"%1!*.*s! %3 %4!*s!";

    // The variable length arguments correspond directly to the format
    // strings in pMessage.
    pBuffer = GetFormattedMessage(pMessage, 4, 2, L"Bill", L"Bob", 6, L"Bill");
    if (pBuffer)
    {
        // Buffer contains "  Bi Bob   Bill".
        wprintf(L"Formatted message: %s\n", pBuffer);
        LocalFree(pBuffer);
    }
    else
    {
        wprintf(L"Format message failed with 0x%x\n", GetLastError());
    }
}

// Formats a message string using the specified message and variable
// list of arguments.
LPWSTR GetFormattedMessage(LPWSTR pMessage, ...)
{
    LPWSTR pBuffer = NULL;

    va_list args = NULL;
    va_start(args, pMessage);

    FormatMessage(FORMAT_MESSAGE_FROM_STRING |
                  FORMAT_MESSAGE_ALLOCATE_BUFFER,
                  pMessage, 
                  0,
                  0,
                  (LPWSTR)&pBuffer, 
                  0, 
                  &args);

    va_end(args);

    return pBuffer;
}

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows XP [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile winbase.h (Windows.h einschließen)
Bibliothek Kernel32.lib
DLL Kernel32.dll

Siehe auch

Fehlerbehandlungsfunktionen

Meldungs-Compiler

Meldungstabellen