Como converter de ANSI em Unicode e Unicode para ANSI para OLE

Traduções deste artigo Traduções deste artigo
ID do artigo: 138813 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Sumário

Todas as seqüências que são passadas para e recebidas de 32 bits OLE APIs e métodos de interface usam Unicode. Isso requer aplicativos que usam seqüências de caracteres ANSI para convertê-los para Unicode antes de transmiti-los ao OLE e converter cadeias de caracteres Unicode que são recebidas de OLE para ANSI. Este artigo demonstra como essas conversões podem ser feitas.

Mais Informações

Windows NT implementa Unicode (ou caractere largo) e as versões ANSI do funções Win32 que usam parâmetros de seqüência de caracteres. No entanto o Windows 95 não implementa a versão Unicode da maioria das funções do Win32 que levam parâmetros de seqüência de caracteres. Em vez disso, ele implementa apenas as versões ANSI dessas funções.

Uma exceção principal para essa regra é OLE de 32 bits. APIs (interfaces de programação de aplicativo) de 32 bits OLE e métodos de interface no Windows NT e Windows 95 usam Unicode exclusivamente. Versões ANSI dessas funções não são implementadas no Windows NT ou Windows 95.

Isso significa que um aplicativo de 32 bits que precisa ser executado no Windows 95 e Windows NT deve usar as versões ANSI das funções que não sejam OLE Win32 e deve converter cadeias de caracteres ANSI para Unicode antes que eles são passados para OLE.

Um aplicativo Unicode de 32 bits que é executado somente no Windows NT não precisa usar as funções de conversão Unicode/ANSI.

Win32 fornece MultiByteToWideChar e WideCharToMultiByte para converter seqüências de caracteres ANSI para Unicode e cadeias de caracteres Unicode em ANSI. Este artigo fornece AnsiToUnicode e UnicodeToAnsi, que usa essas funções para conversão Unicode/ANSI.
/*
 * 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;

}
				
exemplo uso dessas funções é da seguinte maneira. CoTaskMemFree é usado para liberar a seqüência convertida se CoTaskMemAlloc foi usado para alocar a seqüência de caracteres. A seqüência convertida deve não ser liberada se ele for retornado por meio de um parâmetro de saída para outro componente OLE, porque esse componente é responsável por liberando a seqüência de caracteres. LPOLESTR é um ponteiro para uma seqüência de caracteres 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);

}
				
Observação : comentários no AnsiToUnicode e UnicodeToAnsi sobre o alocador é usado para alocar a seqüência convertida. CoTaskMemAlloc (o alocador OLE) é necessário para ser usado somente se a seqüência de caracteres resultante será passada para outro componente OLE e se esse componente pode liberar a cadeia de caracteres. Isso significa que cadeias de caracteres que é passada como em parâmetros para métodos de interface OLE não precisa usar o alocador OLE. Seqüências de caracteres que são passadas como saída-parâmetros ou retornadas por meio de parâmetros de saída ou de saída-parâmetros devem ser alocadas usando o alocador OLE.

Constantes de seqüência de caracteres podem ser convertidos para Unicode em tempo de compilação usando a macro OLESTR. Por exemplo:
CreateFileMoniker(OLESTR("c:\\boo\\har.doc"), &pmk);
				
outro exemplo de rotinas de conversão Unicode/ANSI pode ser encontrado no código fonte Microsoft Foundation Classes (MFC) que é fornecido com o compilador Visual C++ 4.0. Essas rotinas são descritas na MFC Technote 59: 'Usando MFC Unicode/MBCS conversão macros'. A definição dessas macros OLE2T, T2OLE, OLE2CT, T2COLE, A2W, W2A, A2CW, W2CA e USES_CONVERSION estão em \msdev\mfc\include\afxpriv.h. Consulte também AfxA2WHelper e AfxW2AHelper no código fonte MFC em \msdev\mfc\src e o uso do OLE2T, T2OLE, OLE2CT e T2COLE em código-fonte MFC em \msdev\mfc\src. Essas funções permitir código ser compilado para Unicode ou ANSI dependendo se a definição de pré-processamento _UNICODE foi feita. Por exemplo, a chamada CreateFileMoniker no exemplo acima pode ser feita como a seguir com as macros MFC:
USES_CONVERSION;
GetOpenFileName(&ofn);
CreateFileMoniker(T2OLE(ofn.lpstrFile), &pmk);
				
Se _UNICODE estiver definido, T2OLE é definida da seguinte forma:
inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
				
Se _UNICODE não está definido, T2OLE é definida da seguinte forma:
#define T2OLE(lpa) A2W(lpa)
				
T no T2OLE indica que o tipo que está sendo convertido em uma seqüência de caracteres OLE (seqüência de caracteres Unicode) é uma seqüência de caracteres Unicode quando _UNICODE é definido e uma seqüência de caracteres ANSI quando _UNICODE não for definida. Da mesma forma LPTSTR é definido como um ponteiro para uma seqüência de caracteres Unicode quando _UNICODE é definido e como um ponteiro para uma seqüência de caracteres ANSI quando _UNICODE não está definido. T2OLE não faz qualquer conversão quando _UNICODE é definido (LPTSTR == LPOLESTR). Quando o Unicode não está definido, A2W é chamado. A2W converte uma seqüência de caracteres ANSI para Unicode da seguinte maneira:
#define A2W(lpa) (\ 
        ((LPCSTR)lpa == NULL) ? NULL : (\ 
            _convert = (strlen(lpa)+1),\ 
            AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)\ 
        )\ 

)
				
AfxA2WHelper usa MultiByteToWideChar para fazer a conversão.

As macros de conversão de MFC use _alloca para alocar espaço da pilha de programa para a seqüência convertida. O espaço é desalocado automaticamente quando a chamada de procedimento for concluído. OLE requer o alocador OLE a ser usado para todas as seqüências (dados) que serão alocadas por um componente e liberadas por outra. Isso significa que cadeias de caracteres passadas para parâmetros de saída e in-out-parâmetros de interfaces OLE devem ser alocados com o alocador OLE. Em parâmetros não precisam ser alocados com o alocador OLE porque o chamador é responsável pela liberação-los. A maioria das Interfaces vínculo/incorporação de objetos OLE e API passam cadeias de caracteres como em parâmetros. Conseqüentemente, as macros de conversão de MFC podem ser usadas na maioria dos casos. As macros de conversão do MFC não podem ser usadas para parâmetros in-out ou para retornar valores por meio de parâmetros de saída porque eles não alocar espaço usando o alocador OLE. AnsiToUnicode e UnicodeToAnsi podem ser usados nesses casos.

Ainda outro conjunto de rotinas de conversão Unicode/ANSI pode ser encontrado na coluna de Don Box OLE no Microsoft Systems Journal, agosto de 1995, volume 10 nº 8, 86 página. Don Box define uma classe C++ com um operador de conversão que retornará uma seqüência de caracteres Unicode/ANSI convertido. O espaço alocado é liberado automaticamente quando o objeto sai do escopo. Essa classe pode ser modificada para alocar usando o alocador OLE e não liberar o espaço alocado para seqüências de caracteres que são passadas in-out ou parâmetros de saída.

Uma das classes String16, da coluna de Don Box que converte uma seqüência de caracteres ANSI para Unicode, segue. Outra classe, String8, semelhante a este é usado para ANSI para conversão de Unicode. A chamada CreateFileMoniker do exemplo anterior pode ser feita como a seguir com essa classe:
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
no código acima, uma instância de String16 é criada. O construtor da classe irá converter a seqüência de caracteres ANSI em Unicode. A implementação de idioma chamará o operador de conversão, o operador const wchar_t *, para converter este parâmetro para o tipo de primeiro parâmetro do CreateFileMoniker. O operador de conversão retornará a seqüência Unicode que será passada para CreateFileMoniker. O objeto será destruct na vai fora do escopo.
// 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;

}
				

Propriedades

ID do artigo: 138813 - Última revisão: quarta-feira, 16 de março de 2005 - Revisão: 2.4
A informação contida neste artigo aplica-se a:
  • Microsoft OLE 4.0 nas seguintes plataformas
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
Palavras-chave: 
kbmt kbcode kbhowto kbprogramming KB138813 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 138813

Submeter comentários

 

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