如何实现TTreeView OnCustomDrawItem,以便完全绘制并将DefaultDraw设置为false

War*_* P 8 delphi treeview

使用TTreeView.OnAdvancedCustomDrawItem或TTreeView.CustomDrawItem,如何完全绘制树视图项?docwiki上没有高级自定义绘图项的示例代码.

德尔福文档网站,有引用不样品中存在的代码,不编译一个混乱的样品.我认为问题分为三个独立的绘画问题:

  1. 获取Windows树视图节点的主题元素并绘制它.
  2. 获取节点中存在的任何图像并对其进行绘制.
  3. 绘制节点的文本.

最后,应设置一个DefaultDraw := false以便控件不对节点执行默认绘制.

在我看来,这样一个基本的东西应该作为一个真正的工作样本存在,但我发现的最接近的是文档维基,它只是说"看到这个其他的东西",并没有提供其他代码的链接.

非工作样本带有相当多的挥手和不完整的代码,引用了一些未在本演示中定义的内容,但显然是从工作样本中剪切和粘贴的.一些人所做的改变是显而易见的(比如定义你自己的方式来获取画笔的颜色,以及你自己决定节点应该是什么字体的方式),有些则不是,比如如何实现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;
Run Code Online (Sandbox Code Playgroud)