使用 TTreeView.OnAdvancedCustomDrawItem 或 TTreeView.CustomDrawItem,如何完全绘制树视图项?高级自定义绘图项目的 docwiki 上没有示例代码。
Delphi 文档 wiki有一个令人困惑的示例,其中引用了示例中不存在且无法编译的代码。我认为问题分为三个独立的绘画问题:
- 获取 Windows 树视图节点的主题元素并绘制它。
- 获取节点中存在的任何图像并绘制它。
- 绘制节点的文本。
最后,应该设置DefaultDraw := false
控件不为节点执行默认绘制。
在我看来,这样一个基本的东西应该作为一个真正的工作样本存在于某个地方,但我发现的最接近的是文档 wiki,它只是说“查看其他东西”并且没有提供到其余代码的链接。
非工作示例具有太多的挥手和不完整的代码,引用了本演示中未定义的一些内容,但显然是从工作示例中剪切和粘贴的。一些改变是显而易见的(比如定义你自己的方式来获取画笔的颜色,以及你自己的方式来决定节点应该是什么字体),而有些则不是,比如如何实现DrawButton
:
procedure TCustomDrawForm.TVCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
State: TCustomDrawState; var DefaultDraw: Boolean);
var
NodeRect: TRect;
begin
with TV.Canvas do
begin
{
If DefaultDraw it is true, any of the node's font
properties can be changed. Note also that when
DefaultDraw = True, Windows draws the buttons and
ignores our font background colors, using instead the
TreeView's Color property.
}
if cdsSelected in State then
begin
Font.Assign(SelectedFontDialog.Font);
Brush.Color := SelBkgColorDialog.Color;
end;
DefaultDraw := False; // FDefaultDrawItem;
{
DefaultDraw = False means you have to handle all the
item drawing yourself, including the buttons, lines,
images, and text.
}
if not DefaultDraw then
begin
//draw the selection rect.
if cdsSelected in State then
begin
NodeRect := Node.DisplayRect(True);
FillRect(NodeRect);
end;
NodeRect := Node.DisplayRect(False);
if None1.Checked then
//no bitmap, so paint in the background color.
begin
Brush.Color := BkgColorDialog.Color;
Brush.Style := FBrushStyle;
FillRect(NodeRect)
end
else
//don't paint over the background bitmap.
Brush.Style := bsClear;
NodeRect.Left := NodeRect.Left + (Node.Level * TV.Indent);
// NodeRect.Left now represents the left-most portion
// of the expand button
DrawButton(NodeRect, Node); // See the CustomDraw demo
NodeRect.Left := NodeRect.Left + TV.Indent + FButtonSize;
//NodeRect.Left is now the leftmost portion of the image.
DrawImage(NodeRect, Node.ImageIndex); // See the CustomDraw demo
NodeRect.Left := NodeRect.Left + ImageList.Width;
//Now we are finally in a position to draw the text.
TextOut(NodeRect.Left, NodeRect.Top, Node.Text);
end;
end;
end;