我把这段写完:
procedure TControl.ReadState(Reader: TReader);
begin
Include(FControlState, csReadingState);
[red]if Reader.Parent is TWinControl then Parent := TWinControl(Reader.Parent);[/red]
[blue]inherited ReadState(Reader);[/blue]
Exclude(FControlState, csReadingState);
if Parent <> nil then
begin
Perform(CM_PARENTCOLORCHANGED, 0, 0);
Perform(CM_PARENTFONTCHANGED, 0, 0);
Perform(CM_PARENTSHOWHINTCHANGED, 0, 0);
Perform(CM_SYSFONTCHANGED, 0, 0);
Perform(CM_PARENTBIDIMODECHANGED, 0, 0);
end;
end;
红色部分完成后,注意,调用了TControl父类的ReadStates,看看父类里面怎么写的:
procedure TComponent.ReadState(Reader: TReader);
begin
Reader.ReadData(Self);
end;
只有一句,再看TReader.ReadData是什么:
procedure TReader.ReadData(Instance: TComponent);
begin
if FFixups = nil then
begin
FFixups := TList.Create;
try
[red]ReadDataInner(Instance);[/red]
DoFixupReferences;
finally
FreeFixups;
end;
end else
ReadDataInner(Instance);
end;
来到红色部分,再看里面:
procedure TReader.ReadDataInner(Instance: TComponent);
var
OldParent, OldOwner: TComponent;
begin
while not EndOfList do ReadProperty(Instance);
ReadListEnd;
OldParent := Parent;
OldOwner := Owner;
Parent := Instance.GetChildParent;
try
Owner := Instance.GetChildOwner;
if not Assigned(Owner) then Owner := Root;
while not EndOfList do [red]ReadComponent(nil);[/red]
ReadListEnd;
finally
Parent := OldParent;
Owner := OldOwner;
end;
end;
注意红色部分,来到:
function TReader.ReadComponent(Component: TComponent): TComponent;
var
CompClass, CompName: string;
Flags: TFilerFlags;
Position: Integer;
OldParent, OldLookupRoot: TComponent;
SubComponents: array of TComponent;
procedure AddSubComponentsToLoaded(Component: TComponent);
var
I: Integer;
begin
for I := 0 to Length(SubComponents) - 1 do
FLoaded.Add(SubComponents
);
end;
procedure CheckSubComponents(Component: TComponent);
var
I: Integer;
begin
for I := 0 to Component.ComponentCount - 1 do
if csSubComponent in Component.Components.FComponentStyle then
begin
SetLength(SubComponents, Length(SubComponents) + 1);
SubComponents[Length(SubComponents) - 1] := Component.Components;
end;
end;
procedure SetSubComponentState(State: TComponentState; Add: Boolean = True);
var
I: Integer;
begin
for I := 0 to Length(SubComponents) - 1 do
if Add then
SubComponents.FComponentState := SubComponents.FComponentState + State
else
SubComponents.FComponentState := SubComponents.FComponentState - State;
end;
function ComponentCreated: Boolean;
begin
Result := not (ffInherited in Flags) and (Component = nil);
end;
function Recover(var Component: TComponent): Boolean;
begin
Result := False;
if not (ExceptObject is Exception) then Exit;
if ComponentCreated then Component.Free;
Component := nil;
SkipComponent(False);
Result := Error(Exception(ExceptObject).Message);
end;
procedure CreateComponent;
var
ComponentClass: TComponentClass;
begin
try
ComponentClass := FindComponentClass(CompClass);
Result := nil;
if Assigned(FOnCreateComponent) then
FOnCreateComponent(Self, ComponentClass, Result);
if Result = nil then
begin
Result := TComponent(ComponentClass.NewInstance);
if ffInline in Flags then
begin
Include(Result.FComponentState, csLoading);
Include(Result.FComponentState, csInline);
end;
try
Result.Create(Owner);
except
Result := nil;
raise;
end;
end;
Include(Result.FComponentState, csLoading);
except
if not Recover(Result) then raise;
end;
end;
procedure SetCompName;
begin
try
[red]Result.SetParentComponent(Parent);[/red]
SetName(Result, CompName);
if (csDesigning in Result.ComponentState) and (FindGlobalComponent(CompName) = Result) then
Include(Result.FComponentState, csInline);
except
if not Recover(Result) then raise;
end;
end;
procedure FindExistingComponent;
begin
try
Result := FindAncestorComponent(CompName, FindComponentClass(CompClass));
Parent := Result.GetParentComponent;
if Parent = nil then Parent := Root;
except
if not Recover(Result) then raise;
end;
end;
var
I: Integer;
begin
ReadPrefix(Flags, Position);
CompClass := ReadStr;
CompName := ReadStr;
OldParent := Parent;
OldLookupRoot := FLookupRoot;
try
Result := Component;
if Result = nil then
if ffInherited in Flags then
FindExistingComponent else
CreateComponent;
if Result <> nil then
try
CheckSubComponents(Result);
Include(Result.FComponentState, csLoading);
SetSubComponentState([csLoading]);
[blue]if not (ffInherited in Flags) then SetCompName;[/blue]
if Result = nil then Exit;
if csInline in Result.ComponentState then
FLookupRoot := Result;
Include(Result.FComponentState, csReading);
SetSubComponentState([csReading]);
Result.ReadState(Self);
Exclude(Result.FComponentState, csReading);
SetSubComponentState([csReading], False);
if ffChildPos in Flags then Parent.SetChildOrder(Result, Position);
if (ffInherited in Flags) or (csInline in Result.ComponentState) then
begin
if FLoaded.IndexOf(Result) < 0 then
begin
AddSubComponentsToLoaded(Result);
FLoaded.Add(Result);
end;
end
else
begin
AddSubComponentsToLoaded(Result);
FLoaded.Add(Result);
end;
except
if ComponentCreated then Result.Free;
raise;
end;
finally
Parent := OldParent;
FLookupRoot := OldLookupRoot;
end;
end;
代码执行到蓝色部分,调用了SetCompName,于是在SetCompName中看到了红色的:
Result.SetParentComponent(Parent);
OK,这里就是整个流程了!就在这里调用了SetParentCOmponent,注意,这就是VCL的持久化机制完成的,一步一步达到的。[]