I would write a handler for the OnDrawText event, because this is the only event (at this time) where you get the text node, the rectangle in which this text will be displayed, as well as the canvas prepared for such rendering. There are more appropriate events for both tasks (for example, OnBeforeCellPaint or OnAfterItemErase for highlighting text and OnAfterCellPaint or OnAfterItemPaint for underlining text), only none of them provide text display options like OnDrawText alone.
If your nodes are not multi-line, and you do not care about text alignment, reading orientation, or line cutting, then your task may be as simple as in one of the following examples.
1. Matching the background color of the text
procedure TForm1.VirtualTreeDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect; var DefaultDraw: Boolean); var BackMode: Integer; begin // if the just rendered node Text starts with the text written in a TEdit control // called Edit, then... if StartsText(Edit.Text, Text) then begin // store the current background mode; we need to use Windows API here because the // VT internally uses it (so the TCanvas object gets out of sync with the DC) BackMode := GetBkMode(TargetCanvas.Handle); // setup the color and draw the rectangle in a width of the matching text TargetCanvas.Brush.Color := clYellow; TargetCanvas.FillRect(Rect( CellRect.Left, CellRect.Top + 1, CellRect.Left + TargetCanvas.TextWidth(Copy(Text, 1, Length(Edit.Text))), CellRect.Bottom - 1) ); // restore the original background mode (as it likely was modified by setting the // brush color) SetBkMode(TargetCanvas.Handle, BackMode); end; end;
Example visual output:

2. Underscore text
procedure TForm1.VirtualTreeDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect; var DefaultDraw: Boolean); begin // if the just rendered node Text starts with the text written in a TEdit control // called Edit, then... if StartsText(Edit.Text, Text) then begin TargetCanvas.Pen.Color := clRed; TargetCanvas.MoveTo(CellRect.Left, CellRect.Bottom - 2); TargetCanvas.LineTo( CellRect.Left + TargetCanvas.TextWidth(Copy(Text, 1, Length(Edit.Text))), CellRect.Bottom - 2 ); end; end;
And an example of visual output:

In real code, I would suggest a preliminary calculation of these forms of selection and only draw in the OnDrawText event, but I would leave the optimization to you; I think the main thing is the event itself.