Hi, I appear to be back... :)
I now understand rather more of the RegisterClass issue than I did when I
wrote the message on this thread (below). I don't now think there is a way
around this issue other than to make calls to RegisterClass as Myles
suggested, but I'll paint the full picture anyway.
>From an editor in the IDE, we have an option to stream the current in-editor
form to a database blob. The client program runs off the database over a
WAN, and will occasionally load and display forms at runtime. This enables
us to quickly make a change to a form; in addition, the client can make
changes to certain aspects of the form using a simple editor we provide as
part of the application, and save those customised changes.
We know we won't have any classes on that form that aren't also used in part
of the client application. This isn't forced on us, it's just something we
know will be true. Writing out the form is simple. The problem comes when
we want to read it in again, and don't know what classes might be on the
form, out of the full set of classes that the client application has.
Obviously we have to somehow make sure the classes we're going to use when
we load the form on the client exist and can be obtained before we load;
Delphi's method of handling this is RegisterClass and the "Class not
registered" message.
But we don't know, for example, whether a TPanel will be on our form or not.
It might be! If we call RegisterClass(TPanel), this effectively targets the
class for the compiler to keep track of so it can find it when we get around
to loading the form with the TPanel on it. So we need to call
RegisterClass(TPanel) in our client application somewhere before loading the
form, only because it *might* be the case. The same holds true however for
every single class that we might possibly use, even though some of them are
exceedingly unlikely to be present.
The annoying thing is that we *know* that the client application uses a
TPanel in it somewhere - we know this because otherwise we wouldn't have
allowed the saving of a form with a TPanel on it in the first place. So the
TPanel definition exists in the compiled code on the client. We also know
that we're going to need a TPanel on loading a particular form with a TPanel
on it, and we're free to store additional information in the blob to reflect
this. In fact we will know all the classes that the form uses, and thus
could store a list of these class names in the blob to be accessed before
retrieval (not the classes themselves - I'm not _quite_ insane enough to
look for ways to add class definitions on the fly :).
But how can we say "go and get me class X (whose definition we are certain
is compiled somewhere in the exe, just to add insult to injury) and then
register it"? Therein lies the crux of the problem. It doesn't matter what
information we choose to save about the class, it appears that it just can't
be done. FindClass (and GetClass) require the class you're looking for to
be registered already. And RegisterClass, of course, requires you to be
explicit about the class you're going to register. Knackered!!
I thought before I understood all this that I could just save the class
pointer and use that to locate the class to register on load (and initially
it seemed to work brilliantly), but of course all sorts of things can cause
the class definitions to move to a different area of the compiled code (eg.
simply moving the class definition into a different unit) and that's access
violation city.
So in the end our client is likely to have to RegisterClasses([TPanel,
TThis, TThat, TTom, TDick, THarry, TKitchenSink, ..., etc. etc.]);
Did I miss anything?
:(
Cheers,
Carl
-----Original Message-----
From: Myles Penlington [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, 23 May 2000 1:02 PM
To: Multiple recipients of list delphi
Subject: RE: [DUG]: Registering classes
Bascially a class reference to your object must be in you compiled base
code. Ie you need to put a RegisterClass in the compiled code for every
class that could be in the DFM file.
Normally in this case we would have something like this.
initialization
RegisterClass( TABC );
end.
> -----Original Message-----
> From: Carl Reynolds [SMTP:[EMAIL PROTECTED]]
> Sent: Tuesday, May 23, 2000 2:25 PM
> To: Multiple recipients of list delphi
> Subject: [DUG]: Registering classes
>
> I'm streaming out some forms and reading them back in at a later date. My
> problem is that before reading them in, RegisterClass needs to be called
> for
> all of the classes of the components I'm reading (assuming these classes
> aren't already registered). So,
>
> 1/. Is there any reason why I can't just write out some class definitions
> before writing my forms, and before reading them in again, read and
> register
> the classes, eg.
> // Write out
> var MyClass: TPersistentClass;
> MyClass := TButton;
> MyStream.Write(MyClass, SizeOf(TPersistentClass));
> // Read in
> MyStream.Read(MyClass, SizeOf(TPersistentClass));
> RegisterClass(MyClass);
> ?
>
> 2/. Is there an easier way than the following to get the class of an
> object
> (and is this method ok)?
> type
> TClassDef = class(TPersistent)
> class function GetClass: TPersistentClass;
> end;
> function TClassDef.GetClass: TPersistentClass;
> begin
> Result := Self;
> end;
> (eg, MyClass := TClassDef(Button1).GetClass;)
>
> I don't know much about the internal structure of a
> TClass/TPersistentClass,
> so I don't know if these sorts of things are "safe". I imagine that I'm
> making the assumption that the class definitions aren't different in the
> program that's reading them in, but I don't know whether that's a
> dangerous
> assumption to make. Is there a better way to do this?
>
> (Incidently, has mail been bouncing from my address? Apologies if so, on
> behalf of the installers of the new firewall here, which it seems was a
> little too efficient - I've had no mail all morning anyway)
>
> Cheers,
> Carl
>
> --------------------------------------------------------------------------
> -
> New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
> Website: http://www.delphi.org.nz
---------------------------------------------------------------------------
New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
Website: http://www.delphi.org.nz
---------------------------------------------------------------------------
New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
Website: http://www.delphi.org.nz