Funzione FormatMessageW (winbase.h)
Formatta una stringa di messaggio. La funzione richiede una definizione di messaggio come input. La definizione del messaggio può provenire da un buffer passato alla funzione. Può provenire da una risorsa tabella messaggi in un modulo già caricato. In alternativa, il chiamante può chiedere alla funzione di cercare la definizione del messaggio nelle risorse della tabella dei messaggi del sistema. La funzione trova la definizione del messaggio in una risorsa di tabella dei messaggi in base a un identificatore di messaggio e a un identificatore di lingua. La funzione copia il testo del messaggio formattato in un buffer di output, elaborando eventuali sequenze di inserimento incorporate, se richiesto.
Sintassi
DWORD FormatMessageW(
[in] DWORD dwFlags,
[in, optional] LPCVOID lpSource,
[in] DWORD dwMessageId,
[in] DWORD dwLanguageId,
[out] LPWSTR lpBuffer,
[in] DWORD nSize,
[in, optional] va_list *Arguments
);
Parametri
[in] dwFlags
Le opzioni di formattazione e come interpretare il parametro lpSource
Questo parametro può essere uno o più dei valori seguenti.
Valore | Significato |
---|---|
|
La funzione alloca un buffer sufficientemente grande da contenere il messaggio formattato e inserisce un puntatore al buffer allocato all'indirizzo specificato da lpBuffer. Il parametro lpBuffer Se la lunghezza del messaggio formattato supera i 128.000 byte, FormatMessage avrà esito negativo e una chiamata successiva a GetLastError restituirà ERROR_MORE_DATA. Nelle versioni precedenti di Windows questo valore non era disponibile per l'uso durante la compilazione di app di Windows Store. A partire da Windows 10 questo valore può essere usato. Windows Server 2003 e Windows XP: Se la lunghezza del messaggio formattato supera i 128.000 byte, FormatMessage non avrà esito negativo automaticamente con un errore di ERROR_MORE_DATA. |
|
Il parametro arguments Questo flag non può essere usato con valori integer a 64 bit. Se si usa un numero intero a 64 bit, è necessario usare la struttura va_list. |
|
Il parametro lpSource Se il modulo non dispone di alcuna risorsa di tabella messaggi, la funzione ha esito negativo con ERROR_RESOURCE_TYPE_NOT_FOUND. |
|
Il parametro lpSource |
|
La funzione deve cercare il messaggio richiesto nelle risorse della tabella messaggi di sistema. Se questo flag viene specificato con FORMAT_MESSAGE_FROM_HMODULE, la funzione cerca nella tabella dei messaggi di sistema se il messaggio non viene trovato nel modulo specificato da lpSource. Questo flag non può essere usato con FORMAT_MESSAGE_FROM_STRING.
Se si specifica questo flag, un'applicazione può passare il risultato della funzione GetLastError |
|
Le sequenze di inserimento nella definizione del messaggio, ad esempio %1, devono essere ignorate e passate al buffer di output invariate. Questo flag è utile per recuperare un messaggio per la formattazione successiva. Se questo flag è impostato, il parametro Arguments viene ignorato. |
Il byte basso di dwFlags può specificare la larghezza massima di una riga di output formattata. Di seguito sono riportati i valori possibili del byte con ordine basso.
Se il byte con ordine basso è un valore diverso da zero diverso da FORMAT_MESSAGE_MAX_WIDTH_MASK, specifica il numero massimo di caratteri in una riga di output. La funzione ignora le interruzioni di riga regolari nel testo della definizione del messaggio. La funzione non divide mai una stringa delimitata da spazi vuoti in un'interruzione di riga. La funzione archivia le interruzioni di riga hardcoded nel testo della definizione del messaggio nel buffer di output. Le interruzioni di riga hardcoded vengono codificate con la sequenza di escape %n.
[in, optional] lpSource
Posizione della definizione del messaggio. Il tipo di questo parametro dipende dalle impostazioni nel parametro dwFlags.
Se nessuno di questi flag è impostato in dwFlags, lpSource viene ignorato.
[in] dwMessageId
Identificatore del messaggio richiesto. Questo parametro viene ignorato se
[in] dwLanguageId
Identificatore di lingua per il messaggio richiesto. Questo parametro viene ignorato se
Se si passa un LANGID
- Lingua neutra
- Thread LANGID, in base al valore delle impostazioni locali del thread
- Impostazione predefinita dell'utente LANGID, in base al valore delle impostazioni locali predefinito dell'utente
- Impostazione predefinita del sistema LANGID, in base al valore delle impostazioni locali predefinito del sistema
- Inglese (Stati Uniti)
[out] lpBuffer
Puntatore a un buffer che riceve la stringa con terminazione Null che specifica il messaggio formattato. Se
Questo buffer non può essere maggiore di 64.000 byte.
[in] nSize
Se il flag FORMAT_MESSAGE_ALLOCATE_BUFFER non è impostato, questo parametro specifica le dimensioni del buffer di output, in TCHAR. Se FORMAT_MESSAGE_ALLOCATE_BUFFER è impostato, questo parametro specifica il numero minimo di TCHAR da allocare per un buffer di output.
Il buffer di output non può essere maggiore di 64.000 byte.
[in, optional] Arguments
Matrice di valori utilizzati come valori di inserimento nel messaggio formattato. Una %1 nella stringa di formato indica il primo valore nella matrice argomenti
L'interpretazione di ogni valore dipende dalle informazioni di formattazione associate all'inserimento nella definizione del messaggio. Il valore predefinito consiste nel considerare ogni valore come puntatore a una stringa con terminazione Null.
Per impostazione predefinita, il parametro Arguments è di tipo va_list*, che è un tipo di dati specifico del linguaggio e dell'implementazione per descrivere un numero variabile di argomenti. Lo stato dell'argomento va_list non è definito quando viene restituito dalla funzione . Per usare nuovamente il va_list, eliminare definitivamente il puntatore all'elenco di argomenti delle variabili usando va_end e reinizializzarlo con va_start.
Se non si dispone di un puntatore di tipo va_list*, specificare il flag FORMAT_MESSAGE_ARGUMENT_ARRAY e passare un puntatore a una matrice di valori DWORD_PTR; tali valori sono input per il messaggio formattato come valori di inserimento. Ogni inserimento deve avere un elemento corrispondente nella matrice.
Valore restituito
Se la funzione ha esito positivo, il valore restituito è il numero di TCHAR archiviati nel buffer di output, escluso il carattere Null di terminazione.
Se la funzione ha esito negativo, il valore restituito è zero. Per ottenere informazioni estese sull'errore, chiamare GetLastError.
Osservazioni
All'interno del testo del messaggio sono supportate diverse sequenze di escape per la formattazione dinamica del messaggio. Queste sequenze di escape e i relativi significati sono illustrate nelle tabelle seguenti. Tutte le sequenze di escape iniziano con il carattere percentuale (%).
Sequenza di escape | Significato |
---|---|
%0 | Termina una riga di testo del messaggio senza un carattere di nuova riga finale. Questa sequenza di escape può essere usata per creare lunghe righe o per terminare il messaggio stesso senza un carattere di nuova riga finale. È utile per i messaggi di richiesta. |
% n!stringa di formato! |
Identifica una sequenza di inserimento. Il valore di n può essere compreso nell'intervallo compreso tra 1 e 99. La stringa di formato (che deve essere racchiusa tra punti esclamativi) è facoltativa e l'impostazione predefinita è !s! se non specificato. Per altre informazioni, vedere Format Specification Fields.
La stringa di formato può includere un identificatore di larghezza e precisione per le stringhe e un identificatore di larghezza per i numeri interi. Usare un asterisco () per specificare la larghezza e la precisione. Ad esempio, %1!.*s! o %1!*u!. Se non si usano gli identificatori di larghezza e precisione, i numeri di inserimento corrispondono direttamente agli argomenti di input. Ad esempio, se la stringa di origine è "%1 %2 %1" e gli argomenti di input sono "Bill" e "Bob", la stringa di output formattata è "Bill Bob Bill". Tuttavia, se si utilizza un identificatore di larghezza e precisione, i numeri di inserimento non corrispondono direttamente agli argomenti di input. Ad esempio, i numeri di inserimento per l'esempio precedente potrebbero cambiare in "%1!*.*s! %4 %5!*s!". I numeri di inserimento dipendono dal fatto che si usi una matrice di argomenti (FORMAT_MESSAGE_ARGUMENT_ARRAY) o un va_list. Per una matrice di argomenti, il numero di inserimento successivo è n+2 se la stringa di formato precedente contiene un asterisco e viene n+3 se sono stati specificati due asterischi. Per un va_list, il numero di inserimento successivo è n+1 se la stringa di formato precedente contiene un asterisco e è n+2 se sono stati specificati due asterischi. Se si vuole ripetere "Bill", come nell'esempio precedente, gli argomenti devono includere "Bill" due volte. Ad esempio, se la stringa di origine è "%1!*.*s! %4 %5!*s!", gli argomenti potrebbero essere, 4, 2, Bill, Bob, 6, Bill (se si usa il flag FORMAT_MESSAGE_ARGUMENT_ARRAY). La stringa formattata sarebbe quindi " Bi Bob Bill". I numeri di inserimento ripetuti quando la stringa di origine contiene identificatori di larghezza e precisione potrebbero non restituire i risultati previsti. Se è stata sostituita %5 con %1, la funzione tenterebbe di stampare una stringa all'indirizzo 6 (probabilmente causando una violazione di accesso). Gli identificatori di formato a virgola mobile, ad esempio E, f e g, non sono supportati.
La soluzione alternativa consiste nell'usare la funzione StringCchPrintf Gli inserimenti che usano il prefisso I64 vengono considerati come due argomenti a 32 bit. Devono essere usati prima dell'utilizzo degli argomenti successivi. Si noti che potrebbe essere più semplice usare StringCchPrintf anziché questo prefisso. |
Qualsiasi altro carattere nondigit dopo un carattere percentuale viene formattato nel messaggio di output senza il carattere percentuale. Di seguito sono riportati alcuni esempi.
Stringa di formato | Output risultante |
---|---|
%% | Single Sign-On. |
% spazio | Uno spazio singolo. Questa stringa di formato può essere usata per garantire il numero appropriato di spazi finali in una riga di testo del messaggio. |
%. | Un singolo punto. Questa stringa di formato può essere utilizzata per includere un singolo punto all'inizio di una riga senza terminare la definizione di testo del messaggio. |
%! | Punto esclamativo singolo. Questa stringa di formato può essere utilizzata per includere un punto esclamativo immediatamente dopo un inserimento senza che venga scambiato per l'inizio di una stringa di formato. |
%n | Interruzione di riga rigida quando la stringa di formato si verifica alla fine di una riga. Questa stringa di formato è utile quando FormatMessage fornisce interruzioni di riga regolari in modo che il messaggio si adatti a una certa larghezza. |
%r | Ritorno a capo fisso senza un carattere di nuova riga finale. |
%t | Una singola scheda. |
osservazioni sulla sicurezza
Se questa funzione viene chiamata senza FORMAT_MESSAGE_IGNORE_INSERTS, il parametro Arguments deve contenere parametri sufficienti per soddisfare tutte le sequenze di inserimento nella stringa del messaggio e devono essere del tipo corretto. Pertanto, non usare stringhe di messaggio non attendibili o sconosciute con inserimenti abilitati perché possono contenere più sequenze di inserimento rispetto a argomenti fornisce o quelli che potrebbero essere di tipo errato. In particolare, non è sicuro accettare un codice di errore di sistema arbitrario restituito da un'API e usare FORMAT_MESSAGE_FROM_SYSTEM senza FORMAT_MESSAGE_IGNORE_INSERTS.Esempi
La funzione FormatMessage
#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);
}
Nell'esempio seguente viene illustrato come implementare l'esempio precedente usando va_list.
#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;
}
Nota
L'intestazione winbase.h definisce FormatMessage come alias che seleziona automaticamente la versione ANSI o Unicode di questa funzione in base alla definizione della costante del preprocessore UNICODE. La combinazione dell'utilizzo dell'alias indipendente dalla codifica con il codice non indipendente dalla codifica può causare mancate corrispondenze che generano errori di compilazione o di runtime. Per altre informazioni, vedere convenzioni di per i prototipi di funzioni.
Fabbisogno
Requisito | Valore |
---|---|
client minimo supportato | Windows XP [app desktop | App UWP] |
server minimo supportato | Windows Server 2003 [app desktop | App UWP] |
piattaforma di destinazione | Finestre |
intestazione |
winbase.h (include Windows.h) |
libreria |
Kernel32.lib |
dll | Kernel32.dll |
Vedere anche
funzioni di gestione degli errori
del compilatore di messaggi
Tabelle dei messaggi