我正在重构一个旧的应用程序,使其响应更快,我有一个使用devExpress组件的表单,并使用CallbackCustomDrawPreviewCell创建一个自定义网格,问题是这个函数非常慢,需要大约0.09s每次通话,但每次打开表格时调用约30至60次,因此表格可以打开2.8秒到5.6秒。 我通常使用C#和Object-C / Swift进行编程,我们可以在后台发送一个块进行处理,但就我的研究而言,我们在Delphi中没有类似的东西,似乎通常在Delphi中有一个新线程必须是一个全新的独立代码。我的假设是否正确?
如果是这样,在这种情况下提高速度的最佳解决方案是什么? (我正在使用Delphi XE)
(如果它有帮助:我也刚刚买了AQTime试图帮我弄清楚如何改进这个但是到目前为止我没有运气,还需要多深入挖掘手册。但它确实对我有所帮助在这个特定的回调中找到速度问题)
提前致谢。
功能是:
procedure TtvdAvaOutageManagementForm.CallbackCustomDrawPreviewCell(Sender: TcxCustomTreeList; ACanvas: TcxCanvas;
AViewInfo: TcxTreeListEditCellViewInfo; var ADone: Boolean);
const
AlignFlag = DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX or DT_END_ELLIPSIS;
cnFontColor = clBlue;
var
AFaultId: variant;
aFault: TtvdFault;
aLocalities, aFaultLocalities: TStringList;
i: integer;
aLocality: string;
Rect: TRect;
size: TSize;
AText: string;
begin
{ colour the preview text blue }
ACanvas.Font.Color := cnFontColor;
AText := AViewInfo.DisplayValue;
aLocalities := TStringList.Create;
aFaultLocalities := TStringList.Create;
try
AFaultId := AViewInfo.Node.Values[FtvdTree.GetColumnByFieldName('FaultId').ItemIndex];
if (not VarIsNull(AFaultId)) then
begin
ACanvas.Brush.Color := COLOR_FAULT;
aFault := FtvdFaults.tvdGetFault(AFaultId);
if Assigned(aFault) then
begin
ACanvas.Brush.Color := aFault.tvdFaultColor;
ACanvas.Brush.Color := aFault.tvdFaultColor;
ACanvas.FillRect(AViewInfo.BoundsRect);
CopyRect(Rect, AViewInfo.BoundsRect);
InflateRect(Rect, -1, -1);
Inc(Rect.Left, FtvdTree.OptionsView.IndicatorWidth);
ACanvas.Font.Color := cnFontColor;
{ if all the localities are in the fault then bold the preview text,
else need to do it manually (i.e. only bold the localities that are
in the fault }
if aFault.tvdAllLocalities then
begin
ACanvas.Font.Style := [fsBold];
ACanvas.DrawTexT(AText, AViewInfo.BoundsRect, AlignFlag);
end
else
begin
CopyRect(Rect, AViewInfo.BoundsRect);
aLocalities.Text := StringReplace(AText, ', ', #13#10, [rfReplaceAll]);
aFaultLocalities.Text := StringReplace(aFault.tvdLocalities, ', ', #13#10, [rfReplaceAll]);
for i := 0 to aLocalities.Count - 1 do
begin
ACanvas.Font.Style := [];
{ draw a comma if this is not the first locality }
if i > 0 then
begin
size := ACanvas.TextExtent(',');
DrawText(ACanvas.Handle, ',', 1, Rect, DT_LEFT or DT_NOPREFIX);
Inc(Rect.Left, size.cx);
end;
aLocality := aLocalities[i];
if aFaultLocalities.IndexOf(aLocality) >= 0 then
begin
ACanvas.Font.Style := [fsBold];
end;
size := ACanvas.TextExtent(aLocality);
if (Rect.Left + size.cx) > Rect.Right then
begin
Rect.Left := AViewInfo.BoundsRect.Left;
Inc(Rect.Top, size.cy);
end;
{ draw the text item }
DrawText(ACanvas.Handle, pchar(aLocality), Length(aLocality), Rect, DT_LEFT or DT_NOPREFIX);
Inc(Rect.Left, size.cx);
end;
end;
ADone := true;
end;
end;
finally
aLocalities.Free;
aFaultLocalities.Free;
end;
end;
答案 0 :(得分:1)
如果你总结我的评论那么它应该或多或少。
试着告诉我们它是如何为您解决的。由于我没有一个有效的例子,它可能不是100%正确。
procedure TtvdAvaOutageManagementForm.CallbackCustomDrawPreviewCell(Sender: TcxCustomTreeList; ACanvas: TcxCanvas;
AViewInfo: TcxTreeListEditCellViewInfo; var ADone: Boolean);
const
AlignFlag = DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX or DT_END_ELLIPSIS;
cnFontColor = clBlue;
var
AFaultId: variant;
aFault: TtvdFault;
aLocalities, aFaultLocalities: TStringList;
i: integer;
aLocality: string;
Rect: TRect;
size: TSize;
AText: string;
begin
{ colour the preview text blue }
ACanvas.Font.Color := cnFontColor;
AText := AViewInfo.DisplayValue;
aLocalities := TStringList.Create;
aFaultLocalities := TStringList.Create;
try
AFaultId := AViewInfo.Node.Values[FaultIdColumn.ItemIndex];
if not VarIsNull(AFaultId) then
begin
ACanvas.Brush.Color := COLOR_FAULT;
aFault := FtvdFaults.tvdGetFault(AFaultId);
if Assigned(aFault) then
begin
ACanvas.Brush.Color := aFault.tvdFaultColor;
ACanvas.Brush.Color := aFault.tvdFaultColor;
ACanvas.FillRect(AViewInfo.BoundsRect);
CopyRect(Rect, AViewInfo.BoundsRect);
InflateRect(Rect, -1, -1);
Inc(Rect.Left, FtvdTree.OptionsView.IndicatorWidth);
ACanvas.Font.Color := cnFontColor;
{ if all the localities are in the fault then bold the preview text,
else need to do it manually (i.e. only bold the localities that are
in the fault }
if aFault.tvdAllLocalities then
begin
ACanvas.Font.Style := [fsBold];
ACanvas.DrawTexT(AText, AViewInfo.BoundsRect, AlignFlag);
end
else
begin
CopyRect(Rect, AViewInfo.BoundsRect);
aLocalities.CommaText:= AText;
aFaultLocalities.CommaText := aFault.tvdLocalities;
aFaultLocalities.Sorted := True;
for i := 0 to aLocalities.Count - 1 do
begin
ACanvas.Font.Style := [];
{ draw a comma if this is not the first locality }
if i > 0 then
begin
size := ACanvas.TextExtent(',');
DrawText(ACanvas.Handle, ', ', 1, Rect, DT_LEFT or DT_NOPREFIX);
Inc(Rect.Left, size.cx);
end;
aLocality := aLocalities[i];
if aFaultLocalities.IndexOf(aLocality) >= 0 then
begin
ACanvas.Font.Style := [fsBold];
end;
size := ACanvas.TextExtent(aLocality);
if (Rect.Left + size.cx) > Rect.Right then
begin
Rect.Left := AViewInfo.BoundsRect.Left;
Inc(Rect.Top, size.cy);
end;
{ draw the text item }
DrawText(ACanvas.Handle, pchar(aLocality), Length(aLocality), Rect, DT_LEFT or DT_NOPREFIX);
Inc(Rect.Left, size.cx);
end;
end;
ADone := true;
end;
end;
finally
aLocalities.Free;
aFaultLocalities.Free;
end;
end;