1

i am drawing text and image in tvirtuailstringtree as following in onbeforecellpaint event

begin
Textrectplace := NewRect;
Textrectplace.Left := Textrectplace.Left + 2;
Textrectplace.Width := 24;
Textrectplace.Height := Data.image.height;
Textrectplace.Top := Textrectplace.Top;
Textrectplace.Bottom := Textrectplace.Bottom;
xOfftext := Textrectplace.Left + Textrectplace.Width + 4;

yOfftext := Textrectplace.Top - 3 + ((Data.image.height - TargetCanvas.TextHeight('H')) div 2);
TargetCanvas.font.color := clgray;
TargetCanvas.font.Size := 10;
TargetCanvas.TextOut(xOfftext, yOfftext, Data.text);
end;

end;


begin
imgrect:= Textrectplace;
imgrect.Left := imgrect.Left + 150;
imgrect.Width := 24;
imgrect.Height := 36;
imgrect.Top := imgrect.Top - 6 + ((Data.image.height - TargetCanvas.TextHeight('H')) div 2);
imgrect.Bottom := imgrect.Bottom;

TargetCanvas.Draw(imgrect.Left, imgrect.Top, Data.image);
end;

I have one problem in text and image alignment I wanted the text to be aligned to left and that part is handled . the image has align problem I wanted to make it aligned to the Right with the text without textoverflow currently if the node has short text its all good and the image showing correctly with the text . but if the text is too long its overflow the image .

here is example image

enter image description here

in the image example It shows how the long texted node looks like and how it should be if the text is too long and the list width is small for the alignment of the image with text it should show I am long nod... until the list become bigger then show the full text which is I am long node text how can I achieve that

Updated Code

procedure TForm1.virtuailtreeBeforeCellPaint(Sender: TBaseVirtualTree;
      TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
      CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
var
Data: ^PnodeData;
NewRect: TRect;
Textrectplace: TRect;
imgrect : TRect;

begin



if not Assigned(Node) then
begin
exit;
end;

Data := virtuailtree.GetNodeData(Node);

NewRect := CellRect;




//text
begin
Textrectplace := NewRect;
Textrectplace.Left := Textrectplace.Left + 2;
Textrectplace.Width := 70;
Textrectplace.Height := 30;
Textrectplace.Top := Textrectplace.Top;
Textrectplace.Bottom := Textrectplace.Bottom;
TargetCanvas.font.color := clgray;
TargetCanvas.font.Size := 10;
DrawText(TargetCanvas.Handle, pChar(Data.text), Length(Data.text)
, Textrectplace, DT_End_Ellipsis );
end;

end;

//right image that should be stay at the right position 


begin
imgrect := Textrectplace;
imgrect.left := imgrect.left + 150;
imgrect.Width := 24;
imgrect.Height := 36;
imgrect.Top := imgrect.Top - 6 + ((30 - TargetCanvas.TextHeight('H')) div 2);
imgrect.Bottom := imgrect.Bottom;


TargetCanvas.Draw(imgrect.left, imgrect.Top, Data.image);
end;




end;
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Raelpaul
  • 31
  • 5
  • What is `NewRect`, where and how does it receive its value? What is the meaning of `XOffText` (why is it given a value beyond `TextRectPlace`. Have you considered using `DrawText()` instead of `TextOut()`? – Tom Brunberg Mar 04 '17 at 09:48
  • Use the textwidth function to see if the text is too long, then shorten it character by character until it fits. – Dsm Mar 04 '17 at 10:02
  • NewRect is a `TRect` var . xofftext to make the drawing text centered with an image , drawtext will make any difference ? – Raelpaul Mar 04 '17 at 10:03
  • @Dsm Shorten is a part of the idea but what I couldn't figure out is how to show the full text if the list size come bigger – Raelpaul Mar 04 '17 at 10:11
  • Not sure I understand the question, but if you are saying when the component resizes then it is automatic because the cell repaints and the function will be called again. – Dsm Mar 04 '17 at 10:14
  • Ah - but don't permanently shorten the text - just use a temporary copy for painting purposes and shorten that. – Dsm Mar 04 '17 at 10:16
  • @TomBrunberg I used drawtext to shorten the text and it helps Thanks for that reference – Raelpaul Mar 04 '17 at 10:34
  • @Dsm using drawtext is shorten the text as following `DrawText(TargetCanvas.Handle, pChar(Data.text), Length(Data.text) , Textrectplace, DT_End_Ellipsis );` – Raelpaul Mar 04 '17 at 10:35
  • @Dsm but on resizing the text still shorten I use splitter to resize – Raelpaul Mar 04 '17 at 10:36
  • I don't see what difference using a splitter makes. Your code is not complete. Please give us a small, complete example that illustrates your problem. Then we can try it in our compilers to see if we can see what your problem is. – Dsm Mar 04 '17 at 10:52
  • I assume you are using owner draw? – Dsm Mar 04 '17 at 10:53
  • @Dsm Updated Code added – Raelpaul Mar 04 '17 at 11:05
  • Yes, Raelpaul, that's exactly what I meant with `DrawText()`. Do you have 1 or more columns? Which column are we now speaking about? Have you aligned (e.g. `alLeft`) the `TVirtualStringTree` and are you then using the `TSplitter` to resize the `TVirtualStringTree`? If yes, then adjust the size of `TextRectPlace` accordingly. But this raises the question what will you do with the image? I guess move it. – Tom Brunberg Mar 04 '17 at 11:35
  • I have only one column that contain every thing text and image , the point of resizing is to move that image exactly the same way as column – Raelpaul Mar 04 '17 at 11:43
  • So, `TextRectPlace.Right := ItemRect - imgRect.width; imgRect.Left := TextRectPlace.Right;` – Tom Brunberg Mar 04 '17 at 11:50
  • Sorry, I looked at wrong paint stage. In my previous comment replace `ItemRect` with `CellRect`. – Tom Brunberg Mar 04 '17 at 12:01
  • @TomBrunberg That's totally a solve . Thank you very much please answer the question so I can accept it – Raelpaul Mar 04 '17 at 12:11

2 Answers2

1

To shorten the text to fit within a TRect you can use the WinApi DrawText() function, with DT_END_ELLIPSIS format specifier.

To adjust the space for text when the TVirtualStringTree is resized (e.g. with a TSplitter) simply use:

TextRectPlace.Right := CellRect - imgRect.width;
imgRect.Left := TextRectPlace.Right;
Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
0

This example shows how to make the column cell and heading text aligned to the left and cell image to the right :

VirtualStringTree1.Alignment := taLeftJustify;
VirtualStringTree1.BiDiMode  := bdLeftToRight;
VirtualStringTree1.Header.Columns[ 0 ].Alignment := taRightJustify;
VirtualStringTree1.Header.Columns[ 0 ].BiDiMode := bdRightToLeftNoAlign;
VirtualStringTree1.Header.Columns[ 0 ].CaptionAlignment := taRightJustify;

image

xavior
  • 1
  • 2