请各位慎重,本人水平很差,下面所述很有可能不正确.
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;