tags:

views:

108

answers:

4

I have some code that does some setup of internal objects in the Loaded() function. However, some external objects are not completely created yet, but are AFTER the Loaded() function is complete. What function does Delphi call after it calls Loaded()?

Better yet what is the creation sequence of a component?

Basically I have a TCP Server and Client. Most people will place those two components into two separate applications, some will place them in the same application for local access.

My Client tries to fetch data from the server in OnLoaded(), but the server may not be up yet! I want to know if another function is called after all the OnLoaded()'s are called.

+1  A: 

Normally you would override TObject.AfterConstruction for that purpose.

The order of execution is:

  each Component.AfterConstruction in creation order
(Form or DataModule).Loaded  
  each Component.Loaded in creation order
(Form or DataModule).AfterConstruction 

Trace:

Debug Output: button AfterConstruction Process Project2.exe (4876)
Debug Output: Form Loaded Process Project2.exe (4876)
Debug Output: button Loaded Process Project2.exe (4876)
Debug Output: Form AfterConstruction Process Project2.exe (4876)
François
AfterConstruction is called before OnLoaded, so my needed components are not ready there either. I need something called after Loaded is called on all components in the main form. There does not appear to be anything.
gbrandt
I don't know of any standard `onLoaded` event. And I'm sorry but `Self.Loaded` happens before `Self.AfterConstruction`.
François
You may have some code that create components on the fly (i.e. not part of the dfm) and in that case their Loaded/AfterConstruction can happen after that sequence for the Owner Form. But if they are ready in the Loaded routine of the Form, they are even more so in the AfterConstruction.
François
I put breakpoints on both OnLoaded and on AfterConstruction. The AfterConstruction breakpoint is hit first. Everytime.
gbrandt
Please change the title and rephrase your question. It is not about the order of execution for Loaded and AfterConstruction of a TComponent for which my answer and comments are right. Try to put a breakpoint in the Loaded and AfterConstruction method for a Form... And I'm curious to see the code where you put a BreakPoint in "OnLoaded" as there is no such thing in the Delphi source code.
François
The question clearly asks what is called, if anything, after the Loaded(). My comment above incorrectly calls Loaded() OnLoaded().
gbrandt
+1  A: 

I'm not sure what you mean with

the server may not be up yet

Anyway, if the client and the server are both on the same application form or datamodule, I see alternatives:

  1. You may "force" the system to create the server before the client and up the server in the server's OnLoad and it will be up at the client OnLoad, because documentation says:

    When the streaming system loads a form or data module from its form file, it first constructs the form component by calling its constructor, then reads its property values from the form file. After reading all the property values for all the components, the streaming system calls the Loaded methods of each component in the order the components were created. This gives the components a chance to initialize any data that depends on the values of other components or other parts of itself.

  2. Inform the "client" whenever the server is UP to let it initialize (pull data from the server). You can use a direct method call, post a message or whatever you feel comfortable with.

  3. Let the client stand up the server inside it's own OnLoad method.

jachguate
And as I stated in my answer, after the Loaded phase is done, the AfterConstruction of the Form or DataModule happens. That where the client should try to connect to the server if the server is already listening (which may be different than Loaded)
François
@François: After you edited your answer, is clear you're talking about form/datamodule AfterConstruction. Before it was not clear to me.
jachguate
+1  A: 

Why not use the onCreate event of the main Form ?

iamjoosy
This puts the onus on the user of the component know the inner workings of that component for set up. Not what I want
gbrandt
+1  A: 

Loaded is called immediately after the dfm is streamed in, and shouldn't be used to access the server. Your best bet is probably to post a custom message to yourself in the constructor, and have a message handler procedure that responds to that message. Posting the message puts it into the end of the message queue, and therefore it won't get processed until all the other messages ahead of it has been handled. This should delay things long enough for your components to be fully constructed for use.

Ken White
Bam, thats the issue, the server is created in the mainform, the client is internal to one of the components. I can't ensure that the server is created first. Lacking a function that is called after Loaded(), sending myself a message is the next best thing. Thanks.
gbrandt