8

我正在尝试为我的应用程序模拟 Outlook 2013 左窗格树视图菜单。我使用 CustomDraw 是因为我只想更改一些简单的字体和背景属性。

这就是我想要的:

Outlook 2013 侧边栏菜单

但是,我总是为选定节点和热跟踪节点获得默认选定图形。我没有 Windows 7 或 XP 来查看这是正常行为还是与我的操作系统(Windows 8)有关。

这是我得到的:

对 Outlook 2013 样式侧边栏菜单的不良模仿

这是我的代码:

procedure TMainForm.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if Node.Level = 1 then
    Sender.Canvas.Font.Size := Sender.Canvas.Font.Size + 2;

  if cdsHot in State then
    Sender.Canvas.Brush.Color := $00F7E6CD
  else if (cdsSelected in State) or (cdsFocused in State) or
    (cdsChecked in State) then
    Sender.Canvas.Brush.Color := $00F2F2F2
  else
    Sender.Canvas.Brush.Color := $00DEDEDE;
  DefaultDraw := true;
end;

如何为选定和热门项目绘制不同颜色的背景?

4

1 回答 1

12

尝试以下操作:

在此处输入图像描述

type
  TTreeView = class(Vcl.ComCtrls.TTreeView)
  protected
    procedure CreateWnd; override;
  end;


uses uxtheme;

procedure TTreeView.CreateWnd;
begin
  inherited;
  SetWindowTheme(Handle, nil , nil);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

   TreeView1.Font.Name := 'Segoe UI';
   TreeView1.HotTrack := True;
   TreeView1.Font.Size := TreeView1.Font.Size + 1;
   TreeView1.Color := $00DEDEDE;

end;

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin

   if cdsFocused in State then begin
     Sender.Canvas.Brush.Color := $00F2F2F2;
     Sender.Canvas.Font.Color := clblack;
     Sender.Canvas.Font.Style := Sender.Canvas.Font.Style + [fsBold];
   end else if cdsHot in State then
    Sender.Canvas.Brush.Color := $00F7E6CD
   else
    Sender.Canvas.Brush.Color := $00DEDEDE;

end;

解释:

微软在这方面的文档非常模糊,我可以肯定地说,每当对项目(节点)执行操作(选择、热跟踪、取消选择等)时,都会发送特定消息,这消息通过参数标志包含节点的状态,最后在内部决定如何根据当前的 Windows 主题直观地更新项目。

这就是为什么禁用 TreeView 组件的主题会删除默认选择矩形和主题颜色的可能原因。控制状态标志的文档部分支持这一理论。

于 2013-07-08T20:51:01.960 回答