6
votes

I would like to highlight the text from a node of VirtualStringTree according to search criteria like example from bellow:

enter image description here

Any suggestion please?

1
I am not aware of any build-in feature to highlight any text. You will probably need to use owner-draw methods - OnBeforeCellPaint, OnPaintText etc. - smooty86
Do you need to have support for multiline nodes with wrapped text ? - TLama
Now since you mention about wrapped text, I will search for some help about. In this moment I have no idea about how to handle this, at least from where to start to looking for... Anyhow if you have some links or info that can help me is welcome. Thank you in advance! - REALSOFO
Briefly; VT uses DrawText WinAPI function for text rendering (and fires the OnDrawText event if assigned). That's the place where I would render the text background (e.g. making a sort of OnBeforeDrawText event might be useful). I'm saying so, because in earlier stages, the VT does not know anything about the text and you would be repeating what is done after the events like OnBeforeCellPaint fires and before the text is actually rendered. And the task itsef is not easy for wrapped text. And it's not actually related to VT, but as a generic GDI task. - TLama
Possible duplicate of stackoverflow.com/q/31984898/960757 - TLama

1 Answers

1
votes

Thanks to TLama answer (How to underline or highlight a part of node caption) I adjust a bit the code in order to highlight the text also in the middle.

procedure Tform_main.vt_mainDrawText(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  const Text: string; const CellRect: TRect; var DefaultDraw: Boolean);
var
  BackMode, position: Integer;
begin
  // if the just rendered node's Text contain the text written in a TEdit control
  // called Edit, then...
  position:= Pos(AnsiLowerCase(edit_search.Text), AnsiLowerCase(text));
  if position > 0 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 + TargetCanvas.TextWidth(Copy(Text, 1, position-1)),
      CellRect.Top + 3,
      CellRect.Left  + TargetCanvas.TextWidth(Copy(Text, 1, position-1)) + TargetCanvas.TextWidth(Copy(Text, position, Length(edit_search.Text))),
      CellRect.Bottom - 3)
    );
    // restore the original background mode (as it likely was modified by setting the
    // brush color)
    SetBkMode(TargetCanvas.Handle, BackMode);
  end;
end;

Best wishes to TLama!