Sonderzeichen in Richedit

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
teertinker
Beiträge: 6
Registriert: Mo 25. Apr 2016, 10:33

Sonderzeichen in Richedit

Beitrag von teertinker »

Hallo, ich habe meine Lazarus IDE um das Paket lazrichedit erweitert und alles funktioniert prima.
Ich habe ein kleines Programm, in dem Formatierungen für bestimmte Felder einer Tabelle angegeben werden können (Z.B. A2 Fett). In einem RFT Memo werden die Zellinhalte dann als Voransicht im RichText angezeigt. Auch das klappt prima.

Ich habe folgende Prozedur zum schreiben des RTF codes:

Code: Alles auswählen

 
procedure thallo.previewrtffield;
 var  stream:tstringstream;
 
      rtfstring: string;
 begin
 
 
 rtfstring:=richeditpreviewline ;
 
 if combobox3.ItemIndex=1 then rtfstring:=edit9.Text+'1'+edit10.text+rtfstring;
 rtfString :='{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}}'+rtfstring+'}';
 stream := Tstringstream.Create(rtfString);
 richedit.Text:='';
 RichEdit.LoadFromStream(stream);
 stream.Free;
 
 end;
 
Nun zu meinem Problem:
Sonderzeichen (z.B. „ “ ‘ ‚ ), die in dem string richeditpreviewline auftauchen (richeditpreviewline ist eine Kombination mehrerer Zellen eines Stringgrids), werden immer nur mit ??? im Richedit-Feld angezeigt.
Z.b. Passiert das auch, wenn ich die obige erste zeile wie folgt modifiziere:
rtfstring:=richeditpreviewline +'“' ;

Wenn ich die Zeichen direkt händisch in das Richedit-Feld kopiere (in der Kompilierten Programmversion), werden sie korrekt angezeigt. Ich gehe also davon aus, dass das Richedit-Feld grundsätzlich diese Zeichen irgendwie verarbeiten kann.

Kann mir jemand einen Tipp geben, wie ich die Sonderzeichen korrekt angezeigt bekomme? Eine 'dreckige' Version, durch ersetzen der Sonderzeichen durch deren RFT-Hexcode (z.b. \92 für ‘) habe ich schon versucht, aber ohne den gewünschten Erfolg. Mit dem Paket richmemo habe ich im übrigen die selben Erfahrungen gemacht.


Vielen Dank

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Sonderzeichen in Richedit

Beitrag von Michl »

teertinker hat geschrieben:Mit dem Paket richmemo habe ich im übrigen die selben Erfahrungen gemacht.
Ich habe nur einen schnellen Test gemacht. So funktioniert das bei mir mit den Zeichen „ “ ‘ ‚ (evtl. gehts so auch mit dem lzRichedit (PS: lzRichedit wird nicht sonderlich aktiv entwickelt, RichMemo dagegen schon)):

Code: Alles auswählen

uses ..., LConvEncoding;
...
procedure TForm1.Button1Click(Sender: TObject);
var
  Stream: TStringStream;
  RTFString: String;
begin
  RTFString := 'Test mit [„ “ ‘ ‚]';
  RTFString := UTF8ToCP1252(RTFString);
  RTFString :='{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}}' + RTFString + '}';
  Stream := TStringStream.Create(RTFString);
  RichMemo.LoadRichText(Stream);
  Stream.Free;
end;  

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

teertinker
Beiträge: 6
Registriert: Mo 25. Apr 2016, 10:33

Re: Sonderzeichen in Richedit

Beitrag von teertinker »

Vielen Dank!
Ich werde versuchen, es mal auzuprobieren. Bisher habe ich es nicht geschafft, das RichMemo (v 1.0) zum laufen zu bekommen. Ich kann das Paket zwar kompilieren, aber sobald ich eine richmemo komponente in mein formular einfüge kommt "Access violation..."

Leider funktioniert die Konvertierungsfunktion im LZRichedit nicht.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Sonderzeichen in Richedit

Beitrag von Michl »

teertinker hat geschrieben:Ich kann das Paket zwar kompilieren, aber sobald ich eine richmemo komponente in mein formular einfüge kommt "Access violation..."
Welches Betriebssystem, welche Lazarusversion? Das RichMemo von hier sollte funktionieren (zumindest ist wird es gepflegt): https://svn.code.sf.net/p/lazarus-ccr/s ... s/richmemo

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

teertinker
Beiträge: 6
Registriert: Mo 25. Apr 2016, 10:33

Re: Sonderzeichen in Richedit

Beitrag von teertinker »

Ich nutze Ubuntu 12.04 und Lazarus 1.08 mit fpc 2.6.2... Ich probiere mal eine neuere Version.
Michl hat geschrieben:
teertinker hat geschrieben:Ich kann das Paket zwar kompilieren, aber sobald ich eine richmemo komponente in mein formular einfüge kommt "Access violation..."
Welches Betriebssystem, welche Lazarusversion? Das RichMemo von hier sollte funktionieren (zumindest ist wird es gepflegt): https://svn.code.sf.net/p/lazarus-ccr/s ... s/richmemo

teertinker
Beiträge: 6
Registriert: Mo 25. Apr 2016, 10:33

Re: Sonderzeichen in Richedit

Beitrag von teertinker »

Ich konnte das Richmemo mit einer neueren Version kompilieren. Habe aber weiterhin das gleiche Problem gehabt. Da ich ein sehr überschaubares Set an Formatierungen habe, bin ich nun einen anderen Weg gegangen:

