Функція FormatMessage
Форматує рядок повідомлення. Функція вимагає визначення повідомлення як даних, що вводяться. Визначення повідомлення може надходити з буфера, який передається у функцію. Воно може прийти з ресурсу таблиці повідомлень у завантаженому модулі. Або програма, що викликає (викликає модуль) може попросити, щоб функція знайшла в ресурсі (ах) таблиці системних повідомлень визначення повідомлення. Функція знаходить визначення повідомлення в ресурсі таблиці повідомлень на основі ідентифікатора повідомлення та ідентифікатора мови. Функція копіює форматований текст повідомлення в буфер даних, обробляючи будь-які вбудовані послідовності вставок, якщо це потрібно.
Варіанти форматування та як інтерпретувати параметрlpSource. Молодший байтdwFlagsвизначає, як функція обробляє розриви рядків у буфері даних. Молодший байт може також встановити максимальну ширину форматованого рядка, що виводиться.
Цей параметр може мати один або кілька нижченаведених значень.
Призначення
Цей прапорець не може використовуватися з 64-бітовим цілим значенням. Якщо Ви використовуєте 64-бітове ціле число, Ви повинні використовувати структуруva_list.
Якщо модуль не має жодного ресурсу таблиці повідомлень, функція завершується помилкою з кодомERROR_RESOURCE_TYPE_NOT_FOUND.
Якщо цей прапорець встановлений, програма може передати результат роботи функціїGetLastError, щоб вийняти текст повідомлення для певної системи помилки.
Молодший байтdwFlagsможе визначити максимальну довжину форматованого рядка, що виводиться. Нижче перераховуються можливі значення молодшого байта.
Призначення
Розташування визначення повідомлення. Тип цього параметра залежить від параметрівdwFlags.
Установка dwFlags
Призначення
Якщо жоден з цих прапорців не встановленоdwFlags, то параметрlpSourceігнорується.
Ідентифікатор повідомлення для відповідного повідомлення. Цей параметр ігнорується, якщоdwFlagsвключаєFORMAT_MESSAGE_FROM_STRING.
Ідентифікатор мови для відповідного повідомлення. Цей параметр ігнорується, якщоdwFlagsвключаєFORMAT_MESSAGE_FROM_STRING.
ЯкщоВи надаєте конкретнийLANG >ERROR_RESOURCE_LANG_NOT_FOUND. Якщо Ви передаєте нуль,FormatMessageшукає повідомлення дляLANGIDsу наведеному нижче порядку:
- Невизначена мова
- ПотоковийLANGID, ґрунтується на потоках з локалізованими значеннями
- За замовчуваннямLANGID, базується на локалізованому значенні мови країни (місцевості) користувача за умовчанням
- Системний за промовчаннямLANGID, ґрунтується на системному значенні локалізації за умовчанням
- Англійська мова у США
ЯкщоFormatMessageне локалізує повідомлення для будь-якого попередньогоLANG >ERROR_RESOURCE_LANG_NOT_FOUND.
Цей буфер не може бути більшим, ніж 64 КБ.
Якщо прапорецьFORMAT_MESSAGE_ALLOCATE_BUFFERне встановлений, цей параметр визначає розмір буфера виведених даних, вTCHARs. ЯкщоFORMAT_MESSAGE_ALLOCATE_BUFFERвстановлений, цей параметр визначає мінімальне числоTCHARs, призначуване для буфера виведених даних.
Цей буфер не може бути більшим, ніж 64 КБ.
Масив значень, які використовуються як значення вставки у форматованому повідомленні. %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
%n!format string!
Форматуючий рядок може включати специфікатори ширини і точності для рядків і специфікатор ширини для цілих чисел. Використовуйте зірочку (*), щоб встановити ширину та точність. Наприклад, %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). Форматований рядоктоді буде "Бі Боб Білл".
Специфікатори формату з плаваючою точкою – e, E, f та g – не підтримуються. Для обхідного шляху потрібно використовувати функціюStringCchPrintf, щоб форматувати число з плаваючою комою у тимчасовому буфері, а потім використовувати цей буфер як рядок вставки.
Вставки, які використовують префіксI64, обробляються як два 32-розрядні параметри. Вони повинні використовуватися перед тим, як використовуються наступні параметри.
| Зверніть увагу!на те, що може бути легше для Вас використовуватиStringCchPrintfзамість цього префікса. |
Будь-який інший символ нецифри після символу відсотка форматується у повідомленні без символу відсотка. Нижче – деякі приклади.
Форматуючий рядок
Остаточний висновок
Зауваження щодо безпеки
| Якщо ця функція викликана без прапорцяFORMAT_MESSAGE_IGNORE_INSERTS, то параметрArgumentsповинен містити в собі досить багато параметрів, щоб задовольнити всі послідовності вставки в рядку повідомлення, і вони повинні мати коректний тип. З цієї причини, не використовуйте ненадійні або невідомі рядки повідомлень з увімкненими вставками, тому що вони можуть містити в собі більше послідовностей включення, ніж, параметрArgumentsзабезпечує, або вони можуть мати помилковий тип . Зокрема небезпечно отримувати випадкові коди системних помилок, повернутих зAPIта використання прапорцяFORMAT_MESSAGE_FROM_SYSTEMбез прапорцяFORMAT_MESSAGE_IGNORE_INSERTS. |
Демонстраційний код [C++]
ФункціяFormatMessageможе бути використана для отримання рядків повідомлення про помилки для кодів системних помилок, повернутих функцієюGetLastError. Приклад дивись у статтіОтримання останнього коду помилки. Нижченаведені приклади також демонструють використання функціїFormatMessage.
Приклад нижче показує, як використовувати масив параметра та специфікатори ширини та точності.
Демонстраційний код
Приклад нижче показує, як реалізувати попередній приклад, використовуючиva_list.
Дивись також
Огляд Обробка помилок, Функції, що використовуються при обробці помилок, Ресурс MESSAGETABLE, Компілятор повідомлення, Таблиці повідомлень