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