如何从 ANSI 转换为 Unicode 和 Unicode,为 ANSI ole

文章翻译 文章翻译
文章编号: 138813 - 查看本文应用于的产品
展开全部 | 关闭全部

概要

正在传递和从 32 位 OLE api 和接口方法收到的所有字符串都使用 Unicode。这需要使用 ANSI 字符串,将它们转换为 Unicode 之前将它们传递给 OLE,并将转换为 ANSI OLE 从收到的 Unicode 字符串的应用程序。本文演示了如何完成这些转换。

更多信息

Windows NT 实现 Unicode (或宽字符) 和 ANSI 版本的 Win32 函数采用字符串参数。但是 Windows 95 不实现大多数的 Win32 函数采用字符串参数的 Unicode 版本。相反,它实现仅 ANSI 版本的这些函数。

此规则的一个主要的例外是 32 位 OLE。32 位 OLE api 和 Windows NT 和 Windows 95 的接口方法以独占方式使用 Unicode。 在 Windows NT 或 Windows 95 未实现的这些函数的 ANSI 版本。

这意味着需要在 Windows 95 和 Windows NT 上运行的 32 位应用程序必须使用非 OLE Win32 函数的 ANSI 版本和它们传递到 OLE 之前必须转换为 Unicode 的 ANSI 字符串。

仅在 Windows NT 运行 32-位 Unicode 应用程序不需要使用任何 ANSI/unicode 转换函数。

Win32 提供 MultiByteToWideChar 和 WideCharToMultiByte 将为 Unicode 的 ANSI 字符串和 Unicode 字符串转换为 ANSI。本文提供了 AnsiToUnicode 和 UnicodeToAnsi,ANSI/unicode 转换为使用这些函数。
/*
 * AnsiToUnicode converts the ANSI string pszA to a Unicode string
 * and returns the Unicode string through ppszW. Space for the
 * the converted string is allocated by AnsiToUnicode.
 */ 

HRESULT __fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW)
{

    ULONG cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (NULL == pszA)
    {
        *ppszW = NULL;
        return NOERROR;
    }

    // Determine number of wide characters to be allocated for the
    // Unicode string.
    cCharacters =  strlen(pszA)+1;

    // Use of the OLE allocator is required if the resultant Unicode
    // string will be passed to another COM component and if that
    // component will free it. Otherwise you can use your own allocator.
    *ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2);
    if (NULL == *ppszW)
        return E_OUTOFMEMORY;

    // Covert to Unicode.
    if (0 == MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters,
                  *ppszW, cCharacters))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszW);
        *ppszW = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }

    return NOERROR;
/*
 * UnicodeToAnsi converts the Unicode string pszW to an ANSI string
 * and returns the ANSI string through ppszA. Space for the
 * the converted string is allocated by UnicodeToAnsi.
 */ 

HRESULT __fastcall UnicodeToAnsi(LPCOLESTR pszW, LPSTR* ppszA)
{

    ULONG cbAnsi, cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (pszW == NULL)
    {
        *ppszA = NULL;
        return NOERROR;
    }

    cCharacters = wcslen(pszW)+1;
    // Determine number of bytes to be allocated for ANSI string. An
    // ANSI string can have at most 2 bytes per character (for Double
    // Byte Character Strings.)
    cbAnsi = cCharacters*2;

    // Use of the OLE allocator is not required because the resultant
    // ANSI  string will never be passed to another COM component. You
    // can use your own allocator.
    *ppszA = (LPSTR) CoTaskMemAlloc(cbAnsi);
    if (NULL == *ppszA)
        return E_OUTOFMEMORY;

    // Convert to ANSI.
    if (0 == WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, *ppszA,
                  cbAnsi, NULL, NULL))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszA);
        *ppszA = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }
    return NOERROR;

}
				
