Display additional text in tree nodes, not just node.text

I have a TTreeView in Delphi, with nodes at three levels.

I use node data to store another label besides node text.

Type TNodeData = class ExtraNodeLabel: WideString; //... other members end; 

I have an OnAdvancedCustomDrawItem event where I want to display this ExtraNodeLabel in front of node text. I want to achieve this:

  • The blue text will be an additional label.
  • high-light element: the first two words are also an additional label

enter image description here

What I got so far is:

enter image description here

Problems:

  • For some reason I cannot draw text with a different style if I use DrawText / drawTextW (I need drawtextW because of the data in unicode)
  • Another problem is that everything outside the focus rectangle does not matter

What you need to solve:

  • How can I draw text with a different style using DrawText / drawTextW
  • How can I make all text clickable?

The code:

 procedure TMainForm.TntTreeView1AdvancedCustomDrawItem( Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean); var txtrect, fullrect : TRect; DC: HDC; fs: integer; fc: TColor; ExtralabelRect: TRect; nData: TNodeData; begin nData := nil; if assigned(Node.Data) then begin nData := TNodeData(Node.Data); end; DC := TntTreeView1.canvas.Handle; txtRect := Node.DisplayRect(True); fullrect := Node.DisplayRect(False); if stage = cdPostPaint then begin TntTreeView1.Canvas.FillRect(txtRect); if (cdsFocused In State) And (cdsSelected in State) then begin DrawFocusRect(DC,txtRect); end; txtRect.Left := txtRect.Left + 1; txtRect.Top := txtRect.Top + 1; txtRect.Right := txtRect.Right - 1; txtRect.Bottom := txtRect.Bottom - 1; ExtralabelRect := txtRect; fs := TntTreeView1.Canvas.Font.size; fc := TntTreeView1.Canvas.Font.Color; if (nData <> nil) And (nData.ExtraNodeLabel <> '') then begin TntTreeView1.Canvas.Font.Size := 7; TntTreeView1.Canvas.Font.color := clBlue; DrawTextW( DC, PWideChar(nData.ExtraNodeLabel), Length(nData.ExtraNodeLabel), ExtraLabelRect, DT_LEFT or DT_CALCRECT or DT_VCENTER ); DrawTextW( DC, PWideChar(nData.ExtraNodeLabel), Length(nData.ExtraNodeLabel), ExtraLabelRect, DT_LEFT or DT_VCENTER ); txtRect.right := txtRect.Right + ExtraLabelRect.Right + 5; txtRect.Left := ExtraLabelRect.Right + 5; end; TntTreeView1.Canvas.Font.Size := fs; TntTreeView1.Canvas.Font.color := fc; DrawTextW( DC, PWideChar((Node as TTntTreeNode).Text), -1, txtRect, DT_LEFT or DT_VCENTER ); end; end; 
+7
delphi delphi-5 treeview
source share
1 answer

Solution with OP

I was able to partially solve the user drawing by specifying the TFont variable and using SelectObject and setTextColor . Setting the font color and style works, but the font size is not set.

 var nFont: TFont; begin DC := TntTreeView1.Canvas.Handle; NFont := TFont.Create; // rest of the code here ... // i tried to set nFont.Size, but it doesn't seem to work nFont.Size := 7; nFont.Color := colorToRGB(clBlue); nFont.Style := TntTreeview1.Font.Style + [fsBold]; SelectObject(DC,NFont.Handle); SetTextColor(DC,colortoRGB(clBlue)); DrawTextW( DC, PWideChar(nData.nodeLabel), Length(nData.nodeLabel), ExtraLabelRect, DT_LEFT or DT_VCENTER ); // rest of the code here end; 

Source: I used this idea here.


Update 2

I solved the second problem by setting the treeview RowSelect to true. To do this, I had to set the ShowLines property to false, and the user property to draw lines and buttons. Now it works.


Update 3

I improved the solution for the first problem, not creating a new font, but choosing a canvas font to display text, and thus I was able to change any aspect of the font, as well as cleartype system parameters

 // set font size for the canvas font (font style can be set the same time) TntTreeView1.Canvas.Font.Size := 7; // select canvas font for DC SelectObject(DC,TntTreeView1.Canvas.Font.Handle); // set font color SetTextColor(DC,colortoRGB(clBlue)); 
+2
source share

All Articles