Delphi TVirtualStringTree中未正确绘制主题复选框
启用ToThemeWare时,VirtualTrees.pas 5.0.0版中的复选框处理出现中断。csUncheckedNormal的节点绘制为checked+hot 要使用抽屉元素正确绘制未选中的主题复选框,详细信息记录必须为:Element=teButton,Part=3,State=5。但是,当节点设置为csUncheckedNormal时,VirtualTrees.pas最终调用状态为1的抽屉元素 在VirtualTrees中似乎有大量的间接寻址和额外常量,所以我不确定如何最好地解决这个问题。欢迎提出意见Delphi TVirtualStringTree中未正确绘制主题复选框,delphi,delphi-xe2,virtualtreeview,vcl-styles,tvirtualstringtree,Delphi,Delphi Xe2,Virtualtreeview,Vcl Styles,Tvirtualstringtree,启用ToThemeWare时,VirtualTrees.pas 5.0.0版中的复选框处理出现中断。csUncheckedNormal的节点绘制为checked+hot 要使用抽屉元素正确绘制未选中的主题复选框,详细信息记录必须为:Element=teButton,Part=3,State=5。但是,当节点设置为csUncheckedNormal时,VirtualTrees.pas最终调用状态为1的抽屉元素 在VirtualTrees中似乎有大量的间接寻址和额外常量,所以我不确定如何最好地解决这
(即使是在屏幕上显示TVirtualStringTree并填充一些数据的最小代码,在这里发布也有点长。除了基本的代码外,复制它所需要的只是在TreeOptions.MisOptions中启用CheckSupport,并在InitNode回调中设置Node.CheckType:=ctTriStateCheckBox。),由于我认为在移植到delphi XE2时,VirtualTreeView不适用于VCL样式,因此这可能会解决您的问题。您必须在绘制元素之前获取元素详细信息,否则会得到类似的结果(这是对VirtualTreeView绘制复选框状态的模拟)。注意不同的顺序和工件;这是一次禁用VCL样式,第二次启用相同代码的结果: 我知道很奇怪,但我不能回答你为什么会发生这种事。我可以告诉您,您应该调用或选择自己计算状态索引,以使元素渲染正常工作。您可以尝试使用以下修复程序:
procedure TBaseVirtualTree.PaintCheckImage(Canvas: TCanvas;
const ImageInfo: TVTImageInfo; Selected: Boolean);
var
// add a new variable for calculating TThemedButton state from the input
// ImageInfo.Index; I hope ImageInfo.Index has the proper state order
State: Integer;
begin
...
case Index of
0..8: // radio buttons
begin
// get the low index of the first radio button state and increment it by
// the ImageInfo.Index and get details of the button element
State := Ord(TThemedButton(tbRadioButtonUncheckedNormal)) + Index - 1;
Details := StyleServices.GetElementDetails(TThemedButton(State));
end;
9..20: // check boxes
begin
// get the low index of the first check box state and increment it by
// the ImageInfo.Index and get details of the button element
State := Ord(TThemedButton(tbCheckBoxUncheckedNormal)) + Index - 9;
Details := StyleServices.GetElementDetails(TThemedButton(State));
end;
21..24: // buttons
begin
// get the low index of the first push button state and increment it by
// the ImageInfo.Index and get details of the button element
State := Ord(TThemedButton(tbPushButtonNormal)) + Index - 21;
Details := StyleServices.GetElementDetails(TThemedButton(State));
end;
else
Details.Part := 0;
Details.State := 0;
end;
...
end;
我已经对所有的检查类型进行了测试,它对我很有效。我现在做了以下几项;将VirtualStringTree v.5.0.0放在表单上,将ToThemeWare保留在PaintOptions中,将toCheckSupport包含在MiscOptions中,将以下代码行添加到某个事件处理程序
VirtualStringTree1.AddChild(nil)中。检查类型:=ctTriStateCheckBox
,在Windows 7上从my Delphi 2009运行应用程序,并仔细查看复选框;他们没有处于高温状态。所以我回到这里写了这篇评论,问你是否启用了VCL样式(在查看代码之前),向上投票,然后按ENTER键:-)是的,对不起,这是在Delphi XE2下启用样式的应用程序中。@TLama:如果你看到它正确地绘制,我真的会对你在代码中的几个点看到的东西感兴趣。即TBaseVirtualTree.PaintCheckImage中ImageInfo.Index的值。我有9个,这符合第二种情况,所以声明:=9-8,这是错误的。9的索引来自TBaseVirtualTree.GetCheckImage和VirtualTrees.pas的第122行上的常量ckcheckuncheckdnormal,该常量为9。如果你能正确地看到它,那么它一定会有所不同。谢谢不同的是,在我做测试时,我只有Delphi2009可用,它们没有VCL样式。两个版本的一个共同点是,“三态”复选框不是“三态”(但这可能是一些设置)。现在我检查了Delphi XE2上是否启用了VCL样式(除了tri-state之外),并没有启用VCL样式。如果使用VCL样式,则节点.CheckState
是csUncheckedNormal
,但它也会呈现选中的热状态,这肯定是错的。我会看一看,但这需要一些时间,我现在必须做一些事情。是的,这确实解决了问题。不过我想知道,这是否与treeview作者所采用的方法相同。具体地说,我认为GetCheckImage()中的整个CheckStateTochekimage数组都是有原因的,尽管我不知道它是什么,而且在我看来,它似乎是在已经存在的常量之上添加的另一个级别的常量。不管怎样,这确实有效,谢谢!