Функція FormatMessage

Форматує рядок повідомлення. Функція вимагає визначення повідомлення як даних, що вводяться. Визначення повідомлення може надходити з буфера, який передається у функцію. Воно може прийти з ресурсу таблиці повідомлень у завантаженому модулі. Або програма, що викликає (викликає модуль) може попросити, щоб функція знайшла в ресурсі (ах) таблиці системних повідомлень визначення повідомлення. Функція знаходить визначення повідомлення в ресурсі таблиці повідомлень на основі ідентифікатора повідомлення та ідентифікатора мови. Функція копіює форматований текст повідомлення в буфер даних, обробляючи будь-які вбудовані послідовності вставок, якщо це потрібно.

Варіанти форматування та як інтерпретувати параметрlpSource. Молодший байтdwFlagsвизначає, як функція обробляє розриви рядків у буфері даних. Молодший байт може також встановити максимальну ширину форматованого рядка, що виводиться.

Цей параметр може мати один або кілька нижченаведених значень.

Призначення

Цей прапорець не може використовуватися з 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ігнорується.

Ідентифікатор повідомлення для відповідного повідомлення. Цей параметр ігнорується, якщоdwFlagsвключаєFORMAT_MESSAGE_FROM_STRING.

Ідентифікатор мови для відповідного повідомлення. Цей параметр ігнорується, якщоdwFlagsвключаєFORMAT_MESSAGE_FROM_STRING.

ЯкщоВи надаєте конкретнийLANG >ERROR_RESOURCE_LANG_NOT_FOUND. Якщо Ви передаєте нуль,FormatMessageшукає повідомлення дляLANGIDsу наведеному нижче порядку:

  1. Невизначена мова
  2. ПотоковийLANGID, ґрунтується на потоках з локалізованими значеннями
  3. За замовчуваннямLANGID, базується на локалізованому значенні мови країни (місцевості) користувача за умовчанням
  4. Системний за промовчаннямLANGID, ґрунтується на системному значенні локалізації за умовчанням
  5. Англійська мова у США

Якщо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Завершує рядок тексту повідомлення без нового рядка, що замикає. Ця послідовність 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). Форматований рядоктоді буде "Бі Боб Білл".

Специфікатори формату з плаваючою точкою – e, E, f та g – не підтримуються. Для обхідного шляху потрібно використовувати функціюStringCchPrintf, щоб форматувати число з плаваючою комою у тимчасовому буфері, а потім використовувати цей буфер як рядок вставки.

Вставки, які використовують префіксI64, обробляються як два 32-розрядні параметри. Вони повинні використовуватися перед тим, як використовуються наступні параметри.

Зверніть увагу!на те, що може бути легше для Вас використовуватиStringCchPrintfзамість цього префікса.

Будь-який інший символ нецифри після символу відсотка форматується у повідомленні без символу відсотка. Нижче – деякі приклади.

Форматуючий рядок

Остаточний висновок

%%Одиничний знак відсотка.%spaceОдиничний пробіл. Цей форматуючий рядок може бути використаний, щоб гарантувати відповідну кількість пробілів у рядку тексту повідомлення.%.Поодинока точка. Цей форматуючий рядок може бути використаний для включення одиничної точки на початку рядка, не завершуючи визначення тексту повідомлення.%!Одиничний знак оклику. Цей форматуючий рядок може бути використаний, щоб увімкнути знак оклику безпосередньо після вставки без того, щоб він був прийнятий початком форматуючого рядка.%nЖорсткий розрив рядка, коли форматуючий рядок діє наприкінці рядка. Цей форматуючий рядок корисний, коли функціяFormatMessageпостачає звичайні розриви рядка, таким чином повідомлення розміщується у певному розмірі.%rЖорстке повернення каретки без замикаючого знака перекладу на новий рядок.%tПоодинока позиція табуляції.

Зауваження щодо безпеки

Якщо ця функція викликана без прапорцяFORMAT_MESSAGE_IGNORE_INSERTS, то параметрArgumentsповинен містити в собі досить багато параметрів, щоб задовольнити всі послідовності вставки в рядку повідомлення, і вони повинні мати коректний тип. З цієї причини, не використовуйте ненадійні або невідомі рядки повідомлень з увімкненими вставками, тому що вони можуть містити в собі більше послідовностей включення, ніж, параметрArgumentsзабезпечує, або вони можуть мати помилковий тип . Зокрема небезпечно отримувати випадкові коди системних помилок, повернутих зAPIта використання прапорцяFORMAT_MESSAGE_FROM_SYSTEMбез прапорцяFORMAT_MESSAGE_IGNORE_INSERTS.

Демонстраційний код [C++]

ФункціяFormatMessageможе бути використана для отримання рядків повідомлення про помилки для кодів системних помилок, повернутих функцієюGetLastError. Приклад дивись у статтіОтримання останнього коду помилки. Нижченаведені приклади також демонструють використання функціїFormatMessage.

Приклад нижче показує, як використовувати масив параметра та специфікатори ширини та точності.

Демонстраційний код

Приклад нижче показує, як реалізувати попередній приклад, використовуючиva_list.

Дивись також

Огляд Обробка помилок, Функції, що використовуються при обробці помилок, Ресурс MESSAGETABLE, Компілятор повідомлення, Таблиці повідомлень