OnAfterShow Event

I need to create an aftershow event for a form when a form becomes visible. I did write a code that works fine when the form is not modal but I still fight to get the solution for modal forms. I want to make a form that will be a parent form for all forms in my project. The only thought that I have is to re-write TCustomForm from VCL...

P.S. I have seen the solution from http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_20690523.html?sfQueryTermInfo=1+onaftershow I think it's hacky and don't like it. So, I need a correct solution even if it will need to re-wrote some VCL classes.

TAdvForm = class(TForm)
    FOnAfterShow: TNotifyEvent;
    procedure DoAfterShow; dynamic;
    procedure Show;
    property OnAfterShow: TNotifyEvent read FOnAfterShow write FOnAfterShow;


{$R *.dfm}

procedure TAdvForm.DoAfterShow;
  if Assigned(FOnAfterShow) then FOnAfterShow(Self);

procedure TAdvForm.Show;
  inherited Show;

Open in new window

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Just override DoShow
That's why it is set to dynamic, so that you can!

// this is from Forms
procedure TCustomForm.DoShow;
  if Assigned(FOnShow) then FOnShow(Self);

// this is yours
procedure TCustomForm.DoShow;
  if Assigned(FOnShow) then FOnShow(Self);
  if Assigned(FOnAfterShow) then FOnAfterShow(Self);
WaitingWonder2Author Commented:
Your code is not working since FOnShow is a private variable in TCustomForm. Even if I make:

procedure TAdvForm.DoShow;
  inherited DoShow;
  if Assigned(FOnAfterShow) then FOnAfterShow(Self);

My OnAfterShow will be called before the forms becomes visible (the same as OnShow event) but I need after.
Good point.
sub OnShow for FOnShow.

Either of


depending on when you need it to happen.  A private property to track first time show also if required.
Activate is probably the first thing that happens after becoming visible.
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

WaitingWonder2Author Commented:
Both this methods were given in the original post. I don't like a work-around solution with Form.Activate, I wrote it at the beginning in my first post.

Form.VisibleChanging is calling when Visible is changing, i.e. before showing a form and before closing a form.

Please, test you solution before providing it. It feels like you are guessing, not knowing the correct solution.

If you want things to happen after the form's onshow is called (that's what "OnAfterShow" implies, then override DoShow).

If you want it to happen just before it becomes visible to the user, override VisibleChanging

If you want it to happen right after it becomes visible, override the Paint method - but this may not be called due to desktop compositing and overlapping windows - depends on your definition of 'visible'.

If you want it to happen right after it is activated (a bit after visible, the form is fully active for interactiveness, but this gets called each time it enters this state) - override Activate.

What exactly are you trying to do that can fall outside of all these?
I know you stated that you don't like it, but is there a particular reason? Just because someone said that it is hacky?
My opinion, but "even if it will need to re-wrote some VCL classes." sounds like more of a hack than overriding a procedure marked dynamic/virtual.
WaitingWonder2Author Commented:
If you have a look at TCustomForm more closely then would understand that DoShow is called before ShowWindow.

Visible is when property Visible is set to true. It is done in method Show. I override it and it works perfectly for non Modal forms, the problem is with modal form.

I have enough experience to understand what is a good solution and what is going around. Many excellent components like DevExpress and Raize are written from scratch, I mean from TComponent etc. Do you know why they do it? Why not just inherite from TLabel to create a new nice looking label but they do all work from scratch. My guess is that VCL lacks something to expand it in convenient way.
WaitingWonder2Author Commented:
Ok. I found solution myself. Just override procedure WndProc.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Yes apologies I inspected it more and it does call showwindow so overriding DoShow would run too early.

Does it work? Because as you have found, a modal form does not need to go through ShowWindow.  Playing with Windows messages directly is the power of Delphi, but even the best can get it wrong.  I use DevExpress (you mentioned them), and see this bug.

It may help you prevent some issues - it involves
+ modal dialog
+ postmessage (3rd party to component developer)
= unexpected outcome
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.