boost::locale::translate und umlaute



  • Wie stellst du die texte dar?
    Denn die API unter windows kennt an vielen stellen kein UTF-8 sondern nur UTF-18 (wchar_t als datentyp für strings)



  • @firefly sagte in boost::locale::translate und umlaute:

    Wie stellst du die texte dar?

    Wird mit SendMessage aus WinUser.h an eine andere Applikation (MFC mit CString) gesendet

    @firefly sagte in boost::locale::translate und umlaute:

    UTF-18 (wchar_t als datentyp für strings)

    Du meinst UTF-16?



  • @booster sagte in boost::locale::translate und umlaute:

    Wird mit SendMessage aus WinUser.h an eine andere Applikation (MFC mit CString) gesendet

    Dann würde ich SendMessageW verwenden und L"texttexttext" Literale (die auf Windows UTF-16 sind).

    Wenn du Texte aus einem File lesen willst, dann kommt es darauf an wie dieses kodiert ist. Auf Windows kannst du aber auf jeden Fall MultiByteToWideChar verwenden um 8-Bit kodierte Strings nach UTF-16 zu konvertieren. Du musst dabei natürlich die passende 8-Bit CodePage mitgeben - eben abhängig davon was für ein Encoding das File verwendet. (Bzw. was für ein Encoding du von gettext zurückbekommst, aber ich nehme an dass das 1:1 dem entspricht was im File drinnen steht.)



  • @booster sagte in boost::locale::translate und umlaute:

    @firefly sagte in boost::locale::translate und umlaute:

    Wie stellst du die texte dar?

    Wird mit SendMessage aus WinUser.h an eine andere Applikation (MFC mit CString) gesendet

    @firefly sagte in boost::locale::translate und umlaute:

    UTF-18 (wchar_t als datentyp für strings)

    Du meinst UTF-16?

    Ja stimmt ist ein vertipper 🙂



  • @hustbaer sagte in boost::locale::translate und umlaute:

    Dann würde ich SendMessageW verwenden und L"texttexttext" Literale (die auf Windows UTF-16 sind).

    Das war doch jetzt gar nicht die Frage. Habe ich ja nur geschreiben weil firefly gefragt hat wo ich das darstelle.

    @hustbaer sagte in boost::locale::translate und umlaute:

    Wenn du Texte aus einem File lesen willst, dann kommt es darauf an wie dieses kodiert ist. Auf Windows kannst du aber auf jeden Fall MultiByteToWideChar verwenden um 8-Bit kodierte Strings nach UTF-16 zu konvertieren.

    Bin eigentlich dran die Microsoft Erweiterungen zu vermeiden. Es sollte aber auch kein Problem sein das File auf UTF-16 umzustellen

    Eigentlich sollte ich im Programm auf Unicode Character Set umstellen. Das hat aber hinreichende Änderungen in meinem Programm zur Folge.



  • @booster sagte in boost::locale::translate und umlaute:

    @hustbaer sagte in boost::locale::translate und umlaute:

    Dann würde ich SendMessageW verwenden und L"texttexttext" Literale (die auf Windows UTF-16 sind).

    Das war doch jetzt gar nicht die Frage. Habe ich ja nur geschreiben weil firefly gefragt hat wo ich das darstelle.

    Doch, da du eine Frage über ein Darstellungsproblem gestellt hast. Und da ist es wichtig zu wissen wo die Darstellung erfolgt und wie die Daten da hin kommen.
    @booster:

    Nun habe ich allerdings das Problem dass meine Umlaute nicht richtig dargestellt werden.

    Und SendMessage (bei Multi Byte Character Set ist es SendMessageA) kann nur mit ASCII/ANSI zeichen umgehen.
    Bzw. der Empfänger der Nachricht wird den String als ASCII/ANSI kodiert ansehen und nicht als Unicode.
    Ist die Empfänger Applikation (MFC mit CString) auch auf Multi Byte Character set eingestellt? Wenn ja, dann ist CString = CStringA und kann kein Unicode. Sonder du musst CStringW (CString ist ein CStringW, wenn Character Set = UNICODE) verwenden.

    Wenn beide Applikationen "Multi Byte" sein müssen, dann musst du den Uncode String in die lokale codepage (ANSI codepage) umwandeln und dann mit SendMessageA an die andere Applikation senden.



  • Danke für deine Erläuterung.

    Ich glaube ich habe noch nicht genau verstanden was die Umstellung von MultiByte auf Unicode im Visual Studio bewirkt.

    Wenn ich auf Unicode Umstelle werden die Funktionen mit dem zusatz W verwendet anstatt mit dem Zusatz A.
    Also widestring statt Ansi. Ist das korrekt?

    was ist mit meinen strings. Muss ich nun alles als wstring kennzeichnen?



  • @booster sagte in boost::locale::translate und umlaute:

    Danke für deine Erläuterung.

    Ich glaube ich habe noch nicht genau verstanden was die Umstellung von MultiByte auf Unicode im Visual Studio bewirkt.

    Wenn ich auf Unicode Umstelle werden die Funktionen mit dem zusatz W verwendet anstatt mit dem Zusatz A.
    Also widestring statt Ansi. Ist das korrekt?

    Wenn du die Funktionen ohne A/W zusatz verwendest, dann wird bei MultiByte die A variante und bei Unicode die W variante verwendet. Die Funktionen ohne diesen Zusatz (z.b. SendMessage) sind nur Aliase (als macro definiert) für die A/W varianten (z.b. SendMessageA/SendMessageW)

    was ist mit meinen strings. Muss ich nun alles als wstring kennzeichnen?
    Meinst du hartcodierte Strings? Ja die müssen bei UNICODE als "wstring" gekennzeichnet werden. Es gibt ein Macro mit der Bezeichnung TEXT (https://docs.microsoft.com/en-us/windows/desktop/api/winnt/nf-winnt-text), welche das ganze passend handhabt.

    Eingelesene strings müssen nach UTF-16 konvertiert (bevor diese an z.b. SendMessageW übergeben werden können) werden (via MultiByteToWideChar), falls diese nicht schon als UTF-16 eingelesen werden.



  • @firefly sagte in boost::locale::translate und umlaute:

    Wenn du die Funktionen ohne A/W zusatz verwendest, dann wird bei MultiByte die A variante und bei Unicode die W variante verwendet. Die Funktionen ohne diesen Zusatz (z.b. SendMessage) sind nur Aliase (als macro definiert) für die A/W varianten (z.b. SendMessageA/SendMessageW)

    Ja das meinte ich. Das war ja meine Frage. Ist das alles was passiert wenn ich von Multibyte auf Unicode umstelle?

    Also der datentyp std::string bassiert weiterhin auf char. Bei CString von microsoft ist das anders.



  • muss ich nun im ganzen Code auf wstring umstellen?



  • @booster sagte in boost::locale::translate und umlaute:

    Ja das meinte ich. Das war ja meine Frage. Ist das alles was passiert wenn ich von Multibyte auf Unicode umstelle?

    Probiers doch einmal aus. Intern in der WinApi wird ohnehin alles nach UTF-16 codiert. Wahrscheinlich wirst du mit Fehlermeldungen zugeschüttet werden.
    Prinzipiell ist es immer eine gute Idee (wenn nicht sofort alles auf UNICODE gesetzt wird) eine Konfiguration auf MultiByte, die andere auf UNICODE zu stellen (bspw. Debug->UNICODE, Release->MultiByte).

    Alles was std::string ist und irgendwie mit der WinApi zu tun hat, sollte ebenfalls angepasst sein:

    typedef std::basic_string<TCHAR> tstring;
    

    Bei großen Projekten bedeutet die Umstellung leider ziemlich viel Arbeit, da immer geschaut werden muss, ob die Unterscheidung notwendig und nicht fehlerhaft ist. Ein find and replace in allen Dateien funktioniert nicht.



  • Ja ich werde mit Fehlermeldungen zugeschüttet. Darum die Frage kann ich nicht bei Multibyte Character Set bleiben. Und trotzdem Umlaute verwenden.
    Wieso heißt das überhaupt Multibyte. Multibyte heißt doch mehrere Bytes verwenden um ein Zeichen zu codieren.

    @yahendrik sagte in boost::locale::translate und umlaute:

    Alles was std::string ist und irgendwie mit der WinApi zu tun hat, sollte ebenfalls angepasst sein:
    typedef std::basic_string<TCHAR> tstring;

    std::string ist doch ein typedef auf std::basic_string<char> also wird es ja nicht angepasst.



  • @booster Da steht TCHAR, nicht char.



  • @yahendrik sagte in boost::locale::translate und umlaute:

    Da steht TCHAR, nicht char.

    Ja das habe ich schon gesehen. Und da steht auch tstring.
    Aber im Satz vor dem typedef sagst du std::string

    Also std::string wird nicht angepasst da std::string<char>
    und tstring wird nach deiner definition angepasst. Aber das verwende ich ja nirgends.



  • Beispiel:
    Vorher

    std::string s="Windowtext";
    SetWindowText(wnd, s.c_str());
    

    ->

    tstring s=TEXT("WindowText");
    SetWindowText(wnd, s.c_str());
    

    Wenn UNICODE definiert ist, wird SetWindowTextW mit wstring::c_str() aufgerufen, sonst SetWindowTextA mit string::c_str().



  • @yahendrik

    Ja das war klar. Aber das wollte ich gar nicht wissen.

    Egal. Nochmals zu dem was nun noch nicht klar ist:

    • kann ich nicht bei Multibyte Character Set bleiben. Und trotzdem Umlaute verwenden.
    • Wieso heißt das überhaupt Multibyte. Multibyte heißt doch mehrere Bytes verwenden um ein Zeichen zu codieren. Dann bräuchte ich doch kein Unicode?

    Bei Wikipedia steht übrigens:
    Die wichtigsten Vertreter von MBCS sind: UTF-8, UTF-16, UTF-7, Shift-JIS, Big5 und GB2312. ??

    Dachte UTF-16 wäre Unicode!



  • Ist es.

    Multibyte kann auch single-byte sein. wchar_t ist laut der msdn unicode also zwei bytes.

    Was du willst sind wide characters, also wstring. Und wenn die standard Exception-Klassen keine überladungen dafür implementieren kannst du auch einfach eine eigene klasse schreiben.



  • wo liegt jetzt der Unterschied zwischen Multibyte und Unicode

    Multibyte sind mehrere Bytes
    Unicode sind auch mehrere Bytes.

    Und wieso will ich wstring?

    Wenn ich einen std::string anlege und darin umlaute speicher werden die auch angezeigt im Visual Studio debugger.


  • Administrator

    Vielleicht müsste man hier klarstellen, dass du von der Multibyte Einstellung in Visual Studio redest? Weil Visual Studio meint damit die Multi Byte Character Sets (MBCS) von Windows. Das sind Windows spezifische 1 bis 2 Byte pro Zeichen Enkodierungen. Windows selbst betrachtet dies als Legacy und empfiehlt heutzutage Unicode zu verwenden.

    MBCS ist eben Windows spezifisch, kann bis zu zwei Bytes pro Zeichen verwenden. Es ist dann aber weiterhin nötig ein Character Set zu verwenden. Du hast MBCS für westeuropäisch, koreanisch, japanisch, usw. Und die sind nicht zueinander kompatibel. Es war eine temporäre Übergangslösung, um Sprachen zu ermöglichen, welche mehr als 255 Zeichen benötigen.

    Unicode dagegen hat ein Character Set. Unicode. Fertig. Unicode unterstützt aber mehrere Möglichkeiten, wie man es enkodiert. UTF-16 verwendet 2 oder 4 Bytes pro Zeichen. UTF-8 hat 1 bis 4 (?) Bytes pro Zeichen. Windows empfiehlt heutzutage UTF-16 zu verwenden. Da UTF-16 mindestens 2 Bytes benötigt, verwendet man dafür unter Windows wchar_t und somit std::wstring.

    Ist das einigermassen verständlich?



  • Die Unterschiede werden in Unicode and MBCS sowie Unicode and Multibyte Character Set (MBCS) Support beschrieben.

    Lies aber auch mal VisualStudio: MultiByte vs Unicode.

    Die Definition in Wikipedia bzgl. MBCS und DBCS entspricht also (strenggenommen) nicht dem, was MS unter "MBCS" versteht (1 oder 2 Bytes per Zeichen, daher char als Basis für TCHAR), also der älteren Definition wie in Double Byte Character Set erwähnt.

    Und bei "UNICODE" wird UTF-16 aktiviert (daher wchar_t).


Anmelden zum Antworten