Partager via


FormatMessageW, fonction (winbase.h)

Met en forme une chaîne de message. La fonction nécessite une définition de message en tant qu’entrée. La définition du message peut provenir d’une mémoire tampon passée dans la fonction. Il peut provenir d’une ressource de table de messages dans un module déjà chargé. Ou l’appelant peut demander à la fonction de rechercher la ou les ressources de la table de messages du système pour la définition du message. La fonction recherche la définition du message dans une ressource de table de messages en fonction d’un identificateur de message et d’un identificateur de langue. La fonction copie le texte du message mis en forme dans une mémoire tampon de sortie, en traitant les séquences d’insertion incorporées si demandées.

Syntaxe

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
);

Paramètres

[in] dwFlags

Options de mise en forme et comment interpréter le paramètre lpSource. L’octet de faible ordre de dwFlags spécifie comment la fonction gère les sauts de ligne dans la mémoire tampon de sortie. L’octet de faible ordre peut également spécifier la largeur maximale d’une ligne de sortie mise en forme.

Ce paramètre peut être une ou plusieurs des valeurs suivantes.

Valeur Signification
FORMAT_MESSAGE_ALLOCATE_BUFFER
0x00000100
La fonction alloue une mémoire tampon suffisamment grande pour contenir le message mis en forme et place un pointeur vers la mémoire tampon allouée à l’adresse spécifiée par lpBuffer. Le paramètre lpBuffer est un pointeur vers un LPTSTR; vous devez convertir le pointeur en LPTSTR (par exemple, (LPTSTR)&lpBuffer). Le paramètre nSize spécifie le nombre minimal d'TCHAR à allouer pour une mémoire tampon de message de sortie. L’appelant doit utiliser la fonction LocalFree pour libérer la mémoire tampon lorsqu’elle n’est plus nécessaire.

Si la longueur du message mis en forme dépasse 128 000 octets, FormatMessage échoue et un appel ultérieur à GetLastError retourne ERROR_MORE_DATA.

Dans les versions précédentes de Windows, cette valeur n’était pas disponible pour être utilisée lors de la compilation d’applications du Windows Store. À compter de Windows 10, cette valeur peut être utilisée.

Windows Server 2003 et Windows XP :

Si la longueur du message mis en forme dépasse 128 000 octets, formatMessage ne échoue pas automatiquement avec une erreur de ERROR_MORE_DATA.

FORMAT_MESSAGE_ARGUMENT_ARRAY
0x00002000
Le paramètre arguments n’est pas une structure va_list, mais est un pointeur vers un tableau de valeurs qui représentent les arguments.

Cet indicateur ne peut pas être utilisé avec des valeurs entières 64 bits. Si vous utilisez un entier 64 bits, vous devez utiliser la structure va_list.

FORMAT_MESSAGE_FROM_HMODULE
0x00000800
Le paramètre lpSource est un handle de module contenant les ressources de table de messages à rechercher. Si ce handle lpSource est NULL, le fichier image de l’application du processus actuel est recherché. Cet indicateur ne peut pas être utilisé avec FORMAT_MESSAGE_FROM_STRING.

Si le module n’a aucune ressource de table de messages, la fonction échoue avec ERROR_RESOURCE_TYPE_NOT_FOUND.

FORMAT_MESSAGE_FROM_STRING
0x00000400
Le paramètre lpSource est un pointeur vers une chaîne terminée par null qui contient une définition de message. La définition du message peut contenir des séquences d’insertion, tout comme le texte du message dans une ressource de table de messages. Cet indicateur ne peut pas être utilisé avec FORMAT_MESSAGE_FROM_HMODULE ou FORMAT_MESSAGE_FROM_SYSTEM.
FORMAT_MESSAGE_FROM_SYSTEM
0x00001000
La fonction doit rechercher la ou les ressources de table de messages système pour le message demandé. Si cet indicateur est spécifié avec FORMAT_MESSAGE_FROM_HMODULE, la fonction recherche la table de messages système si le message est introuvable dans le module spécifié par lpSource. Cet indicateur ne peut pas être utilisé avec FORMAT_MESSAGE_FROM_STRING.

Si cet indicateur est spécifié, une application peut transmettre le résultat de la fonction GetLastError pour récupérer le texte du message pour une erreur définie par le système.

