We help IT Professionals succeed at work.

Before Create and After Create Froms , Application Level

i7mad
i7mad asked
on
Medium Priority
793 Views
Last Modified: 2013-11-23
Hello,

    My Application has more than 100 forms, I want to trap the windows messages that windows send to application before create any form , and after finish creating the form.

  I need this because I have a procedure that shows a "Please Wait" form, and another procedure that destroy this Wait form. So That I want the application to show this wait form before creating any form and destroy it after finish creating that form.

  That is because my Application runs on slow machines. so creating and showing some forms takes like 2-5 seconds, so I want that Wait from to be shown while creating other form. Just to make my Customer be informed that the application is doing something so please wait.
Comment
Watch Question

Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
Hello i7mad,

you need to create an ancestor form for all these forms
with an override constructor and a override DoShow

in the override constructor you call the show wait form
and in the doshow you call the hide wait form

you will have to set the ancestor of all these forms or copy the constructor in all these forms
there is no windows message for creating a form

G

Author

Commented:
Geert_Gruwez

 Thanks for your fast response.

  Yes it is easy to do so, but I have exactly 147 form, It will take some time, and I am lazy doing same code for 147 forms, Thats Why I asked about windows messages.
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
unit Ancestors;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TAncestorForm = class(TForm)
  protected
    procedure DoShow; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

var
  AncestorForm: TAncestorForm;

implementation

{$R *.dfm}

{ TAncestorForm }

constructor TAncestorForm.Create(AOwner: TComponent);
begin
  // Show Wait form
  inherited Create(AOwner);
end;

procedure TAncestorForm.DoShow;
begin
  inherited DoShow;
  // Hide Wait form here
end;

end.
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
you'll also need to change the child form's dfms *object* to *inherited*
manually with notepad or similar editor

Author

Commented:
I dont use MDI forms all 147 are normal forms.
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
i'm talking about vfi, visual form inheritance, not mdi
MerijnBSr. Software Engineer
CERTIFIED EXPERT

Commented:
I think all your forms are created at startup, and you want the waiting form to be displayed only when you show them? Or do you actually create the forms at runtime?

Author

Commented:
MerijnB:

   I Create Only the Main form at startup, the rest 147 Forms will be created at runtime.

Author

Commented:
I create anyform when the user call it from the main menu, and FREE it when the closes it.
MerijnBSr. Software Engineer
CERTIFIED EXPERT

Commented:
In that case, Geert's solution is the best way to do this.

Author

Commented:
And NO Windows Messages regarding Creating forms sent to the Application?
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
no, the form is actually a wrapper around a windows window handle,
catching the window handle will be possible but put a simple tpanel on the form also creates a window ...

the first thing you actually need to do is the following :
categorise your forms
for example:
forms with master detail
forms with only a detail
forms used to filter the master / detail or detail
forms used to pick an item from a dropdown, like a user

then you need to categorise them by speed ...
from very slow, to very fast
the order i gave above will probably be the same

then you will have to work down from slowest to fastest and set the ancestor
you may need to set different ancestors depending on what form you have

in one of my apps, i have roughly the same number of forms
about 20 filter forms, about 70 detail forms, and so in.
each category has a certain type of ancestor.

the ancestor filter form has a function TFilterForm.Filter: string; virtual;
the descendants override this and add their own filtering

the ancestor detail form have a grid export button, next, previous, first, last, ok, cancel, ok + insert next
and validation routines
i never program the buttons in child forms, allready done in the ancestor

the master/detail have 2 grids, 1 master and 1 detail, export buttons, etc ...

if i were to add a show/hide wait form, i would have to change 4 forms (the ancestors)
and the result  would be that i have changed some 140 forms ...

the thing is to group behaviour together into an ancestor form and program it only once.
the child forms just inherit this behaviour

is that something you are interested in ?

obviously for your app to change you would have to change the common ancestor of all forms
but if you would do that considering the categories, you would further benefit from this work in the future.
it's up to you.

Author

Commented:
creating an ancestor form for all forms will not work with me, I have many details and form has much differences. if I am to categorize, I will have more than 50 category. similarity between forms in my application is rare.

Thanks guys anyway.
MerijnBSr. Software Engineer
CERTIFIED EXPERT

Commented:
There is a very evil alternative, which involves making a change in forms.pas, but I don't know if you are willing to go that far.
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
it wouldn't be that evil if you copy forms.pas into your .dpr directory and to the changes there ...

Author

Commented:
MerijnB:

   Yes I am intrested, I have made some changes in standards VCL units and added it to my Application documentation.
Sr. Software Engineer
CERTIFIED EXPERT
Commented:
In Forms.pas there is a method TScreen.AddForm:

procedure TScreen.AddForm(AForm: TCustomForm);

_All_ forms which are created are passing this method, so you could make a hook here, doing your stuff (showing the 'please wait' window).

After the Form.OnShow event, TScreen.UpdateLastActive (also in Forms.pas) is called for _all_ forms, so you can remove your 'please wait' window there.

You'll have to do some checking, like if it's not your own (please wait) form which is calling AddForm, but I think it's quite a good option to achieve what you want...

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
Exactly what I want. Thanks.

Author

Commented:
ohhh, couldn't find forms.pas ?!?!

I am using Delphi 2009 btw.
MerijnBSr. Software Engineer
CERTIFIED EXPERT

Commented:
On my pc it's in C:\Program Files\Borland\BDS\4.0\source\Win32\vcl\
(delphi 2006)

Author

Commented:
the is forms.dcu in C:\Program Files\CodeGear\RAD Studio\6.0\lib
MerijnBSr. Software Engineer
CERTIFIED EXPERT

Commented:
He needs the .pas, not the .dcu
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.