Независимо изменить цвет текста RichEdit с уже загруженным текстом

Как я могу изменить цвет текста Rich Edit построчно? Это зависит от должности. Первая строка должна быть красной, вторая – зеленой и так далее. Проблема в том, что текст Rich Edit уже загружен. Поэтому его необходимо изменить после того, как текст уже находится в элементе управления. Я использую Делфи.


person Arno Jonck    schedule 27.05.2020    source источник


Ответы (2)


Лучше с самого начала загрузить его правильными цветами.

Но чтобы ответить на ваш вопрос, быстрое, грязное и довольно уродливое решение - сделать

function RandomColor: TColor;
begin
  Result := RGB(Random(256), Random(256), Random(256))
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to RichEdit1.Lines.Count - 1 do
  begin
    RichEdit1.CaretPos := Point(0, i);
    RichEdit1.SelLength := RichEdit1.Lines[i].Length;
    RichEdit1.SelAttributes.Color := RandomColor;
  end;
end;
person Andreas Rejbrand    schedule 27.05.2020
comment
Обратите внимание: вы можете использовать сообщение EM_EXSETSEL, чтобы установить начало и конец выделения одновременно (CaretPos делает это внутри, устанавливая начало и конец в одно и то же значение). Кроме того, вы должны использовать сообщение EM_LINELENGTH вместо RichEdit1.Lines[i].Length. Кроме того, вы должны использовать сообщение EM_SETEVENTMASK для отключения уведомлений EN_SELCHANGE (запуск события TRichEdit.OnSelectionChange) при манипулировании выбором. А затем оберните весь код в WM_SETREDRAW, чтобы отключить обновления экрана при изменении цветов. - person Remy Lebeau; 27.05.2020
comment
@RemyLebeau: я знаю. Вот почему я подчеркнул, что решение быстрое, грязное и довольно уродливое. (И у меня не было времени изучать подробности API RichEdit. Однако во многих практических ситуациях этого решения достаточно.) Не стесняйтесь публиковать улучшенную версию в качестве ответа, и я удалю эту. - person Andreas Rejbrand; 27.05.2020
comment
Да, я видел эту страницу. Но использование элемента управления RIch Edit в качестве редактора программиста с подсветкой синтаксиса не идеально, даже если это возможно? :) - person Andreas Rejbrand; 27.05.2020
comment
Нет, RichEdit не лучший выбор для редактора с подсветкой синтаксиса. Но для простого линейного логгера этого будет достаточно. И это должно решить те же проблемы, что и подсветка синтаксиса при работе с цветом после вставки текста. - person Remy Lebeau; 27.05.2020

Если содержимое элемента управления richedit не разделено на строки, а скорее переносится на лету в зависимости от размера элемента управления (возможно, изменяющегося при изменении размера формы), вы можете использовать эту процедуру для попеременного окрашивания линий между красным, зеленым и синим цветом. :

procedure TForm1.Button1Click(Sender: TObject);
const
  ColorWheel: array[0..2] of TColor = (clRed, clGreen, clBlue);
var
  RowNr, RowStartPos, RowEndPos, C: Integer;
  HasReachedEnd: Boolean;
begin
  HasReachedEnd := False;
  RowStartPos := 0;
  C := 0;
  RowNr := 1;
  repeat
    RowEndPos := RichEdit1.Perform(EM_LINEINDEX, RowNr, 0);
    if RowEndPos = -1 then
    begin
      // Last row reached
      HasReachedEnd := True;
      RowEndPos := RichEdit1.GetTextLen;
    end;
    // Select text
    RichEdit1.SelStart := RowStartPos;
    RichEdit1.SelLength := RowEndPos - RowStartPos;
    // Change selected text colour
    RichEdit1.SelAttributes.Color := ColorWheel[C];
    C := (C + 1) mod 3;
    // Prepare for next row
    RowStartPos := RowEndPos;
    Inc(RowNr);
  until HasReachedEnd;
end;
person Matthias B    schedule 27.05.2020
comment
Вы должны использовать RichEdit1.GetTextLen() вместо Length(RichEdit1.Lines.Text) - person Remy Lebeau; 27.05.2020
comment
Ах, действительно! Я редактирую свой ответ, чтобы включить ваше правильное предложение. - person Matthias B; 27.05.2020