How to underline or highlight part of a node header

I want to implement a search function in my virtualtreeview. And I want to highlight or emphasize the search word in the nodes.

How can i do this? thank you

+3
source share
2 answers

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:

enter image description here

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:

enter image description here

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.

+6
source

Small modification. Please note if.

 var BackMode: integer; begin inherited; // if the just rendered node Text starts with the text written in a TEdit control // called Edit, then... if StartsText(Sender.SearchBuffer, Text) and (Node = Sender.FocusedNode) then begin TargetCanvas.Pen.Color := clRed; TargetCanvas.MoveTo(CellRect.Left, CellRect.Bottom - 2); TargetCanvas.LineTo( CellRect.Left + TargetCanvas.TextWidth(Copy(Text, 1, Length(Sender.SearchBuffer))), CellRect.Bottom - 2 ); end; end; 
0
source

Source: https://habr.com/ru/post/986227/


All Articles