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;
  }