Compartir a través de


Función FormatMessageA (winbase.h)

Da formato a una cadena de mensaje. La función requiere una definición de mensaje como entrada. La definición del mensaje puede proceder de un búfer pasado a la función. Puede proceder de un recurso de tabla de mensajes en un módulo ya cargado. O bien, el autor de la llamada puede pedir a la función que busque los recursos de la tabla de mensajes del sistema para la definición del mensaje. La función busca la definición de mensaje en un recurso de tabla de mensajes en función de un identificador de mensaje y un identificador de idioma. La función copia el texto del mensaje con formato en un búfer de salida, procesando las secuencias de inserción insertadas si se solicitan.

Sintaxis

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

Parámetros

[in] dwFlags

Las opciones de formato y cómo interpretar el parámetro lpSource. El byte de orden bajo de dwFlags especifica cómo controla la función los saltos de línea en el búfer de salida. El byte de orden bajo también puede especificar el ancho máximo de una línea de salida con formato.

Este parámetro puede ser uno o varios de los siguientes valores.

Valor Significado
FORMAT_MESSAGE_ALLOCATE_BUFFER
0x00000100
La función asigna un búfer lo suficientemente grande como para contener el mensaje con formato y coloca un puntero al búfer asignado en la dirección especificada por lpBuffer. El parámetro lpBuffer de es un puntero a un LPTSTR; debe convertir el puntero a un LPTSTR de (por ejemplo, ). El parámetro nSize especifica el número mínimo de TCHAR asignar para un búfer de mensajes de salida. El autor de la llamada debe usar la función LocalFree para liberar el búfer cuando ya no sea necesario.

Si la longitud del mensaje con formato supera los 128 000 bytes, formatMessage producirá un error y se producirá un error en una llamada posterior a GetLastError devolverá ERROR_MORE_DATA.

En versiones anteriores de Windows, este valor no estaba disponible para su uso al compilar aplicaciones de la Tienda Windows. A partir de Windows 10, este valor se puede usar.

Windows Server 2003 y Windows XP:

Si la longitud del mensaje con formato supera los 128 000 bytes, formatMessage no producirá automáticamente un error de ERROR_MORE_DATA.

FORMAT_MESSAGE_ARGUMENT_ARRAY
0x00002000
El parámetro Arguments no es una estructura va_list, pero es un puntero a una matriz de valores que representan los argumentos.

Esta marca no se puede usar con valores enteros de 64 bits. Si usa un entero de 64 bits, debe usar la estructura va_list.

FORMAT_MESSAGE_FROM_HMODULE
0x00000800
El parámetro lpSource es un identificador de módulo que contiene los recursos de la tabla de mensajes que se van a buscar. Si este identificador de lpSource es null, se buscará en el archivo de imagen de aplicación del proceso actual. Esta marca no se puede usar con FORMAT_MESSAGE_FROM_STRING.

Si el módulo no tiene ningún recurso de tabla de mensajes, se produce un error en la función con ERROR_RESOURCE_TYPE_NOT_FOUND.

FORMAT_MESSAGE_FROM_STRING
0x00000400
El parámetro lpSource es un puntero a una cadena terminada en null que contiene una definición de mensaje. La definición del mensaje puede contener secuencias de inserción, al igual que el texto del mensaje en un recurso de tabla de mensajes. Esta marca no se puede usar con FORMAT_MESSAGE_FROM_HMODULE o FORMAT_MESSAGE_FROM_SYSTEM.
FORMAT_MESSAGE_FROM_SYSTEM
0x00001000
La función debe buscar los recursos de la tabla de mensajes del sistema para el mensaje solicitado. Si se especifica esta marca con FORMAT_MESSAGE_FROM_HMODULE, la función busca en la tabla de mensajes del sistema si el mensaje no se encuentra en el módulo especificado por lpSource. Esta marca no se puede usar con FORMAT_MESSAGE_FROM_STRING.

Si se especifica esta marca, una aplicación puede pasar el resultado de la función GetLastError para recuperar el texto del mensaje de un error definido por el sistema.

