2009-02-02 13 views
6

Szybkie pytanie dotyczące obsługi UTF-8 i różnych Win32 API.Obsługa WinAPI i UTF-8

W typowym projekcie C++ MFC, czy MessageBox() może wyświetlać zakodowany ciąg znaków UTF-8?

Dzięki, Andrew

Odpowiedz

8

Szybka odpowiedź: Nie

Dłuższa odpowiedź: To będzie działać, jeśli ciąg zawiera tylko regularne znaki ANSI, na przykład US English, ponieważ te kody znaków są takie same w UTF -8 i ANSI.

Jeśli dołączono znaki spoza ANSI lub znaki zakodowane dwubajtowo, należy przekształcić je w kodowanie Unicode-16 za pomocą MultiByteToWideChar z CP_UTF8. Twój program będzie również wymagał kompilacji z zdefiniowanym standardem UNICODE lub możesz użyć wywołań interfejsu API "W" - np. MessageBoxW.

(Należy zauważyć, że funkcje pobierają argument tekstowy, taki jak MessageBox, CreateWindow map do wersji "A" lub "W" w zależności od tego, czy zdefiniowano UNICODE).

Może to być również przydatne;

http://www.joelonsoftware.com/articles/Unicode.html

+1

Wystarczy trochę terminologii, ale to się nazywa UTF -16. Nie ma czegoś takiego jak Unicde-16. :) – jalf

+3

Ten artykuł Joela jest dość stary, a on naprawdę pomija UTF-8, który jest najbardziej technicznie wygodnym kodowaniem Unicode. Jego własne poglądy na temat znalezienia metatagu HTML działają tylko z kodowaniem UTF-8 lub jednym bajtem (pochodzącym z ASCII). W przeciwnym razie otrzymasz bajty o zerowej wartości w całym miejscu, co utrudnia wyszukiwanie znaków "<". W UTF-8 możesz parsować XML (i HTML), nie martwiąc się w ogóle o Unicode, ponieważ gwarantuje to, że zobaczysz bajty <127 tylko wtedy, gdy kodują rzeczywiste znaki ASCII. – jpc

+0

Zauważ też, że większość WinAPI jest bardziej podobna do UCS-2 niż UTF-16, w tym, że przynajmniej niektóre części WinAPI (co? Nie mam pojęcia - to wszystko wydaje się być raczej hit & miss) wygrał ' t prawidłowo obsługiwać pary zastępcze; innymi słowy zakładają, że UTF-16 jest kodowaniem o stałej szerokości. –

4

Nope, użyj MultiByteToWideChar z CP_UTF8. Zobacz: http://www.siao2.com/2006/10/11/816996.aspx, dlaczego A nie może tego zrobić; W (UCS-2) jest jedyną alternatywą.

+0

+1 z niewielkim nacięciem: wersja W to UTF-16, a nie UCS-2 - obsługuje również pary zastępcze. –

+0

To robi z XP, tak. – Mark

+0

Więcej informacji na temat różnicy można znaleźć na stronie http://blogs.msdn.com/michkap/416552.aspx – Mark

3

Używam makr konwersji łańcuchów ATL/MFC. Na przykład, jeśli masz ciąg znaków ASCII o nazwie myUTF8Str zawierające UTF8 znaków:

::MessageBox(hWnd, CA2T(myUTF8Str, CP_UTF8), _T("Caption"), MB_OK); 

Alternatywnie można utworzyć wystąpienie napisu, np

CA2T myConvertedString(myUTF8Str, CP_UTF8); 
... 
TRACE(_T("Converted: %s\n"), myUTF8Str.m_psz); 

Uwaga człon m_psz który pozwala tylko do odczytu dostęp do surowego wskaźnika łańcucha.

Można również kodować używając CT2A, np:

CT2A myEncodedString("Some UTF8", CP_UTF8); 

Jeśli nie używać makr tekst, a następnie użyć CA2W, CW2A itp