Поделиться через


Рекомендации по Юникоду

Для функции-службы WriteFmtUserTypeStg , используемой в методе IPaper::Save , требуются строковые параметры Юникода. Это относится к вызовам службы COM/OLE, которые принимают строковые параметры. При компиляции для строк ANSI ожидаемые параметры Юникода необходимо преобразовать из ANSI в Юникод. Этот процесс достигается с помощью некоторых макросов в APPUTIL.h, которые могут скрывать преобразования. Например, см . раздел WriteFmtUserTypeStg.

Следующий вызов отображается в методе Save .

WriteFmtUserTypeStg(pIStorage, m_ClipBdFmt, TEXT(CLIPBDFMT_STR));

При компиляции StoServe для ANSI (не для Юникода) этот вызов фактически сводится к вызову внутренней суррогатной функции APPUTIL. Для этой поддержки в Apputil.h используется следующая схема макросов, которая является включенным файлом во всем примере кода . CPP-файлы.

#if !defined(UNICODE)

  STDAPI A_WriteFmtUserTypeStg(IStorage*, CLIPFORMAT, LPSTR);

  #if !defined(_NOANSIMACROS_)

  #undef WriteFmtUserTypeStg
  #define WriteFmtUserTypeStg(a, b, c) A_WriteFmtUserTypeStg(a, b, c)

  #endif

  #endif

В схеме используются функции вызова суррогатных служб. Версии вызовов ANSI начинаются с A_. Эти суррогатные функции ANSI реализованы в Apputil.cpp. Они используются при компиляции примера кода для строк ANSI (значение по умолчанию в файлах makefile). Функции службы, заменяемые суррогатами, поддерживают только строковые параметры Юникода. Это приводит к принудительному преобразованию строк из ANSI в Юникод до выполнения реального вызова службы COM/OLE внутри суррогата.

Например, если юникод не определен во время компиляции, все вызовы в примерах функции COM WriteFmtUserTypeStg фактически изменяются макросами в вызовы функции A_WriteFmtUserTypeStg, реализованной в APPUTIL. CPP. Эта функция принимает входной указатель строки ANSI, преобразует его в копию Юникода и передает эту копию Юникода в качестве строкового параметра в вызове фактической функции WriteFmtUserTypeStg .

Ниже приведен A_WriteFmtUserTypeStg из Apputil.cpp.

STDAPI A_WriteFmtUserTypeStg(
           IStorage* pIStorage,
           CLIPFORMAT ClipFmt,
           LPSTR pszUserType)
  {
    HRESULT hr = E_INVALIDARG;
    WCHAR wszUc[MAX_PATH];

    if (NULL != pszUserType)
    {
      // Convert from ANSI in pszUserType to Unicode in wszUc.
      AnsiToUc(pszUserType, wszUc, MAX_PATH);

      // Use the Unicode string in the actual service call.
      hr = WriteFmtUserTypeStg(pIStorage, ClipFmt, wszUc);
    }

    return hr;
  }