TRichEdit цветовые проблемы
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;
Если письмо в ans
соответствует букве в той же позиции, что и буква в correct
Строка, она окрашена в красный цвет, в противном случае, это синий.
Моя проблема заключается в том, что при повторном вводе весь текст RichEdit1 окрашивается так же, как и первая буква (если первая буква RichEdit1
синий, тогда весь текст становится синим).
Кстати, это не тот код, который я просто упростил, потому что есть несколько TRichEdits.
TRichEdits доступны только для чтения, и я назначаю буквы чем-то вроде RichEdit1.Text := RichEdit1.Text+Key;
(делает это, потому что это программа с несколькими клавиатурами, и мне нужно разделять пользовательский ввод)
Это правильное поведение? Как я могу остановить свои изменения цвета от переопределения цвета по умолчанию?
обновление: решено... небрежным способом (применяя цвет по умолчанию всякий раз, когда кто-то печатает), но я оставляю это открытым на случай, если кто-то придумает лучшее решение
1 ответ
Как вы уже обнаружили, вы должны сбросить цвет по умолчанию, когда вы закончите, например:
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;
Есть более эффективные способы справиться с этим, чем раскрашивать по одной букве за раз, например:
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;
Кроме того, использование свойства Text для добавления одного Char очень неэффективно. Вместо этого используйте свойство SelText, например:
RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.SelLength := 0;
RichEdit1.SelAttributes.Color := ...; // optional
RichEdit1.SelText := Key;