FORMAT_MESSAGE_IGNORE_INSERTS
0x00000200
Las secuencias de inserción en la definición de mensaje, como %1, se omitirán y pasarán al búfer de salida sin cambios. Esta marca es útil para capturar un mensaje para el formato posterior. Si se establece esta marca, se omite el parámetro Argumentos.
 

El byte de orden bajo de dwFlags puede especificar el ancho máximo de una línea de salida con formato. A continuación se muestran los valores posibles del byte de orden bajo.

Valor Significado
0
No hay restricciones de ancho de línea de salida. La función almacena saltos de línea que se encuentran en el texto de definición de mensaje en el búfer de salida.
FORMAT_MESSAGE_MAX_WIDTH_MASK
0x000000FF
La función omite los saltos de línea normales en el texto de la definición del mensaje. La función almacena saltos de línea codificados de forma rígida en el texto de definición de mensaje en el búfer de salida. La función no genera saltos de línea nuevos.
 

Si el byte de orden bajo es un valor distinto de FORMAT_MESSAGE_MAX_WIDTH_MASK, especifica el número máximo de caracteres en una línea de salida. La función omite los saltos de línea normales en el texto de la definición del mensaje. La función nunca divide una cadena delimitada por espacios en blanco en un salto de línea. La función almacena saltos de línea codificados de forma rígida en el texto de definición de mensaje en el búfer de salida. Los saltos de línea codificados de forma rígida se codifican con la secuencia de escape %n.

[in, optional] lpSource

Ubicación de la definición del mensaje. El tipo de este parámetro depende de la configuración del parámetro dwFlags.

configuración de dwFlags Significado
FORMAT_MESSAGE_FROM_HMODULE
0x00000800
Identificador del módulo que contiene la tabla de mensajes que se va a buscar.
FORMAT_MESSAGE_FROM_STRING
0x00000400
Puntero a una cadena que consta de texto de mensaje sin formato. Se analizará en busca de inserciones y formatos en consecuencia.
 

Si ninguna de estas marcas se establece en dwFlags, se omite lpSource.

[in] dwMessageId

Identificador de mensaje del mensaje solicitado. Este parámetro se omite si dwFlags incluye FORMAT_MESSAGE_FROM_STRING.

[in] dwLanguageId

El identificador de idioma para el mensaje solicitado. Este parámetro se omite si dwFlags incluye FORMAT_MESSAGE_FROM_STRING.

Si pasa un LANGID específico de en este parámetro, formatMessage devolverá un mensaje solo para ese LANGID. Si la función no encuentra un mensaje para ese LANGID, establece Last-Error en ERROR_RESOURCE_LANG_NOT_FOUND. Si pasa cero, FormatMessage busca un mensaje para LANGID en el orden siguiente:

  1. Idioma neutro
  2. Subproceso LANGID, en función del valor de configuración regional del subproceso
  3. El valor predeterminado del usuario LANGID, en función del valor de configuración regional predeterminado del usuario
  4. El valor predeterminado del sistema LANGID, en función del valor de configuración regional predeterminado del sistema
  5. Inglés de EE. UU.
Si formatMessage no encuentra un mensaje para ninguno de los LANGID anteriores, devuelve cualquier cadena de mensaje de idioma que esté presente. Si se produce un error, devuelve ERROR_RESOURCE_LANG_NOT_FOUND.

[out] lpBuffer

Puntero a un búfer que recibe la cadena terminada en NULL que especifica el mensaje con formato. Si dwFlags incluye FORMAT_MESSAGE_ALLOCATE_BUFFER, la función asigna un búfer mediante la función localAlloc y coloca el puntero al búfer en la dirección especificada en lpBuffer.

Este búfer no puede ser mayor que 64 000 bytes.

[in] nSize

Si no se establece la marca FORMAT_MESSAGE_ALLOCATE_BUFFER, este parámetro especifica el tamaño del búfer de salida, en TCHAR. Si se establece FORMAT_MESSAGE_ALLOCATE_BUFFER, este parámetro especifica el número mínimo de TCHAR asignar para un búfer de salida.

El búfer de salida no puede tener más de 64 000 bytes.

[in, optional] Arguments

Matriz de valores que se usan como valores de inserción en el mensaje con formato. Un %1 en la cadena de formato indica el primer valor de la matriz de Argumentos; un %2 indica el segundo argumento; y así sucesivamente.

La interpretación de cada valor depende de la información de formato asociada a la inserción en la definición del mensaje. El valor predeterminado es tratar cada valor como puntero a una cadena terminada en null.

De forma predeterminada, el parámetro Arguments es de tipo va_list*, que es un tipo de datos específico del lenguaje y la implementación para describir un número variable de argumentos. El estado del argumento va_list no está definido tras la devolución de la función. Para volver a usar el va_list, destruya el puntero de lista de argumentos de variable mediante va_end y vuelva a inicializarlo con va_start.

Si no tiene un puntero de tipo va_list*, especifique la marca FORMAT_MESSAGE_ARGUMENT_ARRAY y pase un puntero a una matriz de valores DWORD_PTR; esos valores se introducen en el mensaje con formato como valores de inserción. Cada inserción debe tener un elemento correspondiente en la matriz.

Valor devuelto

Si la función se ejecuta correctamente, el valor devuelto es el número de TCHAR almacenados en el búfer de salida, excepto el carácter nulo de terminación.

Si se produce un error en la función, el valor devuelto es cero. Para obtener información de error extendida, llame a GetLastError.

Observaciones

Dentro del texto del mensaje, se admiten varias secuencias de escape para dar formato dinámico al mensaje. Estas secuencias de escape y sus significados se muestran en las tablas siguientes. Todas las secuencias de escape comienzan con el carácter de porcentaje (%).

Secuencia de escape Significado
%0 Finaliza una línea de texto de mensaje sin un carácter de línea nuevo final. Esta secuencia de escape se puede usar para crear líneas largas o para finalizar el propio mensaje sin un carácter de línea nuevo final. Resulta útil para mensajes de solicitud.
% n!formato de cadena! Identifica una secuencia de inserción. El valor de n puede estar en el intervalo comprendido entre 1 y 99. La cadena de formato (que debe estar rodeada de signos de exclamación) es opcional y el valor predeterminado es !s! si no se especifica. Para obtener más información, vea campos de especificación de formato.

La cadena de formato puede incluir un especificador de ancho y precisión para cadenas y un especificador de ancho para enteros. Use un asterisco () para especificar el ancho y la precisión. Por ejemplo, %1!.*s! o %1!*u!.

Si no usa los especificadores de ancho y precisión, los números de inserción corresponden directamente a los argumentos de entrada. Por ejemplo, si la cadena de origen es "%1 %2 %1" y los argumentos de entrada son "Bill" y "Bob", la cadena de salida con formato es "Bill Bob Bill".

Sin embargo, si usa un especificador de ancho y precisión, los números de inserción no se corresponden directamente con los argumentos de entrada. Por ejemplo, los números de inserción del ejemplo anterior podrían cambiar a "%1!*.*s! %4 %5!*s!".

Los números de inserción dependen de si se usa una matriz de argumentos (FORMAT_MESSAGE_ARGUMENT_ARRAY) o un va_list. Para una matriz de argumentos, el siguiente número de inserción es n+2 si la cadena de formato anterior contenía un asterisco y es n+3 si se especificaron dos asteriscos. Para un va_list, el siguiente número de inserción se n+1 si la cadena de formato anterior contenía un asterisco y es n+2 si se especificaron dos asteriscos.

Si desea repetir "Bill", como en el ejemplo anterior, los argumentos deben incluir "Bill" dos veces. Por ejemplo, si la cadena de origen es "%1!*.*s! %4 %5!*s!", los argumentos podrían ser, 4, 2, Bill, Bob, 6, Bill (si se usa la marca de FORMAT_MESSAGE_ARGUMENT_ARRAY). La cadena con formato sería " Bi Bob Bill".

Repetir números de inserción cuando la cadena de origen contiene especificadores de ancho y precisión puede no producir los resultados previstos. Si ha reemplazado %5 por %1, la función intentará imprimir una cadena en la dirección 6 (lo que probablemente provocaría una infracción de acceso).

No se admiten especificadores de formato de punto flotante (e, E, f y g). La solución consiste en usar la función StringCchPrintf para dar formato al número de punto flotante en un búfer temporal y, a continuación, usar ese búfer como cadena de inserción.

Las inserciones que usan el prefijo I64 se tratan como dos argumentos de 32 bits. Deben usarse antes de que se usen argumentos posteriores. Tenga en cuenta que puede ser más fácil usar StringCchPrintf en lugar de este prefijo.

 

Cualquier otro carácter nondigit después de un carácter de porcentaje tiene el formato en el mensaje de salida sin el carácter de porcentaje. A continuación se muestran algunos ejemplos.

Cadena de formato Salida resultante
%% Un solo signo de porcentaje.
% espacio Un solo espacio. Esta cadena de formato se puede usar para garantizar el número adecuado de espacios finales en una línea de texto de mensaje.
%. Un único período. Esta cadena de formato se puede usar para incluir un único punto al principio de una línea sin terminar la definición de texto del mensaje.
%! Un único signo de exclamación. Esta cadena de formato se puede usar para incluir un signo de exclamación inmediatamente después de una inserción sin que se confunda por el principio de una cadena de formato.
%n Salto de línea dura cuando la cadena de formato se produce al final de una línea. Esta cadena de formato es útil cuando FormatMessage proporciona saltos de línea normales para que el mensaje se ajuste a un ancho determinado.
%r Retorno de carro duro sin un carácter de nueva línea final.
%t Una sola pestaña.
 

Comentarios de seguridad de

Si se llama a esta función sin FORMAT_MESSAGE_IGNORE_INSERTS, el parámetro Arguments debe contener suficientes parámetros para satisfacer todas las secuencias de inserción de la cadena de mensaje y deben ser del tipo correcto. Por lo tanto, no use cadenas de mensaje que no sean de confianza o desconocidas con inserciones habilitadas porque pueden contener más secuencias de inserción que Argumentos proporciona, o aquellas que pueden ser del tipo incorrecto. En concreto, no es seguro tomar un código de error arbitrario del sistema devuelto desde una API y usar FORMAT_MESSAGE_FROM_SYSTEM sin FORMAT_MESSAGE_IGNORE_INSERTS.

Ejemplos

La función FormatMessage de se puede usar para obtener cadenas de mensaje de error para los códigos de error del sistema devueltos por GetLastError. Para obtener un ejemplo, vea Recuperar el código de Last-Error.

En el ejemplo siguiente se muestra cómo usar una matriz de argumentos y los especificadores de ancho y precisión.
#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);
}


En el ejemplo siguiente se muestra cómo implementar el ejemplo anterior mediante 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

El encabezado winbase.h define FormatMessage como alias que selecciona automáticamente la versión ANSI o Unicode de esta función en función de la definición de la constante de preprocesador UNICODE. La combinación del uso del alias neutral de codificación con código que no es neutral de codificación puede dar lugar a errores de coincidencia que dan lugar a errores de compilación o tiempo de ejecución. Para obtener más información, vea Conventions for Function Prototypes.

Requisitos

Requisito Valor
cliente mínimo admitido Windows XP [aplicaciones de escritorio | Aplicaciones para UWP]
servidor mínimo admitido Windows Server 2003 [aplicaciones de escritorio | Aplicaciones para UWP]
de la plataforma de destino de Windows
encabezado de winbase.h (incluya Windows.h)
biblioteca de Kernel32.lib
DLL de Kernel32.dll

Consulte también

funciones de control de errores

del compilador de mensajes de

Tablas de mensajes