【发布时间】:2014-09-11 00:32:17
【问题描述】:
我需要绘制一些图形作为节点图像。 就像它在 OnGetImageIndex 事件中从 ImageList 中绘制图像一样,但来自 TIcon、TImage、TBitmap 等单一来源。
在我的情况下,所有节点在 UserData 记录中都有自己的图标和位置。
如何将这些图标绘制到节点上?
我在这里找到了这段代码,并尝试适应我的情况:
procedure TForm10.Button1Click(Sender: TObject);
var
Node: PVirtualNode;
begin
VirtualStringTree1.AddChild(nil);
Node := VirtualStringTree1.AddChild(nil);
VirtualStringTree1.AddChild(Node);
Node := VirtualStringTree1.AddChild(Node);
VirtualStringTree1.AddChild(Node);
VirtualStringTree1.AddChild(Node);
VirtualStringTree1.AddChild(Node);
end;
procedure TForm10.VirtualStringTree1AfterItemPaint(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect);
var
rImage: TRect;
OffsetLeft: Integer;
Icon: TIcon;
begin
rImage := ItemRect;
Icon := TIcon.Create;
Icon.LoadFromFile('TestIcon_16.ico');
with TVirtualStringTree(Sender) do
begin
if (toShowRoot in TreeOptions.PaintOptions) then
OffsetLeft := Indent * (GetNodeLevel(Node) + 1)
else
OffsetLeft := Indent * GetNodeLevel(Node);
Inc(rImage.Left, Margin + OffsetLeft);
Inc(rImage.Top, (NodeHeight[Node] - Icon.Height) div 2);
rImage.Right := rImage.Left + Icon.Width;
rImage.Bottom := rImage.Top + Icon.Height;
end;
DrawIcon(TargetCanvas.Handle, rImage.Left, rImage.Top, Icon.Handle);
end;
点击按钮后,我看到:
为什么会这样? 图标大小 100% - 16 x 16 像素。
我在哪里可以解决绘制文本的问题?
我做错了什么?
【问题讨论】:
-
为什么会这样?因为树不知道您正在这样做,并且不会缩进节点文本来为您的图像腾出空间。
-
如何通知?还是有其他想法可以做到这一点?
-
由于我没有使用此组件的任何经验,我只是猜测。但是您不应该改用 OnBeforeItemPaint 事件。我认为通过使用该事件,您可能有机会控制文本的位置,以便它不会绘制在与您的 incons 相同的位置。如果没有别的,您可以通过添加几个空格来更改文本,使其向右移动。在 OnAfterItemPaint 事件中执行此操作将不起作用,因为在事件触发时文本已被绘制。
-
嗯,首先你需要告诉树腾出一些空间。这就是您可以通过增加
OnMeasureTextWidth事件方法的Extent参数来实现的。然后在OnDrawText事件方法中自己绘制文本。但更好的是,您将使用图像列表的默认方法。您可以将这些图像存储到图像列表中,并且每个节点存储只是对该图像列表的索引,不是吗? -
您肯定会看到一个 32x32 的图标。它发生在 b/c 你加载 16x16 图标并用
DrawIcon绘制它,它会拉伸它。您可以使用DrawIconEx或简单地使用TargetCanvas.Draw(x, y, Icon)。无论如何,您泄漏了 TIcon 的内存,我真的不明白为什么您不想使用带有OnGetImageIndex的 ImageList,这真的是正确的方法吗?...
标签: delphi delphi-xe6 virtualtreeview tvirtualstringtree