Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - best. Text farbig hervorheben


Knumonmaster - Mo 14.01.08 17:27
Titel: best. Text farbig hervorheben
Hallo

Ich habe ein RichEdit1, in dem Text in clWindowText und Formatierungsangaben, ähnlich BBCode, welche in anderen Farben angegeben sind.

Zum einen benötige ich die Länge der einzelnen Richedit-Zeilen, wobei nur der Text in clWindowText berücksichtigt werden sollte. Die Länge einer Zeile / eines strings kann ich ja mit length() bestimmen.
Zum anderen benötige ich den reinen Text ohne die Formatierungsangaben, als string, um ihn in einem TLabel anzuzeigen.

nun zum Knackpunkt: wie kann ich es machen, dass nur der Text, der in clwindowText geschrieben ist, als string ausgegeben wird?


Ich hoffe, ihr wisst da eine Lösung,
Knumonmaster


Zorro - Mo 14.01.08 18:34
Titel: Re: Text nach Farbe in string kopieren?
user profile iconKnumonmaster hat folgendes geschrieben:

nun zum Knackpunkt: wie kann ich es machen, dass nur der Text, der in clwindowText geschrieben ist, als string ausgegeben wird?


Klingt danach, als müsstest du dich mit dem RTF-Datenformat auseinandersetzen.

Greetz
Zorro


Knumonmaster - Mo 28.01.08 22:45

Inzwischen hab ich es so gemacht, dass ich alles in einen string kopiert habe und danach die Formatierungen gelöscht bzw. notgedrungen ersetzt habe ...

Nun ergibt sich aber mit der selben Syntax-Hervorhebung ein weiteres Feature-Problem: Die Syntax soll bereits nach der eingabe gefärbt werden.
ich habe dabei Syntax wie "\c[n]" oder \n[n]", auch simplere "\$", aber auch html-ähnlich "\>s\<" n:Int s:Str
mit FindText geht das färben schon sehr gut:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
    while FindText(SearchText, StartPos, Endpos, [stMatchCase])<>-1 do
    begin
      Endpos   := Length(RichEdit.Text) - startpos;
      Position := FindText(SearchText, StartPos, Endpos, [stMatchCase]);
      Inc(StartPos, Length(SearchText));
      //SetFocus;
      SelStart  := Position;
      SelLength := Length(SearchText);
      SelAttributes.Color := clr;
    end;


allerdings kann n von 0 bis 9,999 gehen, weshalb diese methodik in verbindung mit einer schleife eher ungeeignet ist ...

zum anderen habe ich eine methodik gefunden, um wie in html alles von zeichen a bis zeichen b zu färben.
allerdings möchte ich z.b. "\c[n]" und "\n[n]" unterschiedlich einfärben ...

eine lösung wäre sicherlich nach "\c[" zu suchen und SelLength dann bis zum "]" zu erweitern ...
aber ich habe keine ahnung wie ich das bewerkstelligen soll ^^;;;

kann mir da jemand weiter helfen?


Hidden - Mo 28.01.08 23:03
Titel: beliebig langer ausgelassener Text
Hi,

Ich schreibe gerade an einem Textverarbeitungsprogramm und habe mich bereits mit der Thematik beschäftigt...
also ich werde es glaube ich so machen:

:arrow: Du suchst den ersten Textteil mit "Pos" und dann ab der Position des ersten den zweiten Textteil mit "PosEx".
:arrow: nun bestimmst du z.B. die Länge bestimmen, etc...
:arrow: soweit ich dich verstanden habe steht da eine Nummer(n) immer drin, also würde ich das ganze noch mit trystrtofloat oder trystrtoint prüfen.

viel Erfolg :D
Am Ende programmierst du es noch aus und ich kann auf deinem code aufbauen, das wäre nützlich :lol:

Edit: posEx gibt es glaube ich erst ab Delphi 7, kannst du aber leicht nachschreiben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function PosEx(const Substr: stringconst S: string; Offset: Integer): Integer;
begin
  if Offset <= 0 then Result := 0
  else
    Result := Pos(Substr, Copy(S, Offset, Length(S)));

  if Result <> 0 then
    Result := Result + Offset - 1;
end;

Ab Delphi 7 ist PosEx im StrUtils.


Knumonmaster - Mo 28.01.08 23:50

btw ich habe Delphi 7 Enterprise (siehe Infos links unter meinem Avatar)

wie suche ich mit Pos bzw. ExPos in einer schleife??
kannst du mir da ein Beispiel geben?

ich hab das jetzt so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
  StartPos := 0;
  with RichEdit1 do
  begin
    Endpos := Length(RichEdit1.Text);
    Lines.BeginUpdate;
    //while FindText('\c[', StartPos, Endpos, [stMatchCase])<>-1 do begin
      Position := FindText('\c[', StartPos, EndPos, [stMatchCase]);
      ExPosition := FindText(']', Position, EndPos, [stMatchCase]);
      //Inc(StartPos, ExPosition-Position+1);
      //SetFocus;
      SelStart  := Position;
      SelLength := ExPosition-Position+1;
      SelAttributes.Color := clRed;
      SelLength := 0;
    //end;
    Lines.EndUpdate;
  end;

wenn ich die schleife und Inc auskommentiere, markiert er nur das "]", wenn ichs ohne Inc mache, rechnet er sich zu tode X3
was bedeutet eigentlich das Inc? wofür ist das da? Oo

edit so: fehlt nur noch ne schleife ^^;;

Delphi-Quelltext
1:
2:
3:
    SetFocus;
    SelStart := Pos('\c[',RichEdit1.Text)-1;
    SelLength := PosEx(']', RichEdit1.Text,1);


Knumonmaster - Di 12.02.08 14:29

so ... ich hab's jetzt endlich geschafft mein Vorhaben zu realisieren.
Ich habe es wieder mit FindText gelöst:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
function SOF2(RichEdit: TRichEdit; SearchText: string; ST2: string; clr: TColor): integer;
var
  StartPos, Position, Pos2, Endpos: Integer;
begin
  StartPos := 0;
  with RichEdit do
  begin
    Endpos := Length(RichEdit.Text);
    while FindText(SearchText, StartPos, Endpos, [stMatchCase])<>-1 do
    begin
      Endpos   := Length(RichEdit.Text) - startpos;
      Position := FindText(SearchText, StartPos, Endpos, [stMatchCase]);
      Pos2 := FindText(ST2, Position, Endpos, [stMatchCase]);
      Inc(StartPos, Length(SearchText));
      SelStart  := Position;
      SelLength := Pos2 - Position + Length(ST2);
      SelAttributes.Color := clr;
    end;
    SelStart  := Length(RichEdit.Text);
    SelLength := 0;
    Result := SelLength;
  end;
end;
{
SOF2(RichEdit1, '\v[', ']', clGreen);
}


Nun bräuchte ich allerdings auch so eine Methode, um in einem String '\v[n]' n:=int mit z.B.'0' zu ersetzen.
Dummerweise geht weder StringReplace, noch FindText :/

Weiß da jmd. abhilfe?


LG
Knumon