Форматирует строку сообщения. Функция требует определения сообщения как вводимых данных. Определение сообщения может прийти из буфера, который передается в функцию. Оно может прийти из ресурса таблицы сообщений в уже загруженном модуле. Или вызывающая программа (вызывающий модуль) может попросить, чтобы функция нашла в ресурсе (ах) таблицы системных сообщений определение сообщения. Функция находит определение сообщения в ресурсе таблицы сообщений основанных на идентификаторе сообщения и идентификаторе языка. Функция копирует форматированный текст сообщения в буфер выводимых данных, обрабатывая любые встроенные последовательности вставок, если это требуется.
DWORD WINAPI FormatMessage( __in DWORD dwFlags, __in_opt LPCVOID lpSource, __in DWORD dwMessageId, __in DWORD dwLanguageId, __out LPTSTR lpBuffer, __in DWORD nSize, __in_opt va_list* Arguments ); |
Варианты форматирования и как интерпретировать параметр lpSource. Младший байт dwFlags определяет, как функция обрабатывает разрывы строк в буфере выводимых данных. Младший байт может также установить максимальную ширину выводимой форматированной строки.
Этот параметр, может иметь один или несколько нижеследующих значений.
Значение |
Предназначение |
---|---|
FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 |
Параметр lpBuffer - указатель на указатель PVOID, и что параметр nSize определяет минимальное число TCHARs, чтобы назначить для буфера выходное сообщение. Функция назначает буфер, достаточно большой, чтобы содержать форматированное сообщение и помещает указатель в выделенный буфер по адресу, указанному в параметре lpBuffer. Вызывающая программа (вызывающий модуль) должна использовать функцию LocalFree для освобождения буфера, когда он больше не нужен. |
FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000 |
Параметр Arguments не структура va_list, но является указателем на массив значений, которые представляют параметры. Этот флажок не может использоваться с 64-битовым целым значением. Если Вы используете 64-битовое целое число, Вы должны использовать структуру va_list. |
FORMAT_MESSAGE_FROM_HMODULE 0x00000800 |
Параметр lpSource - это дескриптор модуля, содержащего в себе искомый ресурс(ы) таблицы сообщений. Если этот дескриптор
lpSource - NULL, то нужно искать загрузочный модуль
приложения текущего процесса. Этот флажок не может использоваться с флажком
FORMAT_MESSAGE_FROM_STRING. Если у модуля нет никакого ресурса таблицы сообщений, функция завершается ошибкой с кодом ERROR_RESOURCE_TYPE_NOT_FOUND. |
FORMAT_MESSAGE_FROM_STRING 0x00000400 |
Параметр lpSource - указатель на строку с завершающим нулем, который содержит определение сообщения. Определение сообщения может содержать в себе последовательности вставок, а так же может содержать текст сообщения в ресурсе таблицы сообщений. Этот флажок не может использоваться с флажками FORMAT_MESSAGE_FROM_HMODULE или FORMAT_MESSAGE_FROM_SYSTEM. |
FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 |
Функция должна искать в системном ресурсе (ах) таблицы сообщений затребованное сообщение. Если этот флажок установлен вместе с
FORMAT_MESSAGE_FROM_HMODULE, функция ищет в
системной таблице сообщений, если сообщение не найдено в модуле, указанном параметром
lpSource. Этот флажок не может использоваться совместно с
FORMAT_MESSAGE_FROM_STRING. Если этот флажок установлен, приложение может передать результат работы функции GetLastError, чтобы извлечь текст сообщения для определенной системой ошибки. |
FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 |
Последовательности вставки в определении сообщения должны игнорироваться и передаваться неизменными в буфер выводимых данных. Этот флажок полезен для выборки сообщения для более позднего форматирования. Если это флажок установлен, параметр Arguments игнорируется. |
Младший байт dwFlags может определить максимальную длину выводимой форматированной строки. Ниже перечисляются возможные значения младшего байта.
Значение |
Предназначение |
---|---|
0 | Нет никаких ограничений длины строки вывода данных. Функция хранит разрывы строки, которые находятся в тексте определения сообщения в буфере выводимых данных. |
Не нулевое, а другое, чем FORMAT_MESSAGE_MAX_WIDTH_MASK | Ненулевое значение - максимальное число символов в строке вывода. Функция игнорирует обычные разрывы строки в тексте определения сообщения. Функция никогда не рвет строку, разграниченную незаполненным пространством по всему разрыву строки. Функция хранит жестко закодированные разрывы строки в тексте определения сообщения в буфере выводимых данных. Жестко закодированные разрывы строки закодированы при помощи %n ESC-последовательностей. |
FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF |
Функция игнорирует стандартные разрывы строки в тексте определения сообщения. Функция хранит жестко закодированные разрывы строки в тексте определения сообщения в буфер выводимых данных. Функция не создает новых разрывов строки. |
Расположение определения сообщения. Тип этого параметра зависит от параметров настройки в параметре dwFlags.
Установка dwFlags |
Предназначение |
---|---|
FORMAT_MESSAGE_FROM_HMODULE 0x00000800 |
Дескриптор модуля, который содержит таблицу поиска сообщения. |
FORMAT_MESSAGE_FROM_STRING 0x00000400 |
Указатель на строку, которая состоит из неформатированного текста сообщения. Она должна быть развернута для вставок и форматирования соответственно. |
Если ни один из этих флажков не устанавлен в dwFlags, то параметр lpSource игнорируется.
dwMessageIdИдентификатор сообщения для затребованного сообщения. Этот параметр игнорируется, если dwFlags включает в себя FORMAT_MESSAGE_FROM_STRING.
dwLanguageIdИдентификатор языка для затребованного сообщения. Этот параметр игнорируется, если dwFlags включает в себя FORMAT_MESSAGE_FROM_STRING.
Если Вы передаёте конкретный LANGID в этом параметре, то FormatMessage возвратит сообщение только для этого LANGID. Если функция не может найти сообщение для этого LANGID, она возвращает значение ERROR_RESOURCE_LANG_NOT_FOUND. Если Вы передаете нуль, FormatMessage ищет сообщение для LANGIDs в нижеследующем порядке:
Если FormatMessage не локализирует сообщения для какого-либо предшествующего LANGIDs, то она возвращает любую языковую строку сообщения, которая присутствует. Если функция завершается ошибкой, то возвращает значение ERROR_RESOURCE_LANG_NOT_FOUND.
lpBufferУказатель на буфер, который получает строку с завершающим нулем, устанавливающую форматированное сообщение. Если параметр dwFlags включает в себя значение FORMAT_MESSAGE_ALLOCATE_BUFFER, функция назначает буфер, используя функцию LocalAlloc и помещает указатель на буфер по адресу, указанному в параметре lpBuffer.
Этот буфер не может быть больше, чем 64 КБ.
nSize
Если флажок FORMAT_MESSAGE_ALLOCATE_BUFFER не установлен, то этот параметр определяет размер буфера выводимых данных, в TCHARs. Если FORMAT_MESSAGE_ALLOCATE_BUFFER установлен, то этот параметр определяет минимальное число TCHARs, назначаемое для буфера выводимых данных.
Этот буфер не может быть больше, чем 64 КБ.
Arguments
Массив значений, которые используются как значения вставки в форматированном сообщении. %1 в форматирующей строке указывает первое значение в массиве Arguments; %2 указывает второй параметр; и так далее.
Интерпретация каждого значения зависит от информации форматирования, связанной со вставкой в определение сообщения. Значение по умолчанию должно обработать каждое значение как указатель на строку с завершающим нулем.
По умолчанию, параметр Arguments имеет тип va_list *, который является конкретным для языка и конкретным для реализации типом данных для того, чтобы характеризовать переменное число параметров. Состояние параметра va_list не определяется по возвращению из функции. Чтобы использовать va_list снова, ликвидируйте указатель списка переменных параметров, используя va_begin и повторно инициализируйте его при помощи va_start.
Если у Вас нет указателя типа va_list *, то установите флажок FORMAT_MESSAGE_ARGUMENT_ARRAY и передайте указатель на массив значений DWORD_PTR; эти значения - вводимые данные в сообщение, форматированное как значения вставки. У каждой вставки должен быть соответствующий элемент в массиве.
Windows Me/98/95: Никакая отдельная строка включения не может выйти за пределы 1023 символов по длине.
Если функция завершается успешно, возвращаемое значение - число TCHARs, сохраненное в буфере выводимых данных, исключая символ завершающего нуля.
Если функция завершается ошибкой, возвращаемое значение - нуль. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError.
Внутри текста сообщения, несколько ESC-последовательностей поддерживаются для того, чтобы динамически форматировать сообщение. Эти ESC-последовательности и их значения показаны в нижеследующих таблицах. Все ESC-последовательности начинаются с символа процента (%).
ESC-последовательности |
Предназначение |
|
---|---|---|
%0 |
Завершает строку текста сообщения без замыкающего знака новой строки. Эта ESC-последовательность может быть использована для создания длинных строк или для завершения сообщения непосредственно без замыкающего знака новой строки. Это полезно для сообщений приглашения для ввода в командной строке. | |
%n!format string! |
Идентифицирует вставку. Значение n может быть в диапазоне от 1 до 99. Форматирующая строка, которая должна быть окружена восклицательными знаками, является дополнительной (необязательной) и значениями по умолчанию
!s!, если не определены. Дополнительную информацию смотри в статье
Поля спецификации формата.
Форматирующая строка может включить в себя спецификаторы ширины и точности для строк и спецификатор ширины для целых чисел. Используйте звездочку (*), чтобы установить ширину и точность. Например, %1! *.*s! или %1! *u!. Если Вы не используете спецификаторы ширины и точности, числа вставки соответствуют непосредственно входным параметрам. Например, если исходная строка "%1 %2 %1", а вводимые параметры - "Билл" и "Боб", то форматированная строка вывода - "Билл Боб Билл". Однако, если Вы используете спецификатор ширины и точности, числа вставки не соответствуют непосредственно вводимым параметрам. Например, числа вставки для предыдущего примера могут поменяться на "%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-разрядных параметра. Они должны использоваться перед тем, как используются, последующие параметры.
|
Любой другой символ нецифры после символа процента форматируется в выводимом сообщении без символа процента. Ниже - некоторые примеры.
Форматирующая строка |
Окончательный вывод |
---|---|
%% | Единичный знак процента. |
%space | Единичный пробел. Эта форматирующая строка может быть использована, чтобы гарантировать соответствующее число пробелов в строке текста сообщения. |
%. | Единичная точка. Эта форматирующая строка может быть использована для включения единичной точки в начале строки, не завершая определение текста сообщения. |
%! | Единичный восклицательный знак. Эта форматирующая строка может быть использована, чтобы включить восклицательный знак непосредственно после вставки без того, чтобы он был принят началом форматирующей строки. |
%n | Жесткий разрыв строки, когда форматирующая строка действует в конце строки. Эта форматирующая строка полезна, когда функция FormatMessage поставляет обычные разрывы строки, таким образом сообщение помещается в определенном размере. |
%r | Жесткий возврат каретки без замыкающего знака перевода на новую строку. |
%t | Единичная позиция табуляции. |
Если эта функция вызванная без флажка FORMAT_MESSAGE_IGNORE_INSERTS, то параметр Arguments должен содержать в себе достаточно многие параметры, чтобы удовлетворить все последовательности вставки в строке сообщения, и они должны иметь корректный тип. По этой причине, не используйте ненадежные или неизвестные строки сообщений с включенными вставками, потому что они могут содержать в себе больше последовательностей включения, чем, параметр Arguments обеспечивает, или они могут иметь ошибочный тип. В частности опасно получать случайные коды системных ошибок, возвращенные из API и использования флажка FORMAT_MESSAGE_FROM_SYSTEM без флажка FORMAT_MESSAGE_IGNORE_INSERTS. |
Функция FormatMessage может быть использована, чтобы получать строки сообщения об ошибках для кодов системных ошибок, возвращенных функцией GetLastError. Пример смотри в статье Получение последнего кода ошибки. Нижеследующие примеры также демонстрируют использования функции 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! (DWORD_PTR)L"Bob", // %4 (DWORD_PTR)6, (DWORD_PTR)L"Bill" }; // %5!*s! const DWORD size = 100+1; WCHAR buffer[size]; if (!FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, pMessage, 0, // игнорируется 0, // игнорируется (LPWSTR)&buffer, size, (va_list*)pArgs)) { wprintf(L"Format message failed with 0x%x\n", GetLastError()); return; } 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!"; pBuffer = GetFormattedMessage(pMessage, 4, 2, L"Bill", L"Bob", 6, L"Bill"); if (pBuffer) { wprintf(L"Formatted message: %s\n", pBuffer); LocalFree(pBuffer); } else { wprintf(L"Format message failed with 0x%x\n", GetLastError()); } } 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; }
|
Обзор Обработка ошибок, Функции, используемые при обработке ошибок, Ресурс MESSAGETABLE, Компилятор сообщения, Таблицы сообщений
Размещение и совместимость FormatMessage |
||
К | Windows Vista | Да |
л | Windows XP | Да |
и | Windows 2000 Professional | Да |
е | Windows NT Workstation | Да версии 3.1 |
н | Windows Me | Да |
т | Windows 98 | Да |
Windows 95 | Да | |
С | Windows Server 2008 | |
е | Windows Server 2003 | Да |
р | Windows 2000 Server | Да |
в | Windows NT Server | Да версии 3.1 |
е | ||
р | ||
Используемая библиотека | Kernel32.lib | |
Используемая DLL | Kernel32.dll | |
Заголовочный файл | ||
- объявлено в | Winbase.h | |
- включено в | Windows.h | |
Unicode | Реализуется как FormatMessageW (Unicode) и FormatMessageA (ANSI) | |
Замечания по платформе | Не имеется |