TTreeView.OnAdvancedCustomDrawItem または TTreeView.CustomDrawItem を使用して、ツリー ビュー アイテムを完全に描画するにはどうすればよいでしょうか。高度なカスタム描画アイテムのサンプル コードは docwiki にありません。
Delphi ドキュメンテーション wikiには、サンプルに存在しないコードを参照し、コンパイルしない紛らわしいサンプルがあります。私は、この問題は 3 つの別々の塗装の問題に分かれていると考えています。
- 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;