乱翻TComponent
请各位慎重,本人水平很差,下面所述很有可能不正确.
TComponent是所有组件的基类,派生至TPersistent.
方法解析:
constructor TComponent.Create(AOwner: TComponent); begin FComponentStyle := [csInheritable];//可继承 if AOwner <> nil then AOwner.InsertComponent(Self);//其后的工作交由Owner end;
再看InsertComponent,在Create里由Owner调用此方法:
procedure TComponent.InsertComponent(AComponent: TComponent);//在作为owner的组件里加入一个AComponent
begin
AComponent.ValidateContainer(Self);//AComponent验证拥有者.在ValidateContainer里拥有者调用ValidateInsert.ValidateContainer和ValidateInsert都是虚拟方法.具体实现功能由派生类决定
if AComponent.FOwner <> nil then
AComponent.FOwner.RemoveComponent(AComponent);//把AComponent从原来的拥有者里移除
ValidateRename(AComponent, '', AComponent.FName);//检查是否已存在同名的实例
Insert(AComponent);//将AComponent加入到FComponents和FSortedComponents里(自动排序),并设置实例的拥有者
AComponent.SetReference(True);//拥有者的相应对象指针指向AComponent
if csDesigning in ComponentState then
AComponent.SetDesigning(True);//AComponent及其拥有的对象添加csDesigning状态
Notification(AComponent, opInsert);//owner广播通知其所拥有的对象(FComponents里的对象),AComponent加入大家庭了
end;//注:FSortedComponents里面的实例已根据名称排序.FSortedComponents服务于FindSortedComponent,而FindSortedComponent由FindComponent调用,FindComponent用于查找所拥有某个实例.
InsertComponent用到的几个方法:
1.
procedure TComponent.ValidateContainer(AComponent: TComponent); begin AComponent.ValidateInsert(Self); end;
2
procedure TComponent.ValidateInsert(AComponent: TComponent); begin end;
3.
procedure TComponent.RemoveComponent(AComponent: TComponent);//在作为owner的组件里移除一个AComponent begin ValidateRename(AComponent, AComponent.FName, ''); Notification(AComponent, opRemove);//通知其所拥有的对象,AComponent将移除. AComponent.SetReference(False);//将拥有者的相应对象指针置为nill Remove(AComponent);//将AComponent的owner置为nill,并将AComponent从FComponents和FSortedComponents里移除, 加下面的Remove方法. end; 4.
procedure TComponent.Notification(AComponent: TComponent;
Operation: TOperation);//暂时就叫它广播方法,负责向FComponents里的对象发送通知(注意递归)
var
I: Integer;
begin
if (Operation = opRemove) and (AComponent <> nil) then
RemoveFreeNotification(AComponent);//如果是删除通知,则将AComponent从owner的FFreeNotifies里移除,将owner从AComponent的FFreeNotifies里移除,见RemoveFreeNotification和RemoveNotification(注意递归)
if FComponents <> nil then
begin
I := FComponents.Count - 1;
while I >= 0 do
begin
TComponent(FComponents[I]).Notification(AComponent, Operation);
Dec(I);
if I >= FComponents.Count then
I := FComponents.Count - 1;
end;
end;
end;procedure TComponent.RemoveFreeNotification(AComponent: TComponent); begin RemoveNotification(AComponent); AComponent.RemoveNotification(Self); end;
procedure TComponent.RemoveNotification(AComponent: TComponent);
var
Count: Integer;
begin
if FFreeNotifies <> nil then
begin
Count := FFreeNotifies.Count;
if Count > 0 then
begin
{ On destruction usually the last item is deleted first }
if FFreeNotifies[Count - 1] = AComponent then
FFreeNotifies.Delete(Count - 1)
else
FFreeNotifies.Remove(AComponent);
end;
if FFreeNotifies.Count = 0 then
begin
FFreeNotifies.Free;
FFreeNotifies := nil;
end;
end;
end;procedure TComponent.Remove(AComponent: TComponent);
var
Count: Integer;
begin
AComponent.FOwner := nil;
Count := FComponents.Count;
if Count > 0 then
begin
{ On destruction usually the last item is deleted first }
if FComponents[Count - 1] = AComponent then
FComponents.Delete(Count - 1)
else
FComponents.Remove(AComponent);
if FSortedComponents <> nil then
FSortedComponents.Remove(AComponent);
end;
if FComponents.Count = 0 then
begin
FSortedComponents.Free;
FSortedComponents := nil;
FComponents.Free;
FComponents := nil;
end;
end;
浙公网安备 33010602011771号