6

We have an application that stores project information in a file by descending from TPersistent. We use TSteam.ReadComponentRes to read from a stream to the object.

We would like to be able to open project files with unknown properties (from newer versions or other development branches of our application). Currently this results in an exception in TReader, which is created by TStream. We've considered making a TStream descendant that uses a TReader descendant that handles this exception instead of stopping reading. Can anybody think of a more elegant way of doing this?

menjaraz
  • 7,551
  • 4
  • 41
  • 81
boileau
  • 817
  • 6
  • 20
  • Yes - I would like to know how to do this too. The TReader excepts and I don't know how to 'resume' it. This has caused problems in my 'TpersistentForm' class that streams out all the published properties to a file on destroy and streams them back in again on create. As you say, there are big problems during development where I am adding/deleting controls from the forms :( I have added in serial bodges over the years to get round most of the problems, but I have never been totally happy. – Martin James Jun 07 '11 at 13:51

1 Answers1

9

Call Stream.ReadResHeader, create a TReader instance, set its OnError event and call Reader.ReadRootComponent and free the reader (i.e. mimic the behaviour of TStream.ReadComponentRes).

Inside the OnError event handler you can set handled := true.

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
  • 1
    Agreed, use `OnError` event. Here's an [example](http://stackoverflow.com/questions/271843/doublebuffered-property-beeing-added-in-the-dfm-in-delphi-2009-does-not-exist-in/275156#275156) for `DoubleBuffered` and `ParentDoubleBuffered` properties both at runtime and designtime. – Ondrej Kelle Jun 07 '11 at 13:55
  • This sounds great. I'm having trouble with `Reader.OnError:=OnReaderError;`. I get a E2009 Incompatible types: 'method pointer and regular procedure' error, though. Got any tips? – boileau Jun 07 '11 at 14:31
  • From the error message it appears that you have defined your OnReaderError procedure at the global level (outside a class). Define it within a class and assign the event to the method of an instance of the class – HeartWare Jun 07 '11 at 14:38
  • It's going to have to be a procedure of object, just like an event handler. I can use a method of my 'TpersistentForm' class, but not sure about a more general Tpersistent. – Martin James Jun 07 '11 at 14:39
  • 1
    Got it: procedure TpersistentContext.DFMreaderError(Reader: TReader; const Message: string; var Handled: Boolean); begin handled:=true; end; – Martin James Jun 07 '11 at 14:43