Hi,
ich raufe mir die wenigen verblieben Haare: es soll ein parser geschrieben werden, der wie z.B. der Delphi-Editor bestimmte Worte oder Zeichen fett oder farbig darstellt. der folgende source ist ein ergebnis, welches bei kleinen texten auch prima funktioniert
<PRE>
TWordPos = record
aWord : string;
StartPos : LongInt;
EndPos : LongInt;
WordLen : integer;
end;
const
cLIMITS = ';:=.()<>[],-' + #39 + '+*!?"§$%&/\?{}';
// die reswords habe ich zum test der delphi-hilfe entnommen und lese als .txt ein
procedure SetLangAttr2Text(aRichEdit: TRichEdit; StartPos,TextLen: integer; ResWords: TStringList; Limeters: string);
var pointer;
WordPos : TWordPos;
i,j,FoundInt,EndPos : LongInt;
s: string;
begin
WordPos.StartPos := 0; WordPos.EndPos := 0; WordPos.WordLen := -1; s := '';
p := pChar(aRichedit.Text); j:= StartPos; aRichEdit.SelStart := StartPos;
inc(pChar(p),StartPos);
if TextLen < 0 then EndPos := Length(aRichEdit.Text) else EndPos := j + TextLen;
while pChar(p)^ <> #0 do
begin
//Wir durchlaufen den Text vorwärts, also ist Start immer bekannt
//nämlich zum ersten Zeitpunkt, wenn kein Limeter auftritt
if IsLimeter(char(p^),cLIMITS) then
begin
WordPos.aWord := s; // das Wort ist fertig
// Limeter einfärben ?
if Form1.Checkbox1.checked = true then
begin
if ord(char(p^))> 32 then
begin
aRichEdit.SelStart:= j;
aRichEdit.SelLength := 1;
aRichEdit.SelAttributes.Color := clRed;
aRichEdit.SelAttributes.Style := [];
end;
end;
if length(s) > 0 then
begin
WordPos.EndPos := j;
WordPos.WordLen := length(s);
end;
s:= '';
end
else
begin
if s = '' then
begin
WordPos.StartPos := j;
WordPos.EndPos := 0;
WordPos.WordLen := -1;
end;
s:= s + pChar(p)^;
end;
i := 1;
if WordPos.WordLen > 0 then
begin
FoundInt := 0;
try
if trim(WordPos.aWord) <> '' then ResWords.find(trim(WordPos.aWord),FoundInt);
except
ShowMessage(WordPos.aWord);
end;
if (FoundInt > -1) and (FoundInt <= ResWords.Count-1) then
begin
if lowercase(ResWords[FoundInt]) = lowercase(WordPos.aWord) then
begin
aRichEdit.SelStart:= WordPos.StartPos;
aRichEdit.SelLength := WordPos.WordLen;
aRichEdit.SelAttributes.Color := clBlack;
aRichEdit.SelAttributes.Style := [fsBold];
i := WordPos.WordLen;
end;
end;
end;
inc(pChar(p),i); inc(j,i);
if j > EndPos then break;
end;
end;
</PRE>
werden alle teile ausgeklammert, die das richedit manipulieren (aRichEdit. ..), dann rennt der Code auch bei der ComCtrls mit > 700 kb, ansonsten kann man Kaffee trinken gehen.
gibt es einen weg, das richedit direkter zu manipulieren, mache ich was falsch oder wo ist der haken? delphi kann's doch auch
für "den" tipp wäre ich wirklich dankbar
gruss, bernhard
ps: die function IsLimeter testet den Const cLIMITS durch und hält nachweislich den code nicht auf
ich raufe mir die wenigen verblieben Haare: es soll ein parser geschrieben werden, der wie z.B. der Delphi-Editor bestimmte Worte oder Zeichen fett oder farbig darstellt. der folgende source ist ein ergebnis, welches bei kleinen texten auch prima funktioniert
<PRE>
TWordPos = record
aWord : string;
StartPos : LongInt;
EndPos : LongInt;
WordLen : integer;
end;
const
cLIMITS = ';:=.()<>[],-' + #39 + '+*!?"§$%&/\?{}';
// die reswords habe ich zum test der delphi-hilfe entnommen und lese als .txt ein
procedure SetLangAttr2Text(aRichEdit: TRichEdit; StartPos,TextLen: integer; ResWords: TStringList; Limeters: string);
var pointer;
WordPos : TWordPos;
i,j,FoundInt,EndPos : LongInt;
s: string;
begin
WordPos.StartPos := 0; WordPos.EndPos := 0; WordPos.WordLen := -1; s := '';
p := pChar(aRichedit.Text); j:= StartPos; aRichEdit.SelStart := StartPos;
inc(pChar(p),StartPos);
if TextLen < 0 then EndPos := Length(aRichEdit.Text) else EndPos := j + TextLen;
while pChar(p)^ <> #0 do
begin
//Wir durchlaufen den Text vorwärts, also ist Start immer bekannt
//nämlich zum ersten Zeitpunkt, wenn kein Limeter auftritt
if IsLimeter(char(p^),cLIMITS) then
begin
WordPos.aWord := s; // das Wort ist fertig
// Limeter einfärben ?
if Form1.Checkbox1.checked = true then
begin
if ord(char(p^))> 32 then
begin
aRichEdit.SelStart:= j;
aRichEdit.SelLength := 1;
aRichEdit.SelAttributes.Color := clRed;
aRichEdit.SelAttributes.Style := [];
end;
end;
if length(s) > 0 then
begin
WordPos.EndPos := j;
WordPos.WordLen := length(s);
end;
s:= '';
end
else
begin
if s = '' then
begin
WordPos.StartPos := j;
WordPos.EndPos := 0;
WordPos.WordLen := -1;
end;
s:= s + pChar(p)^;
end;
i := 1;
if WordPos.WordLen > 0 then
begin
FoundInt := 0;
try
if trim(WordPos.aWord) <> '' then ResWords.find(trim(WordPos.aWord),FoundInt);
except
ShowMessage(WordPos.aWord);
end;
if (FoundInt > -1) and (FoundInt <= ResWords.Count-1) then
begin
if lowercase(ResWords[FoundInt]) = lowercase(WordPos.aWord) then
begin
aRichEdit.SelStart:= WordPos.StartPos;
aRichEdit.SelLength := WordPos.WordLen;
aRichEdit.SelAttributes.Color := clBlack;
aRichEdit.SelAttributes.Style := [fsBold];
i := WordPos.WordLen;
end;
end;
end;
inc(pChar(p),i); inc(j,i);
if j > EndPos then break;
end;
end;
</PRE>
werden alle teile ausgeklammert, die das richedit manipulieren (aRichEdit. ..), dann rennt der Code auch bei der ComCtrls mit > 700 kb, ansonsten kann man Kaffee trinken gehen.
gibt es einen weg, das richedit direkter zu manipulieren, mache ich was falsch oder wo ist der haken? delphi kann's doch auch
für "den" tipp wäre ich wirklich dankbar
gruss, bernhard
ps: die function IsLimeter testet den Const cLIMITS durch und hält nachweislich den code nicht auf
Comment