Cómo convertir de ANSI a Unicode y Unicode a ANSI de OLE

Seleccione idioma Seleccione idioma
Id. de artículo: 138813 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

Resumen

Todas las cadenas que se pasan a y recibidas de OLE API de 32 bits y los métodos de interfaz utilizan Unicode. Esto requiere aplicaciones que utilizan cadenas ANSI para convertir a Unicode antes de pasarlas a OLE y para convertir las cadenas de Unicode que se reciben desde OLE a ANSI. En este artículo se muestra cómo se pueden realizar estas conversiones.

Más información

Windows NT implementa Unicode (o carácter ancho) y las versiones de ANSI de las funciones de Win32 que toman parámetros de cadena. Sin embargo Windows 95 no implementa la versión Unicode de la mayoría funciones de Win32 que toman parámetros de cadena. En su lugar implementa sólo las versiones ANSI de estas funciones.

Una excepción importante a esta regla es OLE de 32 bits. OLE API de 32 bits y los métodos de interfaz de Windows NT y Windows 95 utilizan Unicode exclusivamente. Versiones ANSI de estas funciones no están implementadas en Windows NT o Windows 95.

Esto significa que una aplicación de 32 bits que necesita para ejecutarse en Windows 95 y Windows NT debe utilizar las versiones de ANSI de las funciones no OLE Win32 y debe convertir cadenas ANSI a Unicode antes de que pasen a OLE.

Una aplicación de Unicode de 32 bits que se ejecuta sólo en Windows NT no es preciso utilizar las funciones de conversión de ANSI o Unicode.

Win32 proporciona MultiByteToWideChar y WideCharToMultiByte para convertir cadenas ANSI a Unicode y cadenas Unicode a ANSI. Este artículo proporciona AnsiToUnicode y UnicodeToAnsi, que utiliza estas funciones para la conversión de ANSI o 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;

}
				
uso de ejemplo de estas funciones es como sigue. Se utiliza CoTaskMemFree para liberar la cadena convertida si CoTaskMemAlloc utilizado para asignar la cadena. La cadena convertida debe no liberar si se devuelve a través de un parámetro out a otro componente OLE, ya que dicho componente es responsable de liberar la cadena. LPOLESTR es un puntero a una cadena 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);

}
				
Nota : comentarios en AnsiToUnicode y UnicodeToAnsi relacionada con el asignador se utiliza para asignar la cadena convertida. Es necesario se utiliza sólo si la cadena resultante se pasará a otro componente OLE y si dicho componente puede liberar la cadena CoTaskMemAlloc (el asignador OLE). Esto significa que las cadenas que se pasa como parámetros in a métodos de interfaz OLE no es preciso utilizar el asignador OLE. Cadenas que se pasan como parámetros de salida o devuelto a través de los parámetros out o parámetros de salida se deben asignar mediante el asignador OLE.

Constantes de cadena se pueden convertir a Unicode en tiempo de compilación mediante la macro OLESTR. Por ejemplo:
CreateFileMoniker(OLESTR("c:\\boo\\har.doc"), &pmk);
				
otro ejemplo de rutinas de conversión de ANSI o Unicode puede encontrarse en el código de Foundation Classes (MFC) que se suministra con el compilador de Visual C++ 4.0. Estas rutinas se describen en MFC Nota técnica 59: 'Mediante macros de conversión de MBCS/Unicode de MFC'. La definición de estas macros OLE2T T2OLE, OLE2CT, T2COLE, A2W, W2A, A2CW, W2CA y USES_CONVERSION están en \msdev\mfc\include\afxpriv.h. Vea también AfxA2WHelper y AfxW2AHelper en el código de origen MFC de \msdev\mfc\src y el uso de OLE2T T2OLE, OLE2CT y T2COLE en el código de origen MFC de \msdev\mfc\src. Estas funciones permitir código compilarse para Unicode o ANSI dependiendo de si se ha realizado la definición de preprocesador _UNICODE. Por ejemplo, la llamada CreateFileMoniker en el ejemplo anterior se puede realizar como sigue con las macros de MFC:
USES_CONVERSION;
GetOpenFileName(&ofn);
CreateFileMoniker(T2OLE(ofn.lpstrFile), &pmk);
				
si se define _UNICODE, T2OLE se define como sigue:
inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
				
si no está definido _UNICODE, T2OLE se define como sigue:
#define T2OLE(lpa) A2W(lpa)
				
T en T2OLE indica que el tipo se convierte en una cadena OLE (la cadena Unicode) es una cadena de Unicode cuando se define _UNICODE y una cadena ANSI cuando no está definido _UNICODE. De forma similar LPTSTR se define como un puntero a una cadena Unicode cuando se define _UNICODE y como un puntero a una cadena ANSI no está definido _UNICODE. T2OLE no realizar ninguna conversión cuando se define _UNICODE (LPTSTR == LPOLESTR). Cuando no está definido Unicode, se denomina A2W. A2W convierte una cadena ANSI en Unicode como sigue:
#define A2W(lpa) (\ 
        ((LPCSTR)lpa == NULL) ? NULL : (\ 
            _convert = (strlen(lpa)+1),\ 
            AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)\ 
        )\ 

)
				
AfxA2WHelper utiliza MultiByteToWideChar para realizar la conversión.

Las macros de conversión de MFC utilizan _alloca para asignar espacio de la pila del programa para la cadena convertida. El espacio se desasignan automáticamente cuando finalice la llamada al procedimiento. OLE requiere el asignador OLE que se utilizará para todas las cadenas (datos) que se asigna un componente y liberadas por otro. Esto significa que pasan cadenas mediante parámetros de salida y en-out-parámetros de interfaces OLE deben asignarse con el asignador OLE. No necesitan ser asignadas en parámetros con el asignador OLE porque el llamador es responsable de liberarlos. La mayoría de los Vinculación o incrustación OLE interfaces y API pasan cadenas como parámetros in. Por lo tanto, las macros de conversión de MFC pueden utilizarse en la mayoría de los casos. No se puede utilizar las macros de conversión de MFC para parámetros de salida o para devolver valores mediante parámetros de salida porque no asignan espacio utilizando el asignador OLE. En estos casos, pueden utilizarse AnsiToUnicode y UnicodeToAnsi.

Aún otro conjunto de rutinas de conversión Unicode/ANSI puede encontrarse en columna de Don Box OLE en Microsoft Systems Journal, agosto de 1995, vol. 10 Nº 8, página 86. Don Box define una clase de C++ con un operador de conversión que devolverá una cadena Unicode/ANSI convertido. El espacio asignado se libera automáticamente cuando el objeto queda fuera del ámbito. Esta clase se puede modificar para asignar mediante el asignador OLE y no liberar el espacio asignado para las cadenas que se pasan a través de salida o los parámetros out.

Una de las clases String16, de columna de Don Box que convierte una cadena ANSI a Unicode, sigue. Otra clase, String8, que es similar a éste se utiliza ANSI para la conversión Unicode. La llamada CreateFileMoniker del ejemplo anterior puede realizarse de manera con esta clase:
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
en el código anterior, se crea una instancia de String16. El constructor de la clase convertirá la cadena ANSI a Unicode. La implementación del lenguaje llamará el operador de conversión, el operador const wchar_t *, para convertir este parámetro al tipo de primer parámetro del CreateFileMoniker. El operador de conversión devolverá la cadena Unicode que se pasa a CreateFileMoniker. El objeto se destruir en va fuera del ámbito.
// 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;

}
				

Propiedades

Id. de artículo: 138813 - Última revisión: miércoles, 16 de marzo de 2005 - Versión: 2.4
La información de este artículo se refiere a:
  • Microsoft OLE 4.0 sobre las siguientes plataformas
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
Palabras clave: 
kbmt kbcode kbhowto kbprogramming KB138813 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 138813

Enviar comentarios

 

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