乱翻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;
原文地址:https://www.cnblogs.com/cxp2009/p/2280952.html