FORMAT_MESSAGE_IGNORE_INSERTS
0x00000200
Les séquences d’insertion dans la définition du message, telles que %1, doivent être ignorées et transmises à la mémoire tampon de sortie inchangée. Cet indicateur est utile pour récupérer un message pour une mise en forme ultérieure. Si cet indicateur est défini, le paramètre Arguments est ignoré.
 

L’octet de faible ordre de dwFlags peut spécifier la largeur maximale d’une ligne de sortie mise en forme. Voici les valeurs possibles de l’octet de faible ordre.

Valeur Signification
0
Il n’existe aucune restriction de largeur de ligne de sortie. La fonction stocke les sauts de ligne qui se trouvent dans le texte de définition de message dans la mémoire tampon de sortie.
FORMAT_MESSAGE_MAX_WIDTH_MASK
0x000000FF
La fonction ignore les sauts de ligne réguliers dans le texte de définition de message. La fonction stocke les sauts de ligne codés en dur dans le texte de définition de message dans la mémoire tampon de sortie. La fonction ne génère aucun nouveau saut de ligne.
 

Si l’octet de faible ordre est une valeur différente de FORMAT_MESSAGE_MAX_WIDTH_MASK, elle spécifie le nombre maximal de caractères dans une ligne de sortie. La fonction ignore les sauts de ligne réguliers dans le texte de définition de message. La fonction ne fractionne jamais une chaîne délimitée par un espace blanc sur un saut de ligne. La fonction stocke les sauts de ligne codés en dur dans le texte de définition de message dans la mémoire tampon de sortie. Les sauts de ligne codés en dur sont codés avec la séquence d’échappement %n.

[in, optional] lpSource

Emplacement de la définition du message. Le type de ce paramètre dépend des paramètres du paramètre dwFlags.

paramètre de dwFlags Signification
FORMAT_MESSAGE_FROM_HMODULE
0x00000800
Handle du module qui contient la table de messages à rechercher.
FORMAT_MESSAGE_FROM_STRING
0x00000400
Pointeur vers une chaîne qui se compose d’un texte de message non mis en forme. Il sera analysé pour les insertions et mis en forme en conséquence.
 

Si aucun de ces indicateurs n’est défini dans dwFlags, lpSource est ignoré.

[in] dwMessageId

Identificateur du message demandé. Ce paramètre est ignoré si dwFlags inclut FORMAT_MESSAGE_FROM_STRING.

[in] dwLanguageId

Identificateur de langue pour le message demandé. Ce paramètre est ignoré si dwFlags inclut FORMAT_MESSAGE_FROM_STRING.

Si vous transmettez un LANGID spécifique dans ce paramètre, formatMessage retourne un message pour ce LANGID uniquement. Si la fonction ne trouve pas de message pour ceLANGID , elle définit Last-Error sur ERROR_RESOURCE_LANG_NOT_FOUND. Si vous passez zéro, FormatMessage recherche un message pour LANGIDs dans l’ordre suivant :

  1. Neutre en langue
  2. Thread LANGID, en fonction de la valeur des paramètres régionaux du thread
  3. LANGID par défaut de l’utilisateur , en fonction de la valeur de paramètres régionaux par défaut de l’utilisateur
  4. Valeur par défaut du système LANGID, en fonction de la valeur de paramètres régionaux par défaut du système
  5. Anglais des États-Unis
Si formatMessage ne localise pas de message pour l’un des LANGID précédents, il retourne toute chaîne de message de langue présente. En cas d’échec, elle retourne ERROR_RESOURCE_LANG_NOT_FOUND.

[out] lpBuffer

Pointeur vers une mémoire tampon qui reçoit la chaîne terminée par null qui spécifie le message mis en forme. Si dwFlags inclut FORMAT_MESSAGE_ALLOCATE_BUFFER, la fonction alloue une mémoire tampon à l’aide de la fonction LocalAlloc et place le pointeur vers la mémoire tampon à l’adresse spécifiée dans lpBuffer.

Cette mémoire tampon ne peut pas être supérieure à 64 000 octets.

[in] nSize

Si l’indicateur FORMAT_MESSAGE_ALLOCATE_BUFFER n’est pas défini, ce paramètre spécifie la taille de la mémoire tampon de sortie, dans TCHAR. Si FORMAT_MESSAGE_ALLOCATE_BUFFER est défini, ce paramètre spécifie le nombre minimal d'TCHAR à allouer pour une mémoire tampon de sortie.

