Bagaimana mengkonversi dari ANSI untuk Unicode & Unicode untuk ANSI untuk OLE

Terjemahan Artikel Terjemahan Artikel
ID Artikel: 138813
Perbesar semua | Perkecil semua

RINGKASAN

Semua string yang dilewatkan ke dan menerima dari 32-bit OLE api dan antarmuka metode menggunakan Unicode. Ini memerlukan aplikasi yang menggunakan ANSI string untuk mengkonversikannya ke Unicode sebelum melewati mereka untuk OLE dan untuk mengkonversi string Unicode yang diterima dari OLE ANSI. Ini Artikel menunjukkan bagaimana konversi ini dapat dilakukan.

INFORMASI LEBIH LANJUT

Windows NT mengimplementasikan Unicode (atau karakter lebar) dan versi ANSI Win32 fungsi yang mengambil parameter string. Namun Windows 95 tidak menerapkan versi Unicode Win32 sebagian besar fungsi-fungsi yang mengambil string parameter. Alih-alih menerapkan hanya ANSI versi ini fungsi.

Besar pengecualian aturan ini adalah OLE 32-bit. 32-bit OLE api dan antarmuka metode pada Windows NT dan Windows 95 menggunakan Unicode secara eksklusif. ANSI versi fungsi-fungsi ini tidak dilaksanakan baik pada Windows NT atau Windows 95.

Ini berarti bahwa aplikasi 32-bit yang perlu berjalan di kedua Windows 95 dan Windows NT harus menggunakan versi ANSI dari non - OLE Win32 fungsi dan harus mengubah ANSI string untuk Unicode sebelum mereka dilewatkan ke OLE.

Tidak perlu menggunakan 32-bit Unicode aplikasi yang berjalan pada Windows NT setiap ANSI/Unicode konversi fungsi.

Win32 menyediakan MultiByteToWideChar dan WideCharToMultiByte untuk mengkonversi ANSI string untuk Unicode dan Unicode string untuk ANSI. Artikel ini menyediakan AnsiToUnicode dan UnicodeToAnsi, yang menggunakan fungsi-fungsi ini untuk ANSI/Unicode konversi.
/*
 * 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;

}
				
Contoh penggunaan fungsi-fungsi ini adalah sebagai berikut. CoTaskMemFree digunakan untuk gratis string dikonversi jika CoTaskMemAlloc digunakan untuk mengalokasikan string. String dikonversi harus tidak dibebaskan jika kembali melalui yang keluar-parameter lain OLE komponen, karena komponen bertanggung jawab untuk membebaskan string. LPOLESTR adalah sebuah pointer ke Unicode string.
// 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);

}
				
CATATAN: Komentar di AnsiToUnicode dan UnicodeToAnsi mengenai pengalokasi yang digunakan untuk mengalokasikan string dikonversi. CoTaskMemAlloc (OLE pengalokasi) diperlukan untuk hanya dapat digunakan jika string resultan akan dilewatkan ke komponen OLE lain dan jika komponen tersebut dapat bebas string. Ini berarti bahwa string yang berlalu sebagai dalam parameter untuk OLE antarmuka metode perlu menggunakan OLE pengalokasi. String yang berlalu sebagai di-out-parameter atau kembali melalui keluar-parameter atau di- keluar-parameter harus dialokasikan menggunakan OLE pengalokasi.

Konstanta string dapat dikonversi ke Unicode pada waktu kompilasi dengan menggunakan makro OLESTR. Misalnya:
CreateFileMoniker(OLESTR("c:\\boo\\har.doc"), &pmk);
				
Contoh lain dari ANSI/Unicode konversi rutinitas dapat ditemukan di Microsoft Foundation Classes (MFC) kode sumber yang kapal dengan Visual C++ 4.0 kompilator. Rutinitas ini dijelaskan dalam MFC Technote 59: 'Menggunakan MFC MBCS/Unicode konversi macro'. Definisi ini makro OLE2T, T2OLE, OLE2CT, T2COLE, A2W, W2A, A2CW, W2CA dan USES_CONVERSION berada di \msdev\mfc\include\afxpriv.h. Juga melihat AfxA2WHelper dan AfxW2AHelper di kode sumber MFC di \msdev\mfc\src dan penggunaan OLE2T, T2OLE, OLE2CT dan T2COLE di kode sumber MFC di \msdev\mfc\src. Fungsi-fungsi ini memungkinkan kode untuk menyusun baik untuk Unicode atau ANSI tergantung pada apakah _UNICODE preprocessor definisi yang telah dibuat. Sebagai contoh, CreateFileMoniker panggilan contoh di atas dapat dilakukan sebagai berikut dengan macro MFC:
USES_CONVERSION;
GetOpenFileName(&ofn);
CreateFileMoniker(T2OLE(ofn.lpstrFile), &pmk);
				
Jika _UNICODE didefinisikan, T2OLE didefinisikan sebagai berikut:
inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
				
Jika _UNICODE tidak ditentukan, T2OLE didefinisikan sebagai berikut:
#define T2OLE(lpa) A2W(lpa)
				
T di T2OLE menunjukkan bahwa jenis yang dikonversi ke OLE string (Unicode string) adalah serangkaian Unicode ketika _UNICODE didefinisikan dan sebuah ANSI string ketika _UNICODE tidak didefinisikan. Demikian pula LPTSTR didefinisikan sebagai pointer ke string Unicode ketika _UNICODE didefinisikan dan sebagai pointer ke ANSI string ketika _UNICODE tidak didefinisikan. T2OLE tidak melakukan apapun konversi ketika _UNICODE didefinisikan (LPTSTR == LPOLESTR). Ketika Unicode adalah tidak didefinisikan, disebut A2W. A2W mengkonversi string ANSI-untuk Unicode sebagai berikut:
#define A2W(lpa) (\ 
        ((LPCSTR)lpa == NULL) ? NULL : (\ 
            _convert = (strlen(lpa)+1),\ 
            AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)\ 
        )\ 

)
				
AfxA2WHelper menggunakan MultiByteToWideChar untuk melakukan konversi.

Macro konversi MFC menggunakan _alloca untuk mengalokasikan ruang dari program tumpukan untuk string dikonversi. Ruang ini secara otomatis deallocated ketika panggilan prosedur telah selesai. OLE memerlukan OLE pengalokasi untuk digunakan untuk semua string (data) yang akan dialokasikan oleh satu komponen dan dibebaskan oleh orang lain. Ini berarti bahwa string melewati keluar- parameter dan di-out-parameter OLE antarmuka harus dialokasikan dengan OLE pengalokasi. Dalam parameter tidak perlu dialokasikan dengan OLE pengalokasi karena penelpon bertanggung jawab untuk membebaskan mereka. Sebagian besar Menghubungkan/Embedding OLE antarmuka dan API lulus string sebagai dalam parameter. Akibatnya MFC konversi macro dapat digunakan dalam banyak kasus. The MFC konversi makro tidak dapat digunakan untuk parameter dalam keluar atau untuk kembali nilai-nilai melalui parameter keluar karena mereka tidak mengalokasikan ruang menggunakan OLE pengalokasi. AnsiToUnicode dan UnicodeToAnsi dapat digunakan dalam kasus ini.

Namun serangkaian Unicode/ANSI konversi rutinitas dapat ditemukan di Don Kolom kotak pada OLE di Microsoft sistem Journal, Agustus 1995, Vol. 10 No. 8, halaman 86. Don kotak mendefinisikan kelas C++ dengan operator pemain yang akan kembali string Unicode/ANSI dikonversi. Ruang yang dialokasikan secara otomatis dibebaskan ketika objek berjalan keluar dari lingkup. Kelas ini dapat dimodifikasi untuk mengalokasikan menggunakan OLE pengalokasi dan tidak gratis mengalokasikan ruang untuk string yang melewati dalam keluar atau keluar- parameter.

Salah satu kelas, String16, dari kolom Don kotak yang mengubah ANSI string untuk Unicode, berikut. Kelas lain, String8, yang mirip satu ini digunakan untuk ANSI untuk Unicode konversi. The CreateFileMoniker panggilan dari contoh sebelumnya dapat dibuat sebagai berikut dengan kelas ini:
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
Pada kode diatas, contoh String16 dibuat. Konstruktor kelas akan mengkonversi ANSI string untuk Unicode. Bahasa implementasi akan memanggil pemain operator, operator const wchar_t *, untuk pemain parameter ini jenis CreateFileMoniker's pertama parameter. Operator pemain akan kembali string Unicode yang berlalu untuk CreateFileMoniker. Objek akan merusak ketika di keluar lingkup.
// 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;

}
				

Properti

ID Artikel: 138813 - Kajian Terakhir: 14 September 2011 - Revisi: 2.0
Kata kunci: 
kbcode kbhowto kbprogramming kbmt KB138813 KbMtid
Penerjemahan Mesin
PENTING: Artikel ini diterjemahkan menggunakan perangkat lunak mesin penerjemah Microsoft dan bukan oleh seorang penerjemah. Microsoft menawarkan artikel yang diterjemahkan oleh seorang penerjemah maupun artikel yang diterjemahkan menggunakan mesin sehingga Anda akan memiliki akses ke seluruh artikel baru yang diterbitkan di Pangkalan Pengetahuan (Knowledge Base) dalam bahasa yang Anda gunakan. Namun, artikel yang diterjemahkan menggunakan mesin tidak selalu sempurna. Artikel tersebut mungkin memiliki kesalahan kosa kata, sintaksis, atau tata bahasa, hampir sama seperti orang asing yang berbicara dalam bahasa Anda. Microsoft tidak bertanggung jawab terhadap akurasi, kesalahan atau kerusakan yang disebabkan karena kesalahan penerjemahan konten atau penggunaannya oleh para pelanggan. Microsoft juga sering memperbarui perangkat lunak mesin penerjemah.
Klik disini untuk melihat versi Inggris dari artikel ini:138813

Berikan Masukan

 

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