I would like to highlight the line that contains the caret in a TMemo
control, similar to the editor in the Delphi IDE. I tried the following code and it kind of works:
(Sorry for the With-statement, this needs refactoring.)
procedure TMemo.WMPaint(var Message: TWMPaint);
var
PS: TPaintStruct;
DC: Hdc;
Canvas: TCanvas;
LineIdx: Integer;
X, Y: Integer;
Max: Integer;
s: string;
h: Integer;
begin
DC := Message.DC;
if DC = 0 then
DC := BeginPaint(Handle, PS);
Canvas := TCanvas.Create;
try
Canvas.Handle := DC;
Canvas.Font.Name := Font.Name;
Canvas.Font.Size := Font.Size;
with Canvas do begin
Max := TopLine + VisibleLines;
if Max > Pred(Lines.Count) then
Max := Pred(Lines.Count);
Brush.Color := Self.Color;
FillRect(Self.ClientRect);
Brush.Color := clYellow;
h := Canvas.TextHeight('Mg');
Y := (Line - TopLine) * h;
Marker.Top := y + self.Top;
FillRect(Rect(0, Y, ClientRect.Right, Y + h));
Brush.Color := Self.Color;
Y := 1;
for LineIdx := TopLine to Max do begin
X := 2;
s := Lines[LineIdx];
if LineIdx = Line then
Brush.Color := clYellow
else
Brush.Color := Self.Color;
TextOut(X, Y, s);
Inc(Y, h);
end;
end;
finally
if Message.DC = 0 then
EndPaint(Handle, PS);
end;
Canvas.Free;
inherited;
end;
(This code is added to the memo through an interposer class.)
This works, but it isn't triggered often enough. E.g. when I scroll using the down arrow.
I could, of course now start adding all kinds of events in order to call the memo's invalidate method and so forcing a repaint, but that doesn't seem right. Maybe there is already such a component, that I could just use? I already checked TJvMemo
from the Jvcl
which doesn't seem to have such a feature.
Edit: I ended up using SynEdit.
TMemo
doesn't support that feature natively, and attempting to add that feature will lead to no end of headaches.
Instead, consider using a different text-editing control. That's what the Delphi IDE does. SynEdit, for example, supports the feature: Set the ActiveLineColor
property to something other than clNone
.