gpt4 book ai didi

delphi - 在 Delphi 中,在 THeadercontrol 上调用 Flip Children 会引发错误

转载 作者:行者123 更新时间:2023-12-03 15:32:47 26 4
gpt4 key购买 nike

我刚刚在 Delphi 中遇到了一个行为,这对我来说似乎是一个错误。

在 Delphi 中,只需将一个 THeaderControl 放在窗体上,并为其分配至少一个部分。如果您在当前表单上调用FlipChildren(true),则会引发“列表索引越界”错误。 TCustomHeaderControl 的 FlipChildren 过程中似乎存在问题。

由于相同的行为在不同版本的 Delphi 中都可以重现(我尝试过 Delphi 6 和 Delphi 2010),所以我有点不愿意将其归类为错误。其他人以前遇到过这个问题吗?

最佳答案

这绝对是一个错误。我预计该代码可以在 Delphi 1 中正常工作,但是 THeaderSections 的实现方式发生了变化,从而破坏了它。看来你是从那时起第一个执行代码的人!

这是代码:

procedure TCustomHeaderControl.FlipChildren(AllLevels: Boolean);
var
Loop, FirstWidth, LastWidth: Integer;
ASectionsList: THeaderSections;
begin
if HandleAllocated and
(Sections.Count > 0) then
begin
{ Get the true width of the last section }
LastWidth := ClientWidth;
FirstWidth := Sections[0].Width;
for Loop := 0 to Sections.Count - 2 do Dec(LastWidth, Sections[Loop].Width);
{ Flip 'em }
ASectionsList := THeaderSections.Create(Self);
try
for Loop := 0 to Sections.Count - 1 do with ASectionsList.Add do
Assign(Self.Sections[Loop]);
for Loop := 0 to Sections.Count - 1 do
Sections[Loop].Assign(ASectionsList[Sections.Count - Loop - 1]);
finally
ASectionsList.Free;
end;
{ Set the width of the last Section }
if Sections.Count > 1 then
begin
Sections[Sections.Count-1].Width := FirstWidth;
Sections[0].Width := LastWidth;
end;
UpdateSections;
end;
end;

这个想法是构建一个标题部分的临时列表,从真实部分分配属性。然后以相反的顺序循环临时列表,分配回标题部分的真实列表。但这不起作用。

整个代码都是假的,因为实际上只涉及一个集合。与控件关联的集合。 THeaderSections 的设计假设 header 控件和 THeaderSections 对象之间存在一对一的关系。很容易观察到,ASectionsList.Add 实际上将项目添加到 SectionsList!

所以,当这段代码完成运行时

for Loop := 0 to Sections.Count - 1 do with ASectionsList.Add do
Assign(Self.Sections[Loop]);

您将观察到 Sections.Count 增加了一倍,而 ASectionsList.Count 仍然为零。那么当我们继续运行时

for Loop := 0 to Sections.Count - 1 do
Sections[Loop].Assign(ASectionsList[Sections.Count - Loop - 1]);

ASectionsList[Sections.Count - Loop - 1] 的访问越界。

该代码非常糟糕。我对此感到震惊。所需要的只是一个包含宽度的简单整数数组。这是使用中介层实现的样子:

type
THeaderControl = class(Vcl.ComCtrls.THeaderControl)
public
procedure FlipChildren(AllLevels: Boolean); override;
end;

procedure THeaderControl.FlipChildren(AllLevels: Boolean);
var
Index, Count: Integer;
Widths: TArray<Integer>;
begin
Count := Sections.Count;
if Count>1 then
begin
SetLength(Widths, Count);
for Index := 0 to Count-2 do
Widths[Index] := Sections[Index].Width;
Widths[Count-1] := ClientWidth;
for Index := 0 to Count-2 do
dec(Widths[Count-1], Widths[Index]);
Sections.BeginUpdate;
try
for Index := 0 to Sections.Count-1 do
Sections[Index].Width := Widths[Count-Index-1];
finally
Sections.EndUpdate;
end;
end;
end;

我建议您提交一份QC报告。

关于delphi - 在 Delphi 中,在 THeadercontrol 上调用 Flip Children 会引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21551440/

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