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


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

Функция службы 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 внутри суррогата.

Например, если ЮНИКОД не определен во время компиляции, все вызовы в примерах к функции WriteFmtUserTypeStg COM-служба фактически изменяются макросами на вызовы функции 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;
  }