На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Друзья, соблюдайте, пожалуйста, правила форума и данного раздела:
Данный раздел не предназначен для вопросов и обсуждений, он содержит FAQ-заготовки для разных языков программирования. Любой желающий может разместить здесь свою статью. Вопросы же задавайте в тематических разделах!
• Если ваша статья может быть перенесена в FAQ соответствующего раздела, при условии, что она будет оформлена в соответствии с Требованиями к оформлению статей.
• Чтобы остальным было проще понять, указывайте в описании темы (подзаголовке) название языка в [квадратных скобках]!
Модераторы: Модераторы
  
> Заменитель Format без SysUtils, [Delphi] Неполный аналог Format без SysUtils для минимизации бинарника
    Format без SysUtils

    Сразу оговорюсь, что это не полный аналог Format, с немного другим синтаксисом (несовместимым - можно применять, если все строки форматирования находятся внутри программы). Используется системная функция FormatMessage. Поддерживаются подстановки строк, целых и pointer-to-hex; поддерживаются спецификаторы ширины и точности. Вещественные числа, региональные установки - не поддерживаются.

    Код
    ExpandedWrap disabled
      // Частично позаимствовано из SysUtils.SysErrorMessage
      function FormatWinapi(const Patt: string; const Args: array of const): string;
      var
        Buffer: PChar;
        Len, i: Integer;
        InternalArgs: array of Pointer;
      begin
        SetLength(InternalArgs, Length(Args));
        for i := Low(InternalArgs) to High(InternalArgs) do
          InternalArgs[i] := Pointer(Args[i].VPointer);
        Len := FormatMessage(
          FORMAT_MESSAGE_FROM_STRING or
          FORMAT_MESSAGE_ARGUMENT_ARRAY or
          FORMAT_MESSAGE_ALLOCATE_BUFFER, PChar(Patt), 0, 0, @Buffer, 0, Pointer(InternalArgs));
        try
          { Convert to Delphi string }
          SetString(Result, Buffer, Len);
        finally
          { Free the OS allocated memory block }
          LocalFree(HLOCAL(Buffer));
        end;
      end;


    Применение
    ExpandedWrap disabled
        MemLog.Lines.Add(FormatWinapi('Мама мыла %1.%nВымыто %2!.2d!%%.%nApplication находится по адресу %3!p!.', ['раму', 9, Application]));


    Результат
    ExpandedWrap disabled
      Мама мыла раму.
      Вымыто 09%.
      Application находится по адресу 7EF49E00.


    Обработка ошибок
    Функция FormatMessage возвращает 0 при ошибке, код ошибки получается через GetLastError. Поскольку мы избавляемся от SysUtils, никаких классов исключений не объявлено, и rais-ить ошибку мы не можем. Варианты решения:
    1) Проверять GetLastError после вызова FormatWinapi.
    2) Проверять результирующую строку после вызова FormatWinapi (при ошибке она будет пуста).
    3) Создать собственный класс Exception и rais-ить его.

    Инфо:
    FormatMessage
    printf Type Field Characters
    Codero ergo sum
    // Программирую — значит, существую
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script Execution time: 0,2067 ]   [ 17 queries used ]   [ Generated: 12.12.18, 09:44 GMT ]