如何從 ANSI 轉換成 Unicode & Unicode 以 ANSI OLE

文章翻譯 文章翻譯
文章編號: 138813 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

結論

傳遞至並從 32 位元 OLE API 和介面方法收到的所有字串都使用 Unicode。這需要使用 ANSI 字串傳遞給 OLE 之前將它們轉換成 Unicode,並將從 OLE 接收到 ANSI [Unicode 字串轉換的應用程式。本文將告訴您如何可以完成這些轉換。

其他相關資訊

Windows NT 實作 Unicode (或寬字元) 和接受字串參數的 Win32 函式的 ANSI 版本。然而 Windows 95 未實作大部分的 Win32 函式接受字串參數的 Unicode 版本。相反地它會實作僅 ANSI 版本的這些函式。

主要的例外狀況,這項規則是 32 位元 OLE。32 位元 OLE API 和 Windows NT 和 Windows 95 上的介面方法是以獨佔模式使用 Unicode。 這些函式的 ANSI 版本未實作 Windows NT 或 Windows 95 上。

這表示必須在 Windows 95 與 Windows NT 上執行的 32 位元應用程式必須使用非-OLE Win32 函式的 ANSI 版本,而且必須 ANSI 字串前將轉換為 Unicode 傳遞給 OLE。

只在 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;

}
				
範例使用這些函式的是,如下所示。CoTaskMemFree 用來如果 CoTaskMemAlloc 已用它來配置字串釋放已轉換的字串。轉換後的字串必須不釋放如果透過輸出參數傳回至另一個的 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);
				
可在 Microsoft 基礎類別 (MFC) 原始程式碼的隨附 Visual C++ 4.0 編譯器中找到另一個範例的 ANSI/Unicode 轉換常式。這些常式所述 MFC Technote 59: 巨 '使用 MFC MBCS/Unicode 轉換集'。定義是在 \msdev\mfc\include\afxpriv.h OLE2T、 T2OLE、 OLE2CT、 T2COLE、 A2W、 W2A、 A2CW、 W2CA 及 USES_CONVERSION 這些巨集。請參閱 AfxA2WHelper 和 AfxW2AHelper \msdev\mfc\src 以及在 MFC 原始程式碼中 \msdev\mfc\src OLE2T、 T2OLE、 OLE2CT 和 T2COLE 使用 MFC 原始程式碼中。這些函式,允許程式碼進行編譯可能是 Unicode 或 ANSI 取決於是否已經造成 _UNICODE 前置處理器定義。比方說 CreateFileMoniker 在上述範例中可以被進行呼叫,如下所示與 MFC 巨集,:
USES_CONVERSION;
GetOpenFileName(&ofn);
CreateFileMoniker(T2OLE(ofn.lpstrFile), &pmk);
				
如果定義 _UNICODE T2OLE 定義如下:
inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
				
如果不定義 _UNICODE T2OLE 定義如下:
#define T2OLE(lpa) A2W(lpa)
				
T2OLE 的 T 表示型別轉換成一個 OLE 字串 (Unicode 字串) 是 Unicode 字串定義 _UNICODE 時和 ANSI 字串不定義 _UNICODE 時。同樣地 LPTSTR 是 Unicode 字串定義 _UNICODE 時的指標,而是為 ANSI 字串的指標時,定義 _UNICODE 未定義。定義 _UNICODE 時 T2OLE 並不會執行任何轉換 (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 轉換常式可以找到 Microsoft 系統日誌]) 中的 OLE 的 Don 方塊資料行中八月 1995 Vol.10 [否]。 8,版面 86。Don 方塊定義使用轉換運算子會傳回轉換的 Unicode/ANSI 字串的 C + + 類別。當物件超出範圍時,會自動釋放配置的空間。配置使用 OLE 配置器,並不釋放配置的空間可透過在不足或外傳參數傳遞的字串,這個類別可以進行修改。

類別的其中之一,String16,從 Don 方塊資料行,它會將一個 ANSI 字串轉換為 Unicode,如下。另一個類別,String8 這一個類似的用於 Unicode 轉換成 ANSI。從先前的範例 CreateFileMoniker 呼叫可以與這個類別,如下所示進行:
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
上述程式碼中建立 String16 的執行個體。類別的建構函式會將 ANSI 字串轉換為 Unicode。語言實作會呼叫轉型運算子、 運算子 const wchar_t *、 轉型成 CreateFileMoniker 的第一個參數型別的這個參數。轉換運算子會傳回 Unicode 字串傳遞至 CreateFileMoniker。物件會在步超出範圍時解構。
// 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
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本: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