UTF-8 String in RichTextBox anzeigen



  • Ohne eine Lösung zu haben (auch abseits von UTF-8/16 und auch C#).

    @Th69 sagte in UTF-8 String in RichTextBox anzeigen:

    Und welchen Zeichensatz hast du da eingestellt? Ich denke, es liegt nur daran, daß der Zeichensatz ("Courier New") dieses Zeichen nicht enthält (und daher dann das Fallback-Zeichen, welches meistens ein Rechteck ist, darstellt).

    Nur ein schneller Test:
    https://i.imgur.com/gtKHqBy.png
    Links ein normales Editcontrol, rechts Richedit. Reinkopiert jeweils über die Zwischenablage, gleiche Schriftart eingewählt (lfStatusFont aus SystemParametersInfo).
    Dieses Verhalten hätte ich jetzt auch nicht erwartet.



  • Welche .NET-Version benutzt du? Ab Version 4.7 ist das wohl gefixt (es wurde vorher intern eine ältere Version des WinAPI RichEdit-Controls benutzt, s.a. RichTextBox cannot display Unicode Mathematical alphanumeric symbols).

    Falls du nicht upgraden kannst oder möchtest, so könntest du den Workaround benutzen (also ein eigenes davon abgeleitetes Control erstellen).



  • @hkdd sagte in UTF-8 String in RichTextBox anzeigen:

    Es wird schon so sein, wie firefly bereits sagte, dass die RichTextBox keine vollständige UTF-8 Unterstützung besitzt.

    Nö das hat mit UTF-8 gar nix zu tun. Windows tut immer mit UTF-16 und C# tut immer UTF-16. Und da UTF-8 und UTF-16 grundverschieden sind, liegt es sicher nicht daran dass du UTF-8 wo rein fütterst wo UTF-16 sein sollte. Sonst wäre jedes 2. Zeichen ein Kasterl.

    omit es vermutlich was zu tun hat ist der Rendering-Code der beiden Controls. Courier New & Co. haben lange nicht Glyphen für alles was Unicode so kann. Das normale Edit Control verwendet Funktionen wo Windows automatisch einen "Ersatzfont" auswählt um die fehlenden Zeichen auszugeben.

    Vermutung: Da das Richedit Control aber mehr "kann" (unterschiedliche Formatierung einzelner Wörter/Zeichen etc.), muss es mehr selbst machen. Daher kann es die einfachen Text-Ausgabefunktionen (wo Windows die ganze Show vonwegen Ersatzfont suchen erledigt) nicht verwenden. Weil man bei denen nur einen Font/Grösse/Farbe etc. für alles angeben kann. Und da es keinen eigenen Code für Ersatzfont Suchen hat, wird alles was im ausgewählten Font fehlt einfach als Kasterl angezeigt.



  • Ich habe jetzt noch etwas mit Delphi 10.3 getestet.
    Da wird in einem TRichEdit-Fenster auch nur ein Quadrat, statt Herz angezeigt und in einem TListBox-Fenster ist alles OK.
    Der gleiche Effekt, wie von @yahendrik auch für C# festgestellt.
    Die Strings sind immer UTF8.


  • Administrator

    @hkdd sagte in UTF-8 String in RichTextBox anzeigen:

    Die Strings sind immer UTF8.

    Mich würde ja mal interessieren, wie du weisst, dass es sich um UTF-8 handelt. Die Enkodierung ist vielfach so transparent, dass du gar nicht mitbekommst, dass sich diese irgendwo ändert. Schliesse mich Th69 und hustbaer an. Das hat nichts mit UTF-8 oder UTF-16 zu tun.



  • Ich habe jetzt selber mal den von mir beschriebenen Workaround (ExRichText) mit einem kleinen C# WinForms Programm ausprobiert und zumindestens unter Win10 funktioniert es (während die .NET 4 RichTextBox das Herzchen wirklich nicht richtig anzeigt).

    Unter Win7 wird das Zeichen jedoch von keinem Standardcontrol (auch nicht dem Editor/TextBox) angezeigt, also nur als Rechteck dargestellt.
    Jedoch wird es vom VS 2015 korrekt im Texteditor dargestellt!

    @hkdd: Unsere Aussagen bzgl. UTF-8 und UTF-16 hast du anscheinend immer noch begriffen?!



  • @Th69 ,
    offenbar habe ich da etwas falsch angenommen.
    Zumindest die CS-Codedateien mit dem VS-Editor bearbeitet, haben das UTF8-Format und am Anfang auch einen UTF8-BOM = EF BB BF.
    Das Standard-string-Format ist UTF-16 = Unicode, wie hier ganz klar genannt:
    https://docs.microsoft.com/de-de/dotnet/standard/base-types/character-encoding

    Wenn man mit dieser Faktenlage sich überlegt, warum eine string-Variable, die das Herz-Symbol korrekt enthält (im Unicode-Zeichensatz), die man in ein string[]-Array einer RichTextBox, welches ja demnach auch im Unicode-Format dargestellt sein sollte, in der RichTextBox nicht als Herz-Symbol dargestellt wird.
    Demnach ist string nicht immer gleich string. Oder doch ?



  • @hkdd sagte in UTF-8 String in RichTextBox anzeigen:

    Demnach ist string nicht immer gleich string. Oder doch ?

    String ist String. Encoding ist Encoding.



  • @Swordfish
    Das Encoding läuft dabei unaufgefordert ab.
    Ich habe mal ein ganz kleines Testprogramm gemacht

    using System;
    using System.IO;
    namespace StringTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                StreamWriter Ausgabe = new StreamWriter(@"L:\StringTest.txt");
                Ausgabe.WriteLine("H💜E€");
                Ausgabe.Close();
                Environment.Exit(0);
            }
        }
    }
    

    Da ist kein Encoding drin. Von UTF8 ist auch nirgendwo die Rede.
    Die erstellte Datei sieht folgendermaßen aus:

    H💜E€
    

    Und im Hex-Listing..

     48 F0 9F 92  9C 45 E2 82  AC 0D 0A    
    

    "H" = 0x48
    "💜" = 0xF0 9F 92 9C
    "E" = 0x45
    "€" = 0xE2 82 AC
    0D 0A ist der Zeilenabschluss.

    Es handelt sich eindeutig um UTF8 (ohne BOM).



  • @Th69 sagte in UTF-8 String in RichTextBox anzeigen:

    Welche .NET-Version benutzt du? Ab Version 4.7 ist das wohl gefixt

    das könnte die Ursache sein (werde ich probieren).
    Ich benutze für bestimmte Programme die 4 (nicht 4.7),
    weil nur dadurch diese Programme auch unter XP funktionieren.



  • Dann nimm den von mir oben beschriebenen Workaround (jedoch wird das Herzchen dann wohl auch nicht unter XP angezeigt werden, wenn es schon nicht für Win7 klappt).

    Mit welcher Windows-Version hast du es denn erstellt und getestet?

    Und beim StreamWriter ist UTF-8 das Standard-Encoding (wenn man es nicht explizit angibt), aber ohne BOM: StreamWriter(string) (s. Hinweise)
    So gesehen liefert dein Testprogramm jetzt nichts Interessantes.


  • Administrator

    @hkdd Die dotNet String Klasse verwendet intern UTF-16. Der StreamWriter schreibt standardmässig mit UTF-8. Findest du in der Dokumentation:

    This constructor creates a StreamWriter with UTF-8 encoding without a Byte-Order Mark (BOM), so its GetPreamble method returns an empty byte array.

    Das Problem ist die Darstellung und diese wird von Fonts und Controls übernommen. Und es gibt viele unterschiedliche Arten von Fonts. Und gewisse Controls können mit gewissen Fonts oder spezifischen Zeichen nicht umgehen. Daher hat dies nichts mit Enkodierung oder Unicode zu tun. Hier geht es nur um die Darstellung.

    UTF-8, UTF-16 und UTF-32 sagen nichts über die Darstellung aus. Das sind ausschliesslich Definitionen, wie die rohen Textdaten (also Code points) gespeichert werden sollen.



  • @Th69 sagte in UTF-8 String in RichTextBox anzeigen:

    Mit welcher Windows-Version hast du es denn erstellt und getestet?

    Mit Win10-Pro-64 1903



  • @Dravere sagte in UTF-8 String in RichTextBox anzeigen:

    @hkdd Die dotNet String Klasse verwendet intern UTF-16. Der StreamWriter schreibt standardmässig mit UTF-8. Findest du in der Dokumentation:

    This constructor creates a StreamWriter with UTF-8 encoding without a Byte-Order Mark (BOM), so its GetPreamble method returns an empty byte array.

    Das Problem ist die Darstellung und diese wird von Fonts und Controls übernommen. Und es gibt viele unterschiedliche Arten von Fonts. Und gewisse Controls können mit gewissen Fonts oder spezifischen Zeichen nicht umgehen. Daher hat dies nichts mit Enkodierung oder Unicode zu tun. Hier geht es nur um die Darstellung.

    UTF-8, UTF-16 und UTF-32 sagen nichts über die Darstellung aus. Das sind ausschliesslich Definitionen, wie die rohen Textdaten (also Code points) gespeichert werden sollen.

    Das ist richtig. Nur soweit ich weis ist UTF-8 Support in .Net selbst für Controls nicht vorgesehen sonder UTF-16 (Das ist die standard UNICODE Kodierung von Windows)
    Daher sollte man das ganze nochmal prüfen, wenn man den UTF-8 String (Der bestimmt nicht als C# String vorhanden ist, da die String klasse UTF-16 verwendet) nach UTF-16 konvertiert wird bevor es dem Control übergeben wird



  • @firefly Bitte nicht wieder das UTF-8 Thema aufwärmen, das hatten wir jetzt doch erfolgreich durch. Hier ist kein UTF-8 im Spiel. @hkdd hatte das nur fälschlich angenommen weil seine Source-Files UTF-8 sind. Die CLR Strings die daraus entstehen sind aber schon UTF-16, und falsch konvertiert wird da auch sicher nichts. Weil UTF-8 -> UTF-16 Konvertierung ein paar einfache Zeilen Code sind, in denen bloss ein paar Bits rumgeschoben werden.



  • @hkdd Bitte lerne mal ein bisschen was über die Tools mit denen du da arbeitest. Alle Strings in .NET sind immer UTF-16. Dass du im File UTF-8 bekommst, liegt daran, dass das Default-Encoding eines StreamWriter, wenn du keines angibst, halt UTF-8 ist.

    Hier https://docs.microsoft.com/en-us/dotnet/api/system.io.streamwriter?view=netframework-4.8

    StreamWriter defaults to using an instance of UTF8Encoding unless specified otherwise.

    Im Speicher sind .NET Strings trotzdem immer UTF-16, und sämtliche Windows Controls (ob .NET oder nicht) arbeiten auch immer mit UTF-16. (Also ausgenommen auf DOS-basierten Windowsen ala 95/Me.)

    UTF-8 ist und war hier nie im Spiel, wenn man mal von Encoding deiner Source-Files absieht.

    Das Problem ist das (nicht vorhandene) Spezialhandling von Emoticons und/oder allgemein Zeichen die im aktuellen Font nicht vorkommen. (Ich schätze mal dass Emoticons überhaupt super-spezial behandelt werden, da sie farbig dargestellt werden. Und IIRC können normale Schriftarten überhaupt gar keine farbigen Glyphen enthalten.)



  • @hustbaer ,
    ok, ich habe also viel über UTF-16 erfahren.
    Ursprünglich ging es mir lediglich darum, dass ich in einem Log-Fenster (zunächst im RichText-Format) u.a. die Namen von Dateien und Pfaden protokolliere. Dabei ist es mir völlig egal, in welchem Format das passiert. Das RichText-Fenster hat diese Zeichen nicht angezeigt. Ich habe sie erst kennen gelernt, seit meine drei Enkel ihre Dateien und Namen in den iPhones alle mit so einem Herz gekennzeichnet haben und ich beim Sichern dieser Dateien Probleme mit diesen Dateinamen bekam.
    Nun habe ich das mit C# und einem Edit-Fenster gelöst.
    Parallel habe ich das Programm in Delphi programmiert und dort gab es ebenfalls derartige Probleme mit diesem Zeichen. Die habe ich inzwischen auch gelöst.
    Beide Versionen können mit diesem Zeichen umgehen.
    Korrekt angezeigt wird es ab Windows 8.1.
    Unter Win7 und XP wird ein Quadrat angezeigt.

    Ich bin ja lediglich eine Hobby-Programmierer auf dem PC.
    Früher habe ich viele Jahr Host-Programme auf IBM-Großrechnern erstellt. Und parallel etwas C++ und Delphi und vor Windows mit C++ und Turbo Pascal.

    Bei Problemen versuche ich im Forum und bei Google eine Lösung zu finden. Und dafür danke ich Euch allen.



  • @hustbaer sagte in UTF-8 String in RichTextBox anzeigen:

    dass das Default-Encoding eines StreamWriter, wenn du keines angibst, halt UTF-8 ist.

    Ich habe den StreamWriter lediglich für dieses kleine Testprogramm benutzt, weil ich einen Weg gesucht habe, einen String auszugeben und dann in der Datei zu sehen, wie er aufgebaut ist. Lieber wäre es mir gewesen, ich hätte im Debugger eine Möglichkeit gefunden den String im Hex-Format ansehen zu können, so wie er tatsächlich im Speicher steht.
    Mir ist das nicht gelungen, entweder, weil das nicht geht oder weil ich nicht weiß, wie man das macht.



  • Das hättest du gleich schreiben sollen ;- )
    Für VS 2017 gibt es z.B. den HexVisualizer 2017.


Anmelden zum Antworten