Here is most? of the code.
There are 2 areas to change (TReader & TStream). We have made it virtual so
that by default the normal TReader is used, hence the change to TStream, but
we also have the modified TReader (TReaderLocal) for the different
behaviour. We just had to change TReader to get at virtual methods for the
two different methods required 

var
  StreamReaderClass: TReaderClass = TReader;         //This allows different
kinds of specialised TReaders to be used.

function TStream.ReadComponent(Instance: TComponent): TComponent;
var
  Reader: TReader;
begin
//  Reader := TReader.Create(Self, 4096);
  Reader := StreamReaderClass.Create(Self, 4096);
  try
    Result := Reader.ReadRootComponent(Instance);
  finally
    Reader.Free;
  end;
end;


{ TReaderLocal }

function TReaderLocal.FindInheritedNestedComponent(Root: TComponent; const
NamePath: string): TComponent;
begin
  //
  //The following piece of code is added for the special case of form
loading when cross linking
  //across forms. First attempt to find the component reference in one of
the owners rather
  //than relying on global references - and name changes.
  //This is also matched by a change in TReader.ReadRootComponent //
FindUniqueName
  //
  if Assigned( Root.Owner ) then begin
    Root := Root.Owner;
    repeat
      Result := FindNestedComponent( Root, NamePath);
      if Assigned( Result ) then Exit;
      Root := Root.Owner;
    until not Assigned( Root );
  end;
  Result := nil;
end;

function TReaderLocal.FindUniqueName(const Name: string; Component:
TComponent): string;
var
  I: Integer;
begin
  //
  //The default implementation of this ensures there are unique global names
for root components - eg TForm, TDataModule etc.
  //This implementation does not care, as it assumes there are not really
any global components.
  //Instead the name must just be unique in the component owners name space
instead - so that when we assign to Component.Name, no exception is raised.
  //
  //The code in FindInheritedNestedComponent relies on this, ie names not to
change. Unless they must.
  //
  //This is also matched by a change in TReader.DoFixupReferences
  //
  try
    Component.Name := Name;
    Result         := Name;
  except
    on EComponentError do begin
      //We haved detected a duplicate name, so find a unique name for this
component in it's owners name space
      if Assigned( Component.Owner ) then begin
        I      := 1;
        Result := Format('%s_%d', [Name, I]);
        while Assigned( Component.Owner.FindComponent( Result )) do begin
          Inc(I);
          Result := Format('%s_%d', [Name, I]);
        end;
      end else raise;
    end else raise;
  end;
end;

procedure TReader.DoFixupReferences;
var
  I: Integer;
  CompName: string;
  Reference: Pointer;
begin
  if FFixups <> nil then
    try
      for I := 0 to FFixups.Count - 1 do
        with TPropFixup(FFixups[I]) do
        begin
          CompName := FName;
          ReferenceName(CompName);
          Reference := FindNestedComponent(FInstanceRoot, CompName);

          if not Assigned( Reference ) then Reference :=
FindInheritedNestedComponent( FInstanceRoot, CompName );

         { Free any preexisting global fixups for this instance/property.
            Last fixup added is the only one that counts.
            In particular, fixups created when streaming inherited
forms/frames
            must be destroyed when overriding references are found later
            in the stream.  }
          RemoveGlobalFixup(FFixups[I]);
          if (Reference = nil) and MakeGlobalReference then
          begin
            GlobalFixupList.Add(FFixups[I]);
            FFixups[I] := nil;
          end
          else
            ResolveReference(Reference);
        end;
    finally
      FreeFixups;
    end;
end;

-----Original Message-----
From: Allan, Samuel [mailto:[EMAIL PROTECTED]
Sent: Monday, 8 December 2003 16:03
To: NZ Borland Developers Group - Delphi List
Subject: RE: [DUG] Form / DataModule Creation


Hi Myles,

To me, this sounds like the best solution other than what I've allready
done, because some of the InfoPower components (which we use quite a
lot) link directly to datasets, so even if we were to write our own
TDataSource descendant as Max suggests, we would then have to write our
own descendents for all the InfoPower stuff as well.

However, I know very little myself on how the streaming system works. I
have been reading up, but it would be very helpful if you could tell me
what to change, or send me your altered Classes.pas and I'll work it out
from there. Then I can more quickly gain understanding and put something
concrete to the people who make big decisions like this and let them
decide.

Thanks,
Samuel

-----Original Message-----
From: Myles Penlington [mailto:[EMAIL PROTECTED] 
_______________________________________________
Delphi mailing list
[EMAIL PROTECTED]
http://ns3.123.co.nz/mailman/listinfo/delphi

Reply via email to