FormatMessageA-Funktion (winbase.h)
Formatiert eine Nachrichtenzeichenfolge. Für die Funktion ist eine Nachrichtendefinition als Eingabe erforderlich. 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 Nachrichtentabellenressource(n) des Systems nach der Nachrichtendefinition zu durchsuchen. Die Funktion findet 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 FormatMessageA(
[in] DWORD dwFlags,
[in, optional] LPCVOID lpSource,
[in] DWORD dwMessageId,
[in] DWORD dwLanguageId,
[out] LPSTR lpBuffer,
[in] DWORD nSize,
[in, optional] va_list *Arguments
);
Parameter
[in] dwFlags
Die Formatierungsoptionen und die Interpretation des lpSource--Parameters. Das Byte mit niedriger Reihenfolge von dwFlags gibt an, wie die Funktion Zeilenumbrüche im Ausgabepuffer behandelt. Das Byte mit niedriger Reihenfolge kann auch die maximale Breite einer formatierten Ausgabezeile angeben.
Dieser Parameter kann einen oder mehrere der folgenden Werte sein.
Wert | Bedeutung |
---|---|
|
Die Funktion weist einen Puffer groß genug für die formatierte Nachricht zu und platziert einen Zeiger auf den zugewiesenen Puffer an der durch lpBufferangegebenen Adresse. Der lpBuffer Parameter ist ein Zeiger auf eine LPTSTR-; Sie müssen den Zeiger in eine LPTSTR- umwandeln (z. B. (LPTSTR)&lpBuffer ). Der nSize-Parameter gibt die Mindestanzahl TCHARs an, die für einen Ausgabenachrichtenpuffer zugewiesen werden sollen. Der Aufrufer sollte die funktion LocalFree verwenden, um den Puffer frei zu geben, wenn er nicht mehr benötigt wird.
Wenn die Länge der formatierten Nachricht 128 KB überschreitet, schlägt FormatMessage- fehl, und ein anschließender Aufruf von GetLastError gibt ERROR_MORE_DATAzurü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 KB überschreitet, schlägt FormatMessage- nicht automatisch mit einem Fehler von ERROR_MORE_DATAfehl. |
|
Die 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 64-Bit-Ganzzahl verwenden, müssen Sie die va_list Struktur verwenden. |
|
Der lpSource Parameter ist ein Modulhandle, das die zu durchsuchenden Nachrichtentabellenressourcen enthält. Wenn dieses lpSource- Handle NULL-ist, wird die Anwendungsbilddatei des aktuellen Prozesses durchsucht. Dieses Flag kann nicht mit FORMAT_MESSAGE_FROM_STRINGverwendet werden.
Wenn das Modul keine Nachrichtentabellenressource aufweist, schlägt die Funktion mit ERROR_RESOURCE_TYPE_NOT_FOUNDfehl. |
|
Der lpSource--Parameter ist ein Zeiger auf eine mit Null beendete Zeichenfolge, die eine Nachrichtendefinition enthält. Die Nachrichtendefinition enthält möglicherweise Einfügesequenzen, genau wie der Nachrichtentext in einer Nachrichtentabellenressource. Dieses Kennzeichen kann nicht mit FORMAT_MESSAGE_FROM_HMODULE oder FORMAT_MESSAGE_FROM_SYSTEMverwendet werden. |
|
Die Funktion sollte die Systemnachrichtentabellenressource(n) nach der angeforderten Nachricht durchsuchen. Wenn dieses Flag mit FORMAT_MESSAGE_FROM_HMODULEangegeben wird, durchsucht die Funktion die Systemnachrichtentabelle, wenn die Nachricht nicht im modul gefunden wird, das durch lpSourceangegeben wird. Dieses Flag kann nicht mit FORMAT_MESSAGE_FROM_STRINGverwendet werden.
Wenn dieses Flag angegeben ist, kann eine Anwendung das Ergebnis der GetLastError-Funktion übergeben, um den Nachrichtentext für einen systemdefinierten Fehler abzurufen. |
|
Einfügen von Sequenzen in die Nachrichtendefinition, z. B. %1, werden ignoriert und unverändert an den Ausgabepuffer übergeben. Dieses Kennzeichen ist nützlich, um eine Nachricht für spätere Formatierungen abzurufen. Wenn dieses Kennzeichen festgelegt ist, werden die Argumente Parameter ignoriert. |
Das Byte mit niedriger Reihenfolge von dwFlags kann die maximale Breite einer formatierten Ausgabelinie angeben. Es folgen mögliche Werte des Byte mit niedriger Reihenfolge.
Wenn das Byte mit niedriger Reihenfolge ein anderer Wert als FORMAT_MESSAGE_MAX_WIDTH_MASKist, gibt es die maximale Anzahl von Zeichen in einer Ausgabezeile an. Die Funktion ignoriert normale Zeilenumbrüche im Nachrichtendefinitionstext. Die Funktion teilt niemals eine Zeichenfolge, die durch Leerzeichen durch einen Zeilenumbruch getrennt ist. Die Funktion speichert hartcodierte Zeilenumbrüche im Nachrichtendefinitionstext im Ausgabepuffer. Hartcodierte Zeilenumbrüche werden mit der %n Escapesequenz codiert.
[in, optional] lpSource
Der Speicherort der Nachrichtendefinition. Der Typ dieses Parameters hängt von den Einstellungen im dwFlags Parameter ab.
Wenn keine dieser Flags in dwFlagsfestgelegt wird, wird lpSource- ignoriert.
[in] dwMessageId
Der Nachrichtenbezeichner für die angeforderte Nachricht. Dieser Parameter wird ignoriert, wenn dwFlags-FORMAT_MESSAGE_FROM_STRINGenthält.
[in] dwLanguageId
Der Sprachbezeichner für die angeforderte Nachricht. Dieser Parameter wird ignoriert, wenn dwFlags-FORMAT_MESSAGE_FROM_STRINGenthält.
Wenn Sie eine bestimmte LANGID- in diesem Parameter übergeben, gibt FormatMessage- nur eine Nachricht für diese LANGID- zurück. Wenn die Funktion für diese LANGID-keine Meldung finden kann, wird Last-Error auf ERROR_RESOURCE_LANG_NOT_FOUNDfestgelegt. Wenn Sie null übergeben, sucht FormatMessage- in der folgenden Reihenfolge nach einer Nachricht für LANGIDs:
- Sprache neutral
- Thread-LANGID-, basierend auf dem Gebietsschemawert des Threads
- Benutzerstandard LANGID-basierend auf dem Standardgebietsschemawert des Benutzers
- Systemstandard-LANGID-basierend auf dem Systemstandardgebietsschemawert
- US-Englisch
[out] lpBuffer
Ein Zeiger auf einen Puffer, der die mit Null beendete Zeichenfolge empfängt, die die formatierte Nachricht angibt. Wenn dwFlags-FORMAT_MESSAGE_ALLOCATE_BUFFERenthält, weist die Funktion einen Puffer mithilfe der LocalAlloc--Funktion zu und platziert den Zeiger an der adresse, die in lpBufferangegeben ist.
Dieser Puffer darf nicht größer als 64 KB sein.
[in] nSize
Wenn das FORMAT_MESSAGE_ALLOCATE_BUFFER Flag nicht festgelegt ist, gibt dieser Parameter die Größe des Ausgabepuffers in TCHARsan. Wenn FORMAT_MESSAGE_ALLOCATE_BUFFER festgelegt ist, gibt dieser Parameter die Mindestanzahl der TCHARs an, die für einen Ausgabepuffer zugewiesen werden sollen.
Der Ausgabepuffer darf nicht größer als 64 KB 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 Arguments Array an; ein %2 gibt das zweite Argument an; Und so weiter.
Die Interpretation der einzelnen Werte hängt von den Formatierungsinformationen ab, die dem Einfügen in der Nachrichtendefinition zugeordnet sind. Standardmäßig wird jeder Wert als Zeiger auf eine mit Null beendete Zeichenfolge behandelt.
Standardmäßig ist der Arguments Parameter vom Typ va_list*, ein sprach- und implementierungsspezifischer Datentyp zur Beschreibung einer variablen Anzahl von Argumenten. Der Status des arguments va_list ist nicht definiert, wenn es von der Funktion zurückgegeben wird. Um die va_list erneut zu verwenden, zerstören Sie den Variablenargumentlistenzeiger mit va_end, und initialisieren Sie ihn mit va_starterneut.
Wenn Sie keinen Zeiger vom Typ va_list*haben, geben Sie das FORMAT_MESSAGE_ARGUMENT_ARRAY Flag an und übergeben einen Zeiger an ein Array von DWORD_PTR Werten; diese Werte werden in die Nachricht eingegeben, die als Einfügewerte formatiert ist. Jedes Einfügen muss über ein entsprechendes Element im Array verfügen.
Rückgabewert
Wenn die Funktion erfolgreich ist, ist der Rückgabewert die Anzahl der TCHARs im Ausgabepuffer gespeichert, mit Ausnahme des endenden NULL-Zeichens.
Wenn die Funktion fehlschlägt, ist der Rückgabewert null. Rufen Sie GetLastErrorauf, um erweiterte Fehlerinformationen zu erhalten.
Bemerkungen
Innerhalb des Nachrichtentexts werden mehrere Escapesequenzen unterstützt, um die Nachricht dynamisch zu formatieren. Diese Escapesequenzen und ihre Bedeutungen werden in den folgenden Tabellen gezeigt. Alle Escapesequenzen beginnen mit dem Prozentzeichen (%).
Escape-Sequenz | Bedeutung |
---|---|
%0 | Beendet eine Nachrichtentextzeile ohne nachfolgendes neue Zeilenzeichen. Diese Escapesequenz kann verwendet werden, um lange Zeilen zu erstellen oder die Nachricht selbst ohne nachfolgendes neues Zeilenzeichen zu beenden. Dies ist nützlich für Eingabeaufforderungen von Nachrichten. |
% n!Formatzeichenfolge! |
Identifiziert eine Einfügesequenz. Der Wert von n kann zwischen 1 und 99 liegen. Die Formatzeichenfolge (die von Ausrufezeichen umgeben sein muss) ist optional und standardmäßig auf !s! wenn nicht angegeben. Weitere Informationen finden Sie unter Formatspezifikationsfelder.
Die Formatzeichenfolge kann einen Breiten- und Genauigkeitsbezeichner 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 Genauigkeitsbezeichner nicht verwenden, entsprechen die Einfügenummern 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 Genauigkeitsbezeichner verwenden, entsprechen die Einfügenummern nicht direkt den Eingabeargumenten. Beispielsweise könnte sich das Einfügen von Zahlen für das vorherige Beispiel 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_listverwenden. Bei einem Argumentarray ist die nächste Einfügenummer n+2, wenn die vorherige Formatzeichenfolge ein Sternchen enthielt und n+3 ist, wenn zwei Sternchen angegeben wurden. Bei einem va_listist die nächste Einfügenummer n+1, wenn die vorherige Formatzeichenfolge ein Sternchen enthielt und n+2 ist, wenn zwei Sternchen angegeben wurden. Wenn Sie "Rechnung" wiederholen möchten, wie im vorherigen Beispiel, müssen die Argumente zweimal "Rechnung" enthalten. Beispiel: Wenn die Quellzeichenfolge "%1!*.*s! %4 %5!*s!" könnten die Argumente sein, 4, 2, Bill, Bob, 6, Bill (wenn die FORMAT_MESSAGE_ARGUMENT_ARRAY Kennzeichnung verwendet wird). Die formatierte Zeichenfolge lautet dann "Bi Bob Bill". Wiederholtes Einfügen von Zahlen, wenn die Quellzeichenfolge Breite und Genauigkeitsbezeichner enthält, liefern möglicherweise nicht die vorgesehenen Ergebnisse. Wenn Sie %5 durch %1ersetzt haben, würde die Funktion versuchen, eine Zeichenfolge unter Adresse 6 zu drucken (wahrscheinlich zu einer Zugriffsverletzung). 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. Verwenden Sie diesen Puffer dann als Einfügezeichenfolge. Fügt ein, 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. Im Folgenden sind einige Beispiele aufgeführt.
Formatzeichenfolge | Resultierende Ausgabe |
---|---|
%% | Ein einzelnes Prozentzeichen. |
% | Ein einzelnes Leerzeichen. Diese Formatzeichenfolge kann verwendet werden, um sicherzustellen, dass die entsprechende Anzahl von nachgestellten Leerzeichen in einer Nachrichtentextzeile vorhanden ist. |
%. | 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 einem Einfügen einzuschließen, ohne dass er für den Anfang einer Formatzeichenfolge falsch ist. |
%n | Ein harter Zeilenumbruch, wenn die Formatzeichenfolge am Ende einer Zeile auftritt. Diese Formatzeichenfolge ist nützlich, wenn FormatMessage- normale Zeilenumbrüche liefert, sodass die Nachricht in eine bestimmte Breite passt. |
%r | Eine harte Wagenrücklauf ohne nachfolgendes Zeilenumbruchzeichen. |
%t | Eine einzelne Registerkarte. |
Sicherheitsmerkungen
Wenn diese Funktion ohne FORMAT_MESSAGE_IGNORE_INSERTSaufgerufen wird, muss der parameter Arguments genügend Parameter enthalten, um alle Einfügesequenzen in der Nachrichtenzeichenfolge zu erfüllen, und sie müssen vom richtigen Typ sein. Verwenden Sie daher keine nicht vertrauenswürdigen oder unbekannten Meldungszeichenfolgen mit aktivierten Einfügungen, da sie mehr Einfügesequenzen enthalten können als Argumente, die bereitstellt, oder solche, die vom falschen Typ sein können. Insbesondere ist es unsicher, einen beliebigen Systemfehlercode aus einer API zurückzugeben und FORMAT_MESSAGE_FROM_SYSTEM ohne FORMAT_MESSAGE_IGNORE_INSERTSzu verwenden.Beispiele
Die FormatMessage--Funktion kann verwendet werden, um Fehlermeldungszeichenfolgen für die systemfehlercodes abzurufen, die von GetLastErrorzurückgegeben werden. Ein Beispiel finden Sie unter Abrufen des Last-Error Code-.
Das folgende Beispiel zeigt, wie Sie ein Argumentarray und die Breite und Genauigkeitsbezeichner verwenden.#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);
}
Das folgende Beispiel zeigt, wie Sie das vorherige Beispiel mithilfe von va_listimplementieren.
#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;
}
Anmerkung
Der winbase.h-Header definiert FormatMessage als Alias, der die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante automatisch auswählt. Das Mischen der Verwendung des codierungsneutralen Alias mit Code, der nicht codierungsneutral ist, kann zu Nichtübereinstimmungen führen, die zu Kompilierungs- oder Laufzeitfehlern führen. Weitere Informationen finden Sie unter Konventionen für Funktionsprototypen.
Anforderungen
Anforderung | Wert |
---|---|
mindestens unterstützte Client- | Windows XP [Desktop-Apps | UWP-Apps] |
mindestens unterstützte Server- | Windows Server 2003 [Desktop-Apps | UWP-Apps] |
Zielplattform- | Fenster |
Header- | winbase.h (enthalten Windows.h) |
Library | Kernel32.lib |
DLL- | Kernel32.dll |
Siehe auch
Nachrichtentabellen