Рекомендации по Юникоду
Функция службы 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;
}