If a node in a VirtualStringTree is multiline (vsMultiline in Node.States) then how can i centre the text vertically for all columns (except the multiline column) in that node?
I have tried using the OnBeforeCellPaint
(using TargetCanvas.TextOut()
) but this does not paint the text at all. By default, the text for a multiline node is always painted at the top of the node.
(For non-multiline nodes the text is painted vertically centred).
Thanks to XBasic3000, i was able to come up with this solution, which covers almost every possible combination:
procedure TForm1.TreeDrawText(
Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
Column: TColumnIndex; const Text: WideString; const CellRect: TRect;
var DefaultDraw: Boolean);
var DrawFormat : Cardinal;
R : TRect;
s : WideString;
NodeWidth,EllipsisWidth : Integer;
Size: TSize;
begin
if not (Column in [yourmultilinecolumns]) then
begin
DefaultDraw := False;
R := CellRect;
GetTextExtentPoint32W(TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
NodeWidth := Size.cx + 2 * Tree.TextMargin;
GetTextExtentPoint32W(TargetCanvas.Handle, '...', 3, Size);
EllipsisWidth := Size.cx;
if ((NodeWidth - 2 * Tree.TextMargin) > R.Right - R.Left) then
s := EllipseString(TargetCanvas.Handle, Text, R.Right - R.Left, EllipsisWidth)
else s := Text;
DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE;
Windows.DrawTextW(TargetCanvas.Handle, PWideChar(s), Length(s), R, DrawFormat);
end;
end;
The EllipseString() method is very similar to VirtualTrees.ShortenString() in VirtualTrees.pas.
The only isue is the inability to draw multiline text on other columns. You must specify the multilinecolumns set, so there is no capability to draw multiline and vertically centred.