这些函数的示例使用的是,如下所示。若要释放转换后的字符串,如果 CoTaskMemAlloc 被用来分配字符串使用 CoTaskMemFree。转换后的字符串必须释放不能通过一个输出参数返回到另一个 OLE 组件,如果因为该组件负责释放该字符串。LPOLESTR 是一个指向 Unicode 字符串的指针。
// The following code gets an ANSI filename that is specified by the
// user in the OpenFile common dialog. This file name is converted into
// a Unicode string and is passed to the OLE API CreateFileMoniker. The
// Unicode string is then freed.

OPENFILENAME ofn;
LPOLESTR pszFileNameW;
LPMONIKER pmk;
:

// Get file name from OpenFile Common Dialog. The ANSI file name will
// be placed in ofn.lpstrFile

GetOpenFileName(&ofn);
:
AnsiToUnicode(ofn.lpstrFile, &pszFileNameW);
CreateFileMoniker(pszFileNameW, &pmk);
CoTaskMemFree(pszFileNameW);

// The following code implements IOleInPlaceFrame::SetStatusText.
// The lpszStatusText string, that is received from another OLE
// component, uses Unicode. The string is converted to ANSI before it is
// passed to the ANSI version of SetWindowText. Windows 95 supports only
// the ANSI version of SetWindowText.

COleInPlaceFrame::SetStatusText(LPCOLESTR pszStatusTextW)
{

    LPSTR pszStatusTextA;
    UnicodeToAnsi(pszStatusTextW, &pszStatusTextA);
    SetWindowText(m_hwndStatus, pszStatusTextA);
    CoTaskMemFree(pszStatusTextA);

}
				
: AnsiToUnicode 和 UnicodeToAnsi 有关该分配器用来分配转换后的字符串中的批注。仅当在结果字符串将传递到另一个 OLE 组件,并且如果该组件可以释放该字符串使用需要 CoTaskMemAlloc (OLE 分配器)。这意味着字符串作为参数中传递给 OLE 接口方法不需要使用 OLE 分配器。必须使用 OLE 分配器分配作为在输出参数传递或通过输出参数或 $ 在输出参数返回的字符串。

字符串常数可以转换为 Unicode 在编译时通过使用 OLESTR 宏。例如:
CreateFileMoniker(OLESTR("c:\\boo\\har.doc"), &pmk);
				
随 Visual c + + 4.0 编译器一起提供的 Microsoft 基础类 (MFC) 源代码中找不到的 ANSI/unicode 转换例程的另一个示例。这些例程所述 MFC Technote 59: 使用 MFC MBCS/unicode 转换宏。这些宏 OLE2T、 T2OLE、 OLE2CT、 T2COLE、 A2W、 W2A、 A2CW、 W2CA 和 USES_CONVERSION 处于 \msdev\mfc\include\afxpriv.h 定义。另请参阅 AfxA2WHelper 和 AfxW2AHelper \msdev\mfc\src 和 OLE2T、 T2OLE、 OLE2CT 和 T2COLE MFC 源代码 \msdev\mfc\src 中使用 MFC 源代码中。这些函数,具体取决于是否已建立 _UNICODE 预处理器定义编译为 Unicode 或 ANSI 代码。例如对于在将具有 MFC 宏,如下所示进行 CreateFileMoniker 调用,在上面的示例:
USES_CONVERSION;
GetOpenFileName(&ofn);
CreateFileMoniker(T2OLE(ofn.lpstrFile), &pmk);
				
T2OLE 定义如果定义的 _UNICODE,如下所示:
inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
				
T2OLE 定义如果未定义 _UNICODE,则如下:
#define T2OLE(lpa) A2W(lpa)
				
T T2OLE 中的表示的类型被转换为 OLE 字符串 (Unicode 字符串) 时未定义 _UNICODE,则为所定义 _UNICODE 时对 Unicode 字符串和一个 ANSI 字符串。同样 LPTSTR 时定义为指向定义 _UNICODE 时对 Unicode 字符串的指针,而为 ANSI 字符串的指针不被定义的 _UNICODE。T2OLE 不执行任何转换,定义 _UNICODE 时 (LPTSTR LPOLESTR = =)。当未定义 Unicode,则称为 A2W。将 A2W 的 ANSI 字符串转换为 Unicode,如下所示:
#define A2W(lpa) (\ 
        ((LPCSTR)lpa == NULL) ? NULL : (\ 
            _convert = (strlen(lpa)+1),\ 
            AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)\ 
        )\ 

)
				
