Unicode 注意事项
IPaper::Save 方法中使用的 WriteFmtUserTypeStg 服务函数需要 Unicode 字符串参数。 采用字符串参数的 COM/OLE 服务调用就是这种情况。 编译 ANSI 字符串时,预期的 Unicode 参数需要从 ANSI 转换为 Unicode。 此过程是使用 APPUTIL.h 中的一些宏实现的,这些宏可能会遮挡转换。 例如,请参阅 WriteFmtUserTypeStg。
以下调用显示在 Save 方法中。
WriteFmtUserTypeStg(pIStorage, m_ClipBdFmt, TEXT(CLIPBDFMT_STR));
当 StoServe 编译为 ANSI (而不是 Unicode) 时,此调用实际上会减少到对内部 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 字符串编译代码示例时, (生成文件) 中的默认值时,使用它们。 代理项代替仅支持 Unicode 字符串参数的服务函数。 这强制在代理项内进行真正的 COM/OLE 服务调用之前,将某些字符串从 ANSI 转换为 Unicode。
例如,如果在编译期间未定义 UNICODE,则示例中对 WriteFmtUserTypeStg COM 服务函数的任何调用实际上都由宏更改为对 APPUTIL 中实现的 A_WriteFmtUserTypeStg 函数的调用。Cpp。 此函数接受输入 ANSI 字符串指针,将其转换为 Unicode 副本,并在调用实际 WriteFmtUserTypeStg 函数时将该 Unicode 副本作为字符串参数传递。
下面是 Apputil.cpp 的A_WriteFmtUserTypeStg。
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;
}