TRichEdit color problems
ans:= RichEdit1.Text
for i:=1 to Length(ans) do
begin
RichEdit1.SelStart := i-1;
RichEdit1.SelLength:= 1;
if ans[i] = correct[i] then
RichEdit1.SelAttributes.Color := clRed
else
RichEdit1.SelAttributes.Color := clBlue;
If the letter in ans
matches the letter in the same position as the letter in correct
string, it is colored red otherwise, it is blue.
My problem is when I type again the whole RichEdit1 text is colored as the same as the first letter (if the first letter of RichEdit1
is blue then the whole text becomes blue).
By the way, this is not the the actual code I just simplified it because there are mutiple TRichEdits.
The TRichEdits are read-only and I assign the letters by something likeRichEdit1.开发者_JAVA技巧Text := RichEdit1.Text+Key;
(doing this because it's a multiple keyboard program and I need to separate user inputs)
Is this the correct behavior? How can I stop my color changes from overriding the default color?
update: Solved it... in a sloppy way (applying the default color whenever someone types), but I'm keeping this open in case someone comes up with a better solution.
As you already discovered, you have to reset the default color when you are done, eg:
ans := RichEdit1.Text;
for i := 1 to Length(ans) do
begin
RichEdit1.SelStart := i-1;
RichEdit1.SelLength := 1;
if ans[i] = correct[i] then
RichEdit1.SelAttributes.Color := clRed
else
RichEdit1.SelAttributes.Color := clBlue;
end;
RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.SelLength := 0;
RichEdit1.SelAttributes.Color := RichEdit1.Font.Color;
There are more efficient ways to handle this than coloring one letter at a time, eg:
const
colors: array[Boolean] of TColor = (clRed, clBlue);
var
ans: string;
start, len: Integer;
cur_state: Boolean;
procedure ColorRange(AStart, ALength: Integer; AColor: TColor);
begin
RichEdit1.SelStart := AStart;
RichEdit1.SelLength := ALength;
RichEdit1.SelAttributes.Color := AColor;
end;
begin
RichEdit1.Lines.BeginUpdate;
try
ans := RichEdit1.Text;
start := 0;
len := 0;
cur_start := False;
for i := 1 to Length(ans) do
begin
if (ans[i] = correct[i]) = cur_state then
Inc(len)
else begin
if len > 0 then
ColorRange(start, len, colors[cur_state]);
start := i-1;
len := 1;
cur_state := not cur_state;
end;
end;
if len > 0 then
ColorRange(start, len, colors[cur_state]);
ColorRange(RichEdit1.GetTextLen, 0, RichEdit1.Font.Color);
finally
RichEdit1.Lines.EndUpdate;
end;
end;
Also, using the Text property to append a single Char is very inefficient. Use the SelText property instead, eg:
RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.SelLength := 0;
RichEdit1.SelAttributes.Color := ...; // optional
RichEdit1.SelText := Key;
精彩评论