AfxA2WHelper 使用 MultiByteToWideChar 来执行转换。

MFC 转换宏使用 _alloca 从转换后的字符串的程序堆栈中分配空间。过程调用已完成后,会自动释放空间。OLE 要求要使用的所有字符串 (数据) 将由一个组件分配和释放由另一个 OLE 分配器。这意味着通过输出参数传递的字符串必须与 OLE 分配器在分配中的传出的参数的 OLE 接口。在参数需要不分配与 OLE 分配器,因为调用方负责释放它们。大多数链接/嵌入 OLE 接口和 API 传递字符串作为参数中。 因此可以在大多数情况下使用 MFC 转换宏。用于输入输出参数或返回通过输出参数的值,因为它们不分配使用 OLE 分配器的空间,不能使用 MFC 转换宏。在这些情况下,可以使用 AnsiToUnicode 和 UnicodeToAnsi。

但另一套 unicode/ANSI 转换例程可找到在 Don Box 列中的 Microsoft 系统日记中的 OLE 八月 1995年音量 10 号 8 页 86。Don Box 定义使用转换运算符将返回以 unicode/ANSI 转换的字符串的 c + + 类。当对象超出范围时,会自动释放分配的空间。使用 OLE 分配器分配并不释放已分配的空间,通过在出或输出参数传递的字符串,可以修改此类。

一个类,String16,从 Don Box 列将为 ANSI 字符串转换为 Unicode,它遵循。另一个类,String8,与此类似的用于 ANSI 到 Unicode 转换。使用此类,如下所示进行 CreateFileMoniker 调用前面的示例中:
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
上面的代码中创建的 String16 实例。在类的构造函数会将 ANSI 字符串转换为 Unicode。语言实现将调用强制转换运算符,运算符 const wchar_t *、 强制转换此参数的 CreateFileMoniker 的第一个参数的类型。强制转换运算符将返回传递给 CreateFileMoniker Unicode 字符串。该对象将在转出的范围时销毁。
// String16 //////////////////////////////////////////////////////// 
// Shim class that converts both 8-bit (foreign) and
// 16-bit (native) strings to 16-bit wideness

class String16 {
public:

// native and foreign constructors
    String16(const char *p8);
    String16(const wchar_t *p16);

// non-virtual destructor (this class is concrete)

  ~String16(void);

// native conversion operator

  operator const wchar_t * (void) const;
private:

// native wideness string
    wchar_t *m_sz;
// is foreign??
    BOOL m_bIsForeign;

// protect against assignment!

  String16(const String16&);

    String16& operator=(const String16&);
};

// native constructor is a pass-through

inline String16::String16(const wchar_t *p16)
: m_sz((wchar_t *)p16), m_bIsForeign(FALSE)
{
}

// simply give out the native wideness string

inline String16::operator const wchar_t * (void) const
{
  return m_sz;
}

// foreign constructor requires allocation of a native
// string and conversion

inline String16::String16(const char *p8)
: m_bIsForeign(TRUE)
{

// calculate string length

  size_t len = strlen(p8);

// calculate required buffer size (some characters may
// already occupy 16-bits under DBCS)

  size_t size = mbstowcs(0, p8, len) + 1;

// alloc native string and convert

  if (m_sz = new wchar_t[size])

    mbstowcs(m_sz, p8, size);

}

// delete native string only if synthesized in foreign constructor

inline String16::~String16(void) {
  if (m_bIsForeign)

    delete[] m_sz;

}
				

属性

文章编号: 138813 - 最后修改: 2005年3月16日 - 修订: 2.4
这篇文章中的信息适用于:
  • Microsoft OLE 4.0?当用于
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
关键字:?
kbmt kbcode kbhowto kbprogramming KB138813 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 138813
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com