gpt4 book ai didi

delphi - 高级自定义DrawItem时如何绘制TreeView样式选择矩形?

转载 作者:行者123 更新时间:2023-12-03 14:46:27 25 4
gpt4 key购买 nike

我正在使用 OnAdvancedCustomDrawItem 事件从头开始自定义 TTreeView 绘图,我想知道如何在我的所有者绘制的背景中正确渲染这些选择和热矩形项目?它们是 Vista/7 风格的,所以我不能简单地用纯色填充背景。

enter image description here

我尝试在cdPostPaint阶段绘制我的项目,但如果我在cdPrePaint阶段留下DefaultDraw := True来绘制选择背景,发生完整的默认绘图,包括项目的文本。

procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages,
DefaultDraw: Boolean);
begin
case Stage of
cdPreErase:
begin
DefaultDraw := True;
end;

cdPostErase:
begin
DefaultDraw := True;
end;

cdPrePaint:
begin
// I thought this will paint only the selected/hot backgrounds,
// however this will paint whole item, including text.
DefaultDraw := True;
end;

cdPostPaint:
begin
DefaultDraw := False;

// painting my owner-draw text
// .........
end;
end;

PaintImages := False;
end;

最佳答案

这是我的解决方案(经过测试)。

请注意,TreeView 必须具有 HotTrack := True 才能正常绘制热门项目。

未启用主题时还必须有额外的绘图。

uses
UxTheme,
Themes;

const
TreeExpanderSpacing = 6;

procedure TForm1.DrawExpander(ACanvas: TCanvas; ATextRect: TRect; AExpanded: Boolean;
AHot: Boolean);
var
ExpanderRect: TRect;
Graphics: IGPGraphics;
Points: array of TGPPoint;
Brush: IGPBrush;
Pen: IGPPen;
ThemeData: HTHEME;
ElementPart: Integer;
ElementState: Integer;
ExpanderSize: TSize;
UnthemedColor: TColor;
begin
if ThemeServices.ThemesEnabled then
begin
if AHot then
ElementPart := TVP_HOTGLYPH
else
ElementPart := TVP_GLYPH;

if AExpanded then
ElementState := GLPS_OPENED
else
ElementState := GLPS_CLOSED;

ThemeData := OpenThemeData(TreeView1.Handle, VSCLASS_TREEVIEW);
GetThemePartSize(ThemeData, ACanvas.Handle, ElementPart, ElementState, nil,
TS_TRUE, ExpanderSize);
ExpanderRect.Left := ATextRect.Left - TreeExpanderSpacing - ExpanderSize.cx;
ExpanderRect.Right := ExpanderRect.Left + ExpanderSize.cx;
ExpanderRect.Top := ATextRect.Top + (ATextRect.Bottom - ATextRect.Top - ExpanderSize.cy) div 2;
ExpanderRect.Bottom := ExpanderRect.Top + ExpanderSize.cy;
DrawThemeBackground(ThemeData, ACanvas.Handle, ElementPart, ElementState, ExpanderRect, nil);
CloseThemeData(ThemeData);
end
else
begin

// Drawing expander without themes enabled

Graphics := TGPGraphics.Create(ACanvas.Handle);
Graphics.SmoothingMode := SmoothingModeHighQuality;

ExpanderRect := ATextRect;
ExpanderRect.Right := ATextRect.Left - TDPIAware.GetScaledSize(TreeExpanderSpacing96dpi);
ExpanderRect.Left := ATextRect.Left - TDPIAware.GetScaledSize(TreeExpanderSpacing96dpi) -
TDPIAware.GetScaledSize(Max(TreeExpanderCollapsedWidth96dpi, TreeExpanderExpandedWidth96dpi));

if ASelected then
UnthemedColor := ColorToRGB(clHighlightText)
else
if AExpanded then
UnthemedColor := clBlack
else
UnthemedColor := clGray;

SetLength(Points, 3);
if AExpanded then
begin
Points[0] := TGPPoint.Create(ExpanderRect.Right, ExpanderRect.Top +
(ExpanderRect.Bottom - ExpanderRect.Top - TreeExpanderExpandedHeight96dpi) div 2);
Points[1] := TGPPoint.Create(ExpanderRect.Right, ExpanderRect.Top +
(ExpanderRect.Bottom - ExpanderRect.Top + TreeExpanderExpandedHeight96dpi) div 2);
Points[2] := TGPPoint.Create(ExpanderRect.Right - TreeExpanderExpandedWidth96dpi,
ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top +
TreeExpanderExpandedHeight96dpi) div 2);
Brush := TGPSolidBrush.Create(TGPColor.CreateFromColorRef(UnthemedColor));
Graphics.FillPolygon(Brush, Points);
end
else
begin
Points[0] := TGPPoint.Create(ExpanderRect.Right - TreeExpanderCollapsedWidth96dpi,
ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top -
TreeExpanderCollapsedHeight96dpi) div 2);
Points[1] := TGPPoint.Create(ExpanderRect.Right,
ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top) div 2);
Points[2] := TGPPoint.Create(ExpanderRect.Right - TreeExpanderCollapsedWidth96dpi,
ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top +
TreeExpanderCollapsedHeight96dpi) div 2);
Pen := TGPPen.Create(TGPColor.CreateFromColorRef(UnthemedColor));
Graphics.DrawPolygon(Pen, Points);
end;
end;
end;

procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages,
DefaultDraw: Boolean);
var
NodeRect: TRect;
NodeTextRect: TRect;
Text: string;
ThemeData: HTHEME;
TreeItemState: Integer;
begin
if Stage = cdPrePaint then
begin
NodeRect := Node.DisplayRect(False);
NodeTextRect := Node.DisplayRect(True);

// Drawing background
if (cdsSelected in State) and Sender.Focused then
TreeItemState := TREIS_SELECTED
else
if (cdsSelected in State) and (cdsHot in State) then
TreeItemState := TREIS_HOTSELECTED
else
if cdsSelected in State then
TreeItemState := TREIS_SELECTEDNOTFOCUS
else
if cdsHot in State then
TreeItemState := TREIS_HOT
else
TreeItemState := TREEITEMStateFiller0;

if TreeItemState <> TREEITEMStateFiller0 then
begin
ThemeData := OpenThemeData(Sender.Handle, VSCLASS_TREEVIEW);
DrawThemeBackground(ThemeData, Sender.Canvas.Handle, TVP_TREEITEM, TreeItemState,
NodeRect, nil);
CloseThemeData(ThemeData);
end;

// Drawing expander
if Node.HasChildren then
DrawExpander(Sender.Canvas, NodeTextRect, Node.Expanded, cdsHot in State);

// Drawing main text
SetBkMode(Sender.Canvas.Handle, TRANSPARENT);
SetTextColor(Sender.Canvas.Handle, clBlue);

Text := Node.Text;
Sender.Canvas.TextRect(NodeTextRect, Text,
[tfVerticalCenter, tfSingleLine, tfEndEllipsis, tfLeft]);

// Some extended drawing...

end;

PaintImages := False;
DefaultDraw := False;
end;

关于delphi - 高级自定义DrawItem时如何绘制TreeView样式选择矩形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10930695/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com