- Zuerst den Plaintext in das RichMemo einfügen, dann werden alle Sonderzeichen korrekt dargestellt
- anschließend die Formatierungen über eine prozedur vornehmen
-> das hat soweit gut geklappt.

Ich muss nun in einem abschließenden Schritt noch die RTFcode-Elemente entfernen z.b. '{\b'

das habe ich mit folgendem befehl versucht:

richedit.text:=stringreplace(richedit.text,'{\b','',[rfreplaceall]);

Das Problem: nun wird die gesamte formatierung wieder gelöscht!

Gibt es Vorschläge?

teertinker
Beiträge: 6
Registriert: Mo 25. Apr 2016, 10:33

Zugriff auf Sonderzeichen in Richedit.text über Schleife

Beitrag von teertinker »

Die Richmemo Komponente bringt mich noch um den Schlaf. Der RTF-Code wird nun über mehrere Schleifen direkt im Memo mit .Settextattributes umgewandelt. Die Codebestandteile habe ich im Anschluss durch size:=0 optisch verschwinden lassen.

Mit dieser Lösung konnte ich leben. Allerdings bereiten mir Sonderzeichen immer noch Probleme.

wenn ich mit einer schleifenfunktion über den Text gehe z.b.:

Code: Alles auswählen

for i:=1 to length(richmemo.text) do
begin
if richmemo.text[i]...
end;
Dann wird der Code mit Sonderzeichen (z.b. ”) nicht mehr richtig umgewandelt. Scheinbar belegen Sonderzeichen in richmemo.text mehrere Zeichen und bringen deshalb die Schleifenfunktion in Probleme???
Weiß jemand Rat, wie ich entweder die Sonderzeichen genauso verwenden kann wie normale Zeichen, oder einen Umweg, wie ich Sonderzeichen korrekt behandeln könnte?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Sonderzeichen in Richedit

Beitrag von Michl »

Lazarus verwendet als Default UTF-8 codierte Strings. Will man nun einen UTF-8 codierten Codepoint speichern, muss man diesen speziell umwandeln. Dazu habe ich leider keine fertige Routine gefunden, aber mal in OpenOffice ein RTF mit UTF-8 codierten Zeichen erstellt. Dieses File genommen, angeschaut und eine Routine geschrieben. Funktioniert bei mir soweit (OpenOffice, diverse Betrachter und TRichMemo können damit umgehen).

Beschränkung sind UTF-16 Codepoints > $FFFF, allerdings weiß ich auch nicht, ob RTF diese überhaupt kann. Falls du diese brauchst, kann ich später nochmal schauen, wie es sich damit verhält.

Funktioniert nur mit Lazarus mit einer minimalen FPC Version 2.7.1.

Code: Alles auswählen

function StringToRTF(s: String): String;
var
  i: Integer;
  us: UnicodeString;
begin
  us := UnicodeString(s);
  Result := '';
  for i := 1 to Length(us) do
    if Ord(us[i]) < 128 then
      Result := Result + Char(Ord(us[i]))
    else                  
      Result := Result + LowerCase(#92#117 + IntToStr(Ord(us[i])) + #92#39 + IntToHex(Byte(Ord(us[i])), 2));
end;
 
procedure TForm1.BtnLoadInRichMemoClick(Sender: TObject);
var
  Stream: TStringStream;
  RTFString: String;
begin
  RTFString := 'UTF-8 Text ÄÖÜ „ “ ‘ ‚ Œʊʘ˄ϘҰՓ Test';
  RTFString := StringToRTF(RTFString);
  RTFString :='{\rtf1\ansi\deff0\adeflang1025{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}} ' + RTFString + '}';
  Stream := TStringStream.Create(RTFString);
  RichMemo1.LoadRichText(Stream);
  Stream.Free;
end;
 
procedure TForm1.BtnSaveToFileClick(Sender: TObject);
var
  Stream: TStringStream;
  FileStream: TFileStream;
  RTFString: String;
begin
  RTFString := 'UTF-8 Text ÄÖÜ „ “ ‘ ‚ Œʊʘ˄ϘҰՓ Test';
  RTFString := StringToRTF(RTFString);
  RTFString :='{\rtf1\ansi\deff0\adeflang1025{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}} ' + RTFString + '}';
  Stream := TStringStream.Create(RTFString);
  FileStream := TFileStream.Create('created.rtf', fmCreate);
  FileStream.CopyFrom(Stream, Stream.Size);
  FileStream.Free;
  Stream.Free;
end;  
Habe auch mal das TestProg angehangen. Evtl. hilfts dir ja.
Dateianhänge
TestRTF.zip
(2.55 KiB) 44-mal heruntergeladen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

teertinker
Beiträge: 6
Registriert: Mo 25. Apr 2016, 10:33

Re: Sonderzeichen in Richedit

Beitrag von teertinker »

Vielen Dank Michl!!! Mit der Funktion funktioniert es endlich! Nebenbei habe ich noch herausgefunden, dass mein selbstproduzierter Richtext nur für die LZrichedit-Komponente gepasst hat, nicht mehr jedoch im Richmemo.

Statt {\i italic_text} muss man nun {\i italic_text\i0} eingeben.

Nun habe ich endlich meinen Frieden mit dem Richmemo gefunden.

Antworten