gpt4 book ai didi

delphi - 在运行时删除和替换可视组件

转载 作者:行者123 更新时间:2023-12-03 14:50:34 24 4
gpt4 key购买 nike

例如,是否可以使用在运行时实例化(有条件)的子类组件来替换和释放 TEdit?如果可以,应该如何以及何时进行?我尝试将父项设置为 nil 并在表单构造函数和 AfterConstruction 方法中调用 free(),但在这两种情况下我都遇到了运行时错误。

<小时/>

更具体地说,我收到了访问冲突错误 (EAccessViolation)。弗朗索瓦(François)说在框架构造时释放组件会扰乱表单控制的内务处理,这似乎是正确的。

最佳答案

这个更通用的例程可以与表单或框架一起使用(更新为使用新控件的子类):

function ReplaceControlEx(AControl: TControl; const AControlClass: TControlClass; const ANewName: string; const IsFreed : Boolean = True): TControl;
begin
if AControl = nil then
begin
Result := nil;
Exit;
end;
Result := AControlClass.Create(AControl.Owner);
CloneProperties(AControl, Result);// copy all properties to new control
// Result.Left := AControl.Left; // or copy some properties manually...
// Result.Top := AControl.Top;
Result.Name := ANewName;
Result.Parent := AControl.Parent; // needed for the InsertControl & RemoveControl magic
if IsFreed then
FreeAndNil(AControl);
end;

function ReplaceControl(AControl: TControl; const ANewName: string; const IsFreed : Boolean = True): TControl;
begin
if AControl = nil then
Result := nil
else
Result := ReplaceControlEx(AControl, TControlClass(AControl.ClassType), ANewName, IsFreed);
end;

使用此例程将属性传递给新控件

procedure CloneProperties(const Source: TControl; const Dest: TControl);
var
ms: TMemoryStream;
OldName: string;
begin
OldName := Source.Name;
Source.Name := ''; // needed to avoid Name collision
try
ms := TMemoryStream.Create;
try
ms.WriteComponent(Source);
ms.Position := 0;
ms.ReadComponent(Dest);
finally
ms.Free;
end;
finally
Source.Name := OldName;
end;
end;

像这样使用它:

procedure TFrame1.AfterConstruction;
var
I: Integer;
NewEdit: TMyEdit;
begin
inherited;
NewEdit := ReplaceControlEx(Edit1, TMyEdit, 'Edit2') as TMyEdit;
if Assigned(NewEdit) then
begin
NewEdit.Text := 'My Brand New Edit';
NewEdit.Author := 'Myself';
end;
for I:=0 to ControlCount-1 do
begin
ShowMessage(Controls[I].Name);
end;
end;

注意:如果您在框架的 AfterConstruction 中执行此操作,请注意托管表单构建尚未完成。
在那里释放控件可能会导致很多问题,因为您会搞乱表单控件的内务处理。
如果您尝试阅读要在 ShowMessage 中显示的新编辑标题,看看您会得到什么...
在这种情况下你会想使用
...ReplaceControl(Edit1, 'Edit2', False)
然后做一个
...FreeAndNil(编辑1)
稍后。

关于delphi - 在运行时删除和替换可视组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/120858/

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