Функция FormatMessageW (winbase.h)
Форматирует строку сообщения. Для функции требуется определение сообщения в качестве входных данных. Определение сообщения может поступать из буфера, переданного в функцию. Он может поступать из ресурса таблицы сообщений в уже загруженном модуле. Или вызывающий объект может попросить функцию выполнить поиск ресурсов таблицы сообщений системы для определения сообщения. Функция находит определение сообщения в ресурсе таблицы сообщений на основе идентификатора сообщения и идентификатора языка. Функция копирует отформатированный текст сообщения в выходной буфер, обрабатывая все внедренные последовательности вставки при необходимости.
Синтаксис
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
);
Параметры
[in] dwFlags
Параметры форматирования и интерпретация параметра lpSource. Байт с низким порядком dwFlags указывает, как функция обрабатывает разрывы строк в выходном буфере. Байт с низким порядком также может указать максимальную ширину отформатированных выходных строк.
Этот параметр может быть одним или несколькими из следующих значений.
Ценность | Значение |
---|---|
|
Функция выделяет буфер достаточно большой для хранения отформатированного сообщения и помещает указатель на выделенный буфер по адресу, указанному lpBuffer. Параметр Если длина отформатированного сообщения превышает 128 байт, FormatMessage завершится ошибкой, а последующий вызов getLastError вернет ERROR_MORE_DATA. В предыдущих версиях Windows это значение было недоступно для использования при компиляции приложений Магазина Windows. По состоянию на Windows 10 это значение можно использовать. Windows Server 2003 и Windows XP: Если длина отформатированного сообщения превышает 128 КБ, FormatMessage не будет автоматически завершатся ошибкой ERROR_MORE_DATA. |
|
Параметр аргументов Этот флаг нельзя использовать с 64-разрядными целыми значениями. Если используется 64-разрядное целое число, необходимо использовать структуру va_list. |
|
Параметр lpSource — это дескриптор модуля, содержащий ресурсы таблицы сообщений для поиска. Если этот дескриптор lpSource lpSourceNULL, будет выполнен поиск по файлу образа приложения текущего процесса. Этот флаг нельзя использовать с FORMAT_MESSAGE_FROM_STRING.
Если модуль не имеет ресурса таблицы сообщений, функция завершается ошибкой с ERROR_RESOURCE_TYPE_NOT_FOUND. |
|
Параметр lpSource — это указатель на строку, завершающую значение NULL, содержащую определение сообщения. Определение сообщения может содержать последовательности вставки, так же как текст сообщения в ресурсе таблицы сообщений. Этот флаг нельзя использовать с FORMAT_MESSAGE_FROM_HMODULE или FORMAT_MESSAGE_FROM_SYSTEM. |
|
Функция должна искать ресурсы таблицы системных сообщений для запрошенного сообщения. Если этот флаг указан с FORMAT_MESSAGE_FROM_HMODULE, функция выполняет поиск в системной таблице сообщений, если сообщение не найдено в модуле, указанном lpSource. Этот флаг нельзя использовать с FORMAT_MESSAGE_FROM_STRING.
Если этот флаг указан, приложение может передать результат функции getLastError |
|
Вставка последовательностей в определение сообщения, например %1, должна игнорироваться и передаваться в выходной буфер без изменений. Этот флаг полезен для получения сообщения для последующего форматирования. Если этот флаг задан, параметр Arguments игнорируется. |
Байты с низким порядком dwFlags могут указывать максимальную ширину отформатированных выходных строк. Ниже приведены возможные значения байтов низкого порядка.
Если байт низкого порядка является ненулевое значение, отличное от FORMAT_MESSAGE_MAX_WIDTH_MASK, оно указывает максимальное количество символов в выходной строке. Функция игнорирует регулярные разрывы строк в тексте определения сообщения. Функция никогда не разбивает строку, разделенную пробелами по разрыву строки. Функция сохраняет жестко закодированные разрывы строк в тексте определения сообщения в выходной буфер. Жестко закодированные разрывы строк кодируются с помощью последовательности escape-%n.
[in, optional] lpSource
Расположение определения сообщения. Тип этого параметра зависит от параметров в параметре dwFlags.
Если ни в
[in] dwMessageId
Идентификатор сообщения для запрошенного сообщения. Этот параметр игнорируется, если dwFlags включает FORMAT_MESSAGE_FROM_STRING.
[in] dwLanguageId
Идентификатор языка для запрошенного сообщения. Этот параметр игнорируется, если dwFlags включает FORMAT_MESSAGE_FROM_STRING.
Если вы передаете определенный LANGID в этом параметре, FormatMessage вернет сообщение только для этого LANGID. Если функция не может найти сообщение для этого LANGID, оно задает Last-Error значение ERROR_RESOURCE_LANG_NOT_FOUND. Если вы передаете ноль, FormatMessage ищет сообщение для LANGID в следующем порядке:
- Нейтральный язык
- Поток LANGID на основе значения языкового стандарта потока
- Пользователь по умолчанию LANGID на основе значения языкового стандарта пользователя по умолчанию
- Системный стандарт LANGIDна основе значения языкового стандарта по умолчанию по умолчанию
- Английский язык США
[out] lpBuffer
Указатель на буфер, получающий строку, завершающую значение NULL, которая задает отформатированное сообщение. Если dwFlags включает FORMAT_MESSAGE_ALLOCATE_BUFFER, функция выделяет буфер с помощью функции LocalAlloc и помещает указатель на буфер по адресу, указанному в lpBuffer.
Этот буфер не может быть больше 64 КБ.
[in] nSize
Если флаг FORMAT_MESSAGE_ALLOCATE_BUFFER не задан, этот параметр указывает размер выходного буфера в TCHARs. Если задано FORMAT_MESSAGE_ALLOCATE_BUFFER, этот параметр указывает минимальное количество TCHARs для выделения для выходного буфера.
Выходной буфер не может быть больше 64 КБ.
[in, optional] Arguments
Массив значений, которые используются в качестве вставленных значений в отформатируемом сообщении. %1 в строке форматирования указывает первое значение в массиве аргументов
Интерпретация каждого значения зависит от сведений о форматировании, связанных с вставкой в определении сообщения. Значение по умолчанию — рассматривать каждое значение как указатель на строку, завершаемую значением NULL.
По умолчанию параметр Arguments имеет тип va_list*, который является типом данных, зависящим от языка и реализации, для описания переменного числа аргументов. Состояние аргумента va_list не определено при возврате функции. Чтобы снова использовать va_list, удалите указатель списка аргументов переменной с помощью va_end и повторно инициализировать его с помощью va_start.
Если у вас нет указателя типа va_list*, укажите флаг FORMAT_MESSAGE_ARGUMENT_ARRAY и передайте указатель на массив значений DWORD_PTR; эти значения представляют собой входные данные для сообщения, отформатированного в виде значений вставки. Каждая вставка должна иметь соответствующий элемент в массиве.
Возвращаемое значение
Если функция выполнена успешно, возвращаемое значение равно числу TCHARs, хранящимся в выходном буфере, за исключением завершающего символа NULL.
Если функция завершается ошибкой, возвращаемое значение равно нулю. Чтобы получить расширенные сведения об ошибке, вызовите GetLastError.
Замечания
В тексте сообщения поддерживается несколько escape-последовательностей для динамического форматирования сообщения. Эти escape-последовательности и их значения показаны в следующих таблицах. Все escape-последовательности начинаются с символа процента (%).
Escape-последовательность | Значение |
---|---|
%0 | Завершает текстовую строку сообщения без нового символа строки. Эту последовательность escape-адресов можно использовать для создания длинных строк или завершения самого сообщения без нового символа строки. Это полезно для сообщений с запросом. |
% n!форматирование строки! |
Определяет последовательность вставки. Значение n может находиться в диапазоне от 1 до 99. Строка формата (которая должна быть окружена восклицательными знаками) является необязательной и по умолчанию имеет значение !s! Значение , если не указано. Дополнительные сведения см. в поля спецификации формата.
Строка формата может включать описатель ширины и точности для строк и описатель ширины для целых чисел. Используйте звездочку () для указания ширины и точности. Например, %1!.*s! или %1!*u!. Если вы не используете описатели ширины и точности, цифры вставки соответствуют непосредственно входным аргументам. Например, если исходная строка имеет значение "%1 %2 %1", а входные аргументы — "Bill" и "Bob", форматированная выходная строка — "Билл Боб Билл". Однако если вы используете описатель ширины и точности, цифры вставки не соответствуют непосредственно входным аргументам. Например, цифры вставки для предыдущего примера могут измениться на "%1!*.*s! %4 %5!*s!". Числа вставки зависят от того, используется ли массив аргументов (FORMAT_MESSAGE_ARGUMENT_ARRAY) или va_list. Для массива аргументов следующий номер вставки n+2, если предыдущая строка формата содержала одну звездочку и n+3, если были указаны две звездочки. Для va_listследующий номер вставки n+1, если предыдущая строка формата содержала одну звездочку и n+2, если были указаны две звездочки. Если вы хотите повторить "Билл", как и в предыдущем примере, аргументы должны включать "Билл" дважды. Например, если исходная строка имеет значение "%1!*.*s! %4 %5!*s!", аргументы могут быть: 4, 2, Билл, Боб, 6, Билл (если используется флаг FORMAT_MESSAGE_ARGUMENT_ARRAY). Затем форматированная строка будет "Би Боб Билл". Повторяющиеся числа вставки, если исходная строка содержит описатели ширины и точности, могут не дать предполагаемых результатов. Если вы заменили %5 на %1, функция попытается распечатать строку по адресу 6 (скорее всего, это приведет к нарушению доступа). Описатели формата с плавающей запятой (e, E, F и g) не поддерживаются. Обходной путь — использовать функцию StringCchPrintf для форматирования числа с плавающей запятой в временный буфер, а затем использовать этот буфер в качестве строки вставки. Вставки, использующие префикс I64, обрабатываются как два 32-разрядных аргумента. Они должны использоваться перед использованием последующих аргументов. Обратите внимание, что вы можете использовать StringCchPrintf вместо этого префикса. |
Любой другой символ недигита, следующий за символом процента, форматируется в выходном сообщении без символа процента. Ниже приведены некоторые примеры.
Строка форматирования | Результирующий результат |
---|---|
%% | Единый знак процента. |
% пространства | Одно пространство. Эту строку форматирования можно использовать для обеспечения соответствующего количества конечных пробелов в текстовой строке сообщения. |
%. | Один период. Эту строку форматирования можно использовать для включения одного периода в начале строки без прекращения определения текста сообщения. |
%! | Один восклицательный знак. Эту строку формата можно использовать для включения восклицательного знака сразу после вставки без ошибок в начале строки формата. |
%n | Жесткое разрыв строки при возникновении строки форматирования в конце строки. Эта строка формата полезна, если FormatMessage предоставляет регулярные разрывы строк, чтобы сообщение соответствовало определенной ширине. |
%r | Жесткий карета возвращается без конечного нового символа. |
%t | Одна вкладка. |
Замечания по безопасности
Если эта функция вызывается без FORMAT_MESSAGE_IGNORE_INSERTS, параметр Arguments должен содержать достаточно параметров, чтобы удовлетворить все последовательности вставок в строке сообщения, и они должны иметь правильный тип. Поэтому не используйте ненадежные или неизвестные строки сообщений с включенными вставками, так как они могут содержать больше последовательностей вставки, чем аргументы предоставляет, или те, которые могут иметь неправильный тип. В частности, небезопасно принимать произвольный системный код ошибки, возвращаемый из API, и использовать FORMAT_MESSAGE_FROM_SYSTEM без FORMAT_MESSAGE_IGNORE_INSERTS.Примеры
Функцию
#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);
}
В следующем примере показано, как реализовать предыдущий пример с помощью 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;
}
Заметка
Заголовок winbase.h определяет FormatMessage как псевдоним, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОДа. Сочетание использования псевдонима, нейтрального для кодирования, с кодом, не зависящим от кодирования, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в соглашениях о прототипах функций.
Требования
Требование | Ценность |
---|---|
минимальные поддерживаемые клиентские | Windows XP [классические приложения | Приложения UWP] |
минимальный поддерживаемый сервер | Windows Server 2003 [классические приложения | Приложения UWP] |
целевая платформа | Виндоус |
заголовка | winbase.h (включая Windows.h) |
библиотеки |
Kernel32.lib |
DLL | Kernel32.dll |
См. также
компилятора сообщений
Таблицы сообщений