La mémoire tampon de sortie ne peut pas être supérieure à 64 000 octets.

[in, optional] Arguments

Tableau de valeurs utilisées comme valeurs d’insertion dans le message mis en forme. Une %1 dans la chaîne de format indique la première valeur du tableau arguments  ; un %2 indique le deuxième argument ; et ainsi de suite.

L’interprétation de chaque valeur dépend des informations de mise en forme associées à l’insertion dans la définition du message. La valeur par défaut consiste à traiter chaque valeur comme pointeur vers une chaîne terminée par null.

Par défaut, le paramètre arguments est de type va_list*, qui est un type de données spécifique à la langue et à l’implémentation pour décrire un nombre variable d’arguments. L’état de l’argument va_list n’est pas défini lors du retour de la fonction. Pour utiliser à nouveau le va_list, détruisez le pointeur de liste d’arguments variables à l’aide de va_end et réinitialisez-le avec va_start.

Si vous n’avez pas de pointeur de type va_list*, spécifiez l’indicateur FORMAT_MESSAGE_ARGUMENT_ARRAY et transmettez un pointeur à un tableau de valeurs DWORD_PTR ; ces valeurs sont entrées dans le message mis en forme comme valeurs d’insertion. Chaque insertion doit avoir un élément correspondant dans le tableau.

Valeur de retour

Si la fonction réussit, la valeur de retour est le nombre d'TCHAR stockées dans la mémoire tampon de sortie, à l’exclusion du caractère null de fin.

Si la fonction échoue, la valeur de retour est égale à zéro. Pour obtenir des informations d’erreur étendues, appelez GetLastError.

Remarques

Dans le texte du message, plusieurs séquences d’échappement sont prises en charge pour la mise en forme dynamique du message. Ces séquences d’échappement et leurs significations sont présentées dans les tableaux suivants. Toutes les séquences d’échappement commencent par le caractère de pourcentage (%).

Séquence d’échappement Signification
%0 Met fin à une ligne de texte de message sans caractère de ligne de fin. Cette séquence d’échappement peut être utilisée pour créer des lignes longues ou pour mettre fin au message lui-même sans caractère de ligne de fin. Il est utile pour les messages d’invite.
% n!chaîne de format! Identifie une séquence d’insertion. La valeur de n peut être comprise entre 1 et 99. La chaîne de format (qui doit être entourée de marques d’exclamation) est facultative et a la valeur par défaut !s ! s’il n’est pas spécifié. Pour plus d’informations, consultez des champs de spécification de format .

La chaîne de format peut inclure un spécificateur de largeur et de précision pour les chaînes et un spécificateur de largeur pour les entiers. Utilisez un astérisque () pour spécifier la largeur et la précision. Par exemple, %1!.*s ! ou %1!*u !.

Si vous n’utilisez pas les spécificateurs de largeur et de précision, les nombres d’insertion correspondent directement aux arguments d’entrée. Par exemple, si la chaîne source est «%1 %2 %1» et que les arguments d’entrée sont « Bill » et « Bob », la chaîne de sortie mise en forme est « Bill Bob Bill ».

Toutefois, si vous utilisez un spécificateur de largeur et de précision, les nombres d’insertion ne correspondent pas directement aux arguments d’entrée. Par exemple, les nombres d’insertion de l’exemple précédent peuvent passer à «%1!*.*s ! %4 %5!*s !".

Les nombres d’insertion dépendent d’un tableau d’arguments (FORMAT_MESSAGE_ARGUMENT_ARRAY) ou d’un va_list. Pour un tableau d’arguments, le numéro d’insertion suivant est n+2 si la chaîne de format précédente contenait un astérisque et est n+3 si deux astérisques ont été spécifiés. Pour un va_list, le numéro d’insertion suivant est n+1 si la chaîne de format précédente contenait un astérisque et est n+2 si deux astérisques ont été spécifiés.

Si vous souhaitez répéter « Bill », comme dans l’exemple précédent, les arguments doivent inclure « Bill » deux fois. Par exemple, si la chaîne source est «%1!*.*s ! %4 %5!*s !", les arguments pourraient être, 4, 2, Bill, Bob, 6, Bill (si vous utilisez l’indicateur FORMAT_MESSAGE_ARGUMENT_ARRAY). La chaîne mise en forme serait alors « Bi Bob Bill ».

La répétition des nombres d’insertion lorsque la chaîne source contient des spécificateurs de largeur et de précision peuvent ne pas produire les résultats prévus. Si vous avez remplacé %5 par %1, la fonction essaie d’imprimer une chaîne à l’adresse 6 (ce qui entraîne probablement une violation d’accès).

Les spécificateurs de format à virgule flottante (e, E, f et g) ne sont pas pris en charge. La solution de contournement consiste à utiliser la fonction StringCchPrintf pour mettre en forme le nombre à virgule flottante en mémoire tampon temporaire, puis utiliser cette mémoire tampon comme chaîne d’insertion.

Les insertions qui utilisent le préfixe I64 sont traitées comme deux arguments 32 bits. Ils doivent être utilisés avant l’utilisation des arguments suivants. Notez qu’il peut être plus facile d’utiliser StringCchPrintf au lieu de ce préfixe.

 

Tout autre caractère nondigit suivant un caractère de pourcentage est mis en forme dans le message de sortie sans le caractère de pourcentage. Voici quelques exemples.

Chaîne de format Sortie résultante
%% Un seul signe de pourcentage.
% espace Un espace unique. Cette chaîne de format peut être utilisée pour garantir le nombre approprié d’espaces de fin dans une ligne de texte de message.
%. Une seule période. Cette chaîne de format peut être utilisée pour inclure une seule période au début d’une ligne sans mettre fin à la définition du texte du message.
%! Point d’exclamation unique. Cette chaîne de format peut être utilisée pour inclure un point d’exclamation immédiatement après une insertion sans qu’elle ne soit erronée pour le début d’une chaîne de format.
%n Saut de ligne en dur lorsque la chaîne de format se produit à la fin d’une ligne. Cette chaîne de format est utile lorsque FormatMessage fournit des sauts de ligne réguliers afin que le message s’adapte à une certaine largeur.
%r Retour chariot dur sans caractère de nouvelle ligne de fin.
%t Un seul onglet.
 

Remarques sur la sécurité

Si cette fonction est appelée sans FORMAT_MESSAGE_IGNORE_INSERTS, le paramètre arguments doit contenir suffisamment de paramètres pour satisfaire toutes les séquences d’insertion dans la chaîne de message, et il doit s’agir du type correct. Par conséquent, n’utilisez pas de chaînes de message non approuvées ou inconnues avec des insertions activées, car elles peuvent contenir plus de séquences d’insertion que arguments fournit, ou celles qui peuvent être de type incorrect. En particulier, il est dangereux de prendre un code d’erreur système arbitraire retourné par une API et d’utiliser FORMAT_MESSAGE_FROM_SYSTEM sans FORMAT_MESSAGE_IGNORE_INSERTS.

Exemples

La fonction FormatMessage peut être utilisée pour obtenir des chaînes de message d’erreur pour les codes d’erreur système retournés par GetLastError. Pour obtenir un exemple, consultez Récupération du code Last-Error.

L’exemple suivant montre comment utiliser un tableau d’arguments et les spécificateurs de largeur et de précision.
#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);
}


L’exemple suivant montre comment implémenter l’exemple précédent à l’aide de 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;
}

Note

L’en-tête winbase.h définit FormatMessage en tant qu’alias qui sélectionne automatiquement la version ANSI ou Unicode de cette fonction en fonction de la définition de la constante de préprocesseur UNICODE. Le mélange de l’utilisation de l’alias neutre en encodage avec du code qui n’est pas neutre en encodage peut entraîner des incompatibilités qui entraînent des erreurs de compilation ou d’exécution. Pour plus d’informations, consultez Conventions pour les prototypes de fonction.

Exigences

Exigence Valeur
client minimum pris en charge Windows XP [applications de bureau | Applications UWP]
serveur minimum pris en charge Windows Server 2003 [applications de bureau | Applications UWP]
plateforme cible Windows
d’en-tête winbase.h (inclure Windows.h)
bibliothèque Kernel32.lib
DLL Kernel32.dll

Voir aussi

fonctions de gestion des erreurs

du compilateur de messages

Tables de messages