Como converter de ANSI para Unicode & Unicode para ANSI para a OLE

Traduções de Artigos Traduções de Artigos
Artigo: 138813 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Sumário

Todas as cadeias passadas para e recebidas de 32 bits OLE API e métodos de interface utilizam Unicode. Isto requer que aplicações que utilizam cadeias de ANSI para converter para Unicode antes de passar os mesmos para OLE e converter as cadeias Unicode que são recebidas da OLE para ANSI. Este artigo demonstra como podem ser efectuados estas conversões.

Mais Informação

Windows NT implementa Unicode (ou caracteres) e versões ANSI do Win32 funções que parâmetros da cadeia de caracteres. No entanto o Windows 95 não implementa a versão da maior parte das funções de Win32 que parâmetros da cadeia de caracteres Unicode. Em vez disso, implemente apenas as versões ANSI destas funções.

Uma excepção principal a esta regra é OLE 32-bit. 32-bit OLE API e métodos de interface no Windows NT e Windows 95 utilizam exclusivamente Unicode. Versões ANSI destas funções não estão implementadas no Windows NT ou Windows 95.

Isto significa que uma aplicação de 32 bits que tem de ser executado no Windows 95 e Windows NT tem de utilizar as versões ANSI das funções não OLE Win32 e deve converter cadeias de ANSI para Unicode, antes que são passados para OLE.

Uma aplicação de Unicode de 32 bits que só é executado no Windows NT não necessita de utilizar as funções de conversão Unicode/ANSI.

Win32 fornece MultiByteToWideChar e WideCharToMultiByte converter cadeias de ANSI para Unicode e cadeias Unicode para ANSI. Este artigo fornece AnsiToUnicode e UnicodeToAnsi, que utiliza estas funções para a 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 utilizar estas funções é a seguinte. CoTaskMemFree é utilizado para libertar a cadeia convertida se CoTaskMemAlloc foi utilizado para atribuir a cadeia. A cadeia convertida tem, não, ser libertada se for devolvido através de um parâmetro de saída a outro componente OLE, porque esse componente é responsável pela libertar a cadeia. LPOLESTR é um apontador para uma cadeia 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 : comentários no AnsiToUnicode e UnicodeToAnsi sobre a atribuição é utilizada para atribuir a cadeia convertida. CoTaskMemAlloc (a atribuição de OLE) é necessária para ser utilizada apenas se a cadeia resultante será passada para outro componente OLE e se esse componente pode libertar a cadeia. Isto significa que cadeias que é transmitida como de parâmetros para métodos de interface OLE não necessita de utilizar a atribuição de OLE. Cadeias que são passadas como em-out-parâmetros ou devolvidas através de parâmetros de saída ou in-out-parâmetros devem ser atribuídas utilizando o alocador OLE.

As constantes String podem ser convertidas para Unicode durante a compilação utilizando a macro OLESTR. Por exemplo:
CreateFileMoniker(OLESTR("c:\\boo\\har.doc"), &pmk);
				
outro exemplo de rotinas de conversão Unicode/ANSI poderá encontrar o código de Microsoft Foundation Classes (MFC) que é fornecido com o compilador de Visual C++ 4.0. Estas rotinas são descritas MFC Technote 59: 'Utilizar MFC MBCS/Unicode conversão macros'. A definição destas 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 de origem MFC \msdev\mfc\src e a utilização do OLE2T T2OLE, OLE2CT e T2COLE o código de origem MFC \msdev\mfc\src. Estas funções permitir código a ser compilada para Unicode ou ANSI dependendo se a definição de pré-processador _UNICODE foi efectuada. Por exemplo, a chamada CreateFileMoniker no exemplo anterior pode ser efectuada da seguinte forma 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 estiver definido, T2OLE é definida da seguinte forma:
#define T2OLE(lpa) A2W(lpa)
				
T em T2OLE indica que do tipo que está a ser convertida para uma cadeia OLE (cadeia Unicode) é uma cadeia Unicode quando _UNICODE é definida e uma cadeia ANSI, quando _UNICODE não está definida. Da mesma forma LPTSTR é definido como um ponteiro para uma cadeia Unicode quando _UNICODE é definida e como um ponteiro para uma cadeia ANSI quando _UNICODE não está definido. T2OLE não faz qualquer conversão quando _UNICODE é definida (LPTSTR == LPOLESTR). Quando o Unicode não está definida, A2W é chamado. A2W converte uma cadeia de caracteres ANSI para Unicode da seguinte forma:
#define A2W(lpa) (\ 
        ((LPCSTR)lpa == NULL) ? NULL : (\ 
            _convert = (strlen(lpa)+1),\ 
            AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)\ 
        )\ 

)
				
AfxA2WHelper utiliza MultiByteToWideChar para efectuar a conversão.

As macros de conversão de MFC utilizar _alloca para atribuir espaço de pilha programa para a cadeia convertida. O espaço é desatribuído automaticamente quando a chamada de procedimento estiver concluído. OLE requer a atribuição de OLE a ser utilizada para todas as cadeias (dados) que serão atribuídas por um componente e libertadas por outro. Isto significa que cadeias transmitidas parâmetros de saída e de fora-parâmetros de interfaces OLE devem ser atribuídos com a atribuição de OLE. Em parâmetros não necessitam de ser atribuídos com a atribuição de OLE porque o autor da chamada é responsável pela libertá-los. A maior parte das Interfaces OLE de ligação/incorporação e API passam cadeias como de parâmetros. Consequentemente, as macros de conversão de MFC podem ser utilizadas na maioria dos casos. As macros de conversão de MFC não podem ser utilizadas em parâmetros na saída ou para devolver valores através de parâmetros de saída, uma vez que não a atribuir espaço utilizando o alocador OLE. AnsiToUnicode e UnicodeToAnsi podem ser utilizados nestes casos.

Ainda outro conjunto de rotinas de conversão Unicode/ANSI pode ser encontrado na coluna Don Box OLE no diário do Microsoft Systems, Agosto de 1995, Vol. 10 n.º 8, 86 página. Don Box define uma classe de C++ com um operador de conversão que irá devolver uma cadeia Unicode/ANSI convertido. O espaço alocado é automaticamente libertado quando o objecto ficar fora do âmbito. Esta classe pode ser modificada para atribuir utilizando o alocador OLE e não libertar o espaço alocado para cadeias que passam através de parâmetros de saída ou no exterior.

Um das classes String16, de coluna Don Box, que converte uma cadeia de caracteres ANSI para Unicode, a seguir. Outra classe, String8, semelhante à que este é utilizado para ANSI para a conversão Unicode. A chamada CreateFileMoniker do exemplo anterior pode ser efectuada as seguintes com esta classe:
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
no código anterior, é criada uma instância de String16. O construtor da classe irá converter a cadeia ANSI para Unicode. A implementação de idioma chamará o operador de conversão, o operador wchar_t constante *, para converter este parâmetro para o tipo de primeiro parâmetro do CreateFileMoniker. O operador de conversão devolverá a cadeia Unicode que é transmitida para CreateFileMoniker. O objecto irá destruct na entra fora do â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;

}
				

Propriedades

Artigo: 138813 - Última revisão: 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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