logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

Win32: Unicode e Ansi

Procurando a declaração da função MessageBox (um F12 sobre o nome da função resolve isso no Visual Studio), encontramos isso:


WINUSERAPI
int
WINAPI
MessageBoxA(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType);
#ifdef UNICODE
#define MessageBox  MessageBoxW

#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

Podemos notar que não existe função MessageBox, e sim um #define MessageBox, que aponta para a função com o sufixo A ou W. A letra A é adicionada no nome das funções que suportam caracteres ANSI, e a letra W nas funções que aceitam caracteres UNICODE (o W vem de “wide char”). Como estamos usando Windows NT, a função correta é a que tem W no final.

Os caracteres UNICODE ocupam 2 bytes, o que permite que um caractere UNICODE possa representar até 65536 letras ou símbolos diferentes (em oposição ao ANSI/ASCII, que suporta somente 255), o que permite conter confortavelmente todos os caracteres e símbolos de todas as línguas e dialetos existentes no nosso planeta. Isso acaba com aquela história de MODE CON CODEPAGE PREPARE (lembra?) para ficarmos mudando a página de caracteres dependendo do idioma escolhido. Para declarar strings UNICODE em C++ precisamos prefixá-la com um L (L"dessa forma";). Quando o Windows NT foi projetado (nos ido de 1989), foi feita a decisão pelo UNICODE, para facilitar a internacionalização do Windows e dos softwares que nele rodam. O mesmo não aconteceu com o Windows 95/98/Me, que herda muita coisa do Windows 3.1, baseado em ANSI.

Na hora de programar em Win32, o #define UNICODE é o que vai definir ser vamos usar ANSI ou Unicode. As duas versões funcionam no Windows NT, sendo que o MessageBoxA (assim como todas as APIs ANSI) converte as strings de entrada para UNICODE, chama a função MessageBoxW, e converte as strings de saída de UNICODE para ANSI. Você pode inclusive chamar diretamente uma ou outra versão, como no exemplo abaixo:


#include "stdafx.h"
 
int main()
{
	//
	// ANSI
	//
	MessageBoxA(NULL, "mensagem ANSI", "www.1bit.com.br", MB_OK | MB_ICONEXCLAMATION);

 
	//
	// UNICODE
	//
	MessageBoxW(NULL, L"mensagem UNICODE", L"www.1bit.com.br", MB_OK | MB_ICONQUESTION);
 
 
	//
	// TCHAR: a macro _T() automaticamente coloca o prefixo L caso
	// estejamos compilando com UNICODE. Dessa forma é possível compilar
	// o mesmo código para UNICODE ou ANSI. Apesar de estar entrando em
	// desuso hoje em dia, isso era importante na era dos Windows 9x.
	//
	MessageBox(NULL, _T("mensagem em TCHAR"), _T("www.1bit.com.br"), MB_OK | MB_ICONERROR);
}
   

Em 04/03/2008 22:22, por Rodrigo Strauss


  
 
 
Comentários
Moisés Simões | website | e-mail | em 05/03/2008 | #
Excelente artigo ...

São conceitos simples que muitas vezes abstraímos ou sequer temos noção da existencia deles.

abs,
Thiago Falcão | website | em 06/03/2008 | #
Grande artigo, mostra com clareza (código da WIN API) a importância do UNICODE. Essencial para quem quer desenvolver software para vários idiomas.
Giuliano | website | e-mail | em 05/05/2010 | #
Esse artigo me esclareceu uma dúvida que não conseguia resolver, o porque de usar o unicode em vez do ansi no prototype do método.
Muito bom
Andrew | em 14/03/2011 | #
Boa tarde.

Parabéns pelo seu blog, só uma pequena correção em seu texto:

"em oposição ao ANSI/ASCII, que suporta somente 255"

Na verdade, não são 255 e sim 256 (pois varia de 0 a 255).

Abraços
Rodrigo Strauss | website | em 14/03/2011 | #
Putz, não sei não. O ASCII zero conta como um caractere?
Andrew | website | em 04/04/2011 | #
Sim, conta sim.
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::