From: Bidski on
Hello all.

I am using VC++6 and MFC.

What I am trying to do seems fairly simple and straightforward (at
least, it does to me tongue.gif). Basically what I am wanting to do is
trap an event that occurs when a dialog box is shown to the screen,
but I only want it to happen once (being the first time that the form
is displayed to screen after its initial loading).

I have tried a handful of things and none of them work.

I have tried a couple of hooks that I thought might have triggered at
the right point (WH_FOREGROUNDIDLE, CBT_PROC - WH_ACTIVATE and
CBT_PROC - WH_CREATEWND), but all of these trigger BEFORE the dialog
is visible on the screen.

I used SetWindowsHookEx to set the hook and the appropriate CALLBACK
functions for the above mentioned hooks.

I also tried handling the WM_SHOWWINDOW message, but once again this
triggers before the dialog is visible.


A little about my code and why I am trying to do this .........

At present, this is the general flow of the prgram:

1) User clicks button on main form.

2) Open a database and a recordset, extracting some information from
the recordset which is being stored in 3 different arrays (2
CStringArrays and 1 CUIntArray).

3) Open a text file, extract some information and then use that
information to populate a CTreeView control with various nodes.

4) Populate a CListbox control with the information from 1 of the
CStringArrays and setting the ItemData with the information from the
CUIntArray

4) Select the top-most item in the CListbox control and populate about
35 on-screen controls and about 5 hidden controls (textboxes, labels
and combo/listboxes) with information from the database using a couple
of different recordsets.

5) Form is diplayed (not the main form, but a new one).

At the moment it is all happening pretty quickly with the longest part
being the populating of the CListbox control which is taking about 1-2
seconds to populate it with about 1800 items. This part used to take
close to 10 secs to complete, but with a slight change to the code I
managed to reduce it to its current 1-2 secs. My concern is that if
the amount of data to be populated into the CListbox control grows
(which is very possible, I could see possible situations requiring
10,000+ items) that the loading of the form will once again increase
to a pathetically long time.

With a long delay, the user will click the button on the main form and
the program will appear to do nothing. I have a progress bar on the
form I am displaying, but its not much good if the form isnt visible,
but if I can get the form to show and then do my loading the user will
at least have some sort of visual recognition that the program is
doing something.

And therein lies my problem, is there any event that gets fired AFTER
the form is displayed to the screen that will allow me to do all the
loading that I need to do?

I hope that makes some sense to everyone. If you need further
clarification just ask.

And for anyone that is wondering, this is not homework.

Thanks in advance
Bidski
From: Christian ASTOR on
On 22 oct, 08:37, Bidski <bids...(a)gmail.com> wrote:

> What I am trying to do seems fairly simple and straightforward (at
> least, it does to me tongue.gif). Basically what I am wanting to do is
> trap an event that occurs when a dialog box is shown to the screen,
> but I only want it to happen once (being the first time that the form
> is displayed to screen after its initial loading).

Maybe you can try Windows Events (SetWinEventHook() +
EVENT_OBJECT_SHOW or other) (with a flag for example to get it only
once...)
(not sure if it will not be fired too early for your case)
From: Bidski on
On Oct 22, 6:04 pm, Christian ASTOR <casto...(a)club-internet.fr> wrote:
> On 22 oct, 08:37, Bidski <bids...(a)gmail.com> wrote:
>
> > What I am trying to do seems fairly simple and straightforward (at
> > least, it does to me tongue.gif). Basically what I am wanting to do is
> > trap an event that occurs when a dialog box is shown to the screen,
> > but I only want it to happen once (being the first time that the form
> > is displayed to screen after its initial loading).
>
> Maybe you can try Windows Events (SetWinEventHook() +
> EVENT_OBJECT_SHOW or other) (with a flag for example to get it only
> once...)
> (not sure if it will not be fired too early for your case)

Thanks for the reply. It once again appears as though the even is
triggering slightly before the dialog is displayed. The dialog is
being displayed with all loading complete, all text boxes/combo boxes
are all populated but there is no sign of the progress bar doing its
thing. I dont get why this is such a hard thing to accomplish, I would
have thought that this sort of event would be easy to trap.
From: ScottMcP [MVP] on
On Oct 22, 5:02 am, Bidski <bids...(a)gmail.com> wrote:
> > > What I am trying to do seems fairly simple and straightforward (at
> > > least, it does to me tongue.gif). Basically what I am wanting to do is
> > > trap an event that occurs when a dialog box is shown to the screen,
> > > but I only want it to happen once (being the first time that the form
> > > is displayed to screen after its initial loading).

You can make your own event to do this. In the dialog's OnInitDialog
do PostMessage. Add a message handler for this custom message. It
will be called after the dialog is visible on the screen. For details
on using a custom message see

http://vcfaq.mvps.org/mfc/12.htm

The progress bar is not going to update while you are doing the
lengthy control updates, because a lengthy code operation blocks
message processing. So the progress bar does not receive WM_PAINT.
You can, however, force the progress bar to update by calling its
UpdateWindow method every time you change the progress position.
From: Bidski on
On Oct 23, 2:05 am, "ScottMcP [MVP]" <scott...(a)mvps.org> wrote:
> On Oct 22, 5:02 am, Bidski <bids...(a)gmail.com> wrote:
>
> > > > What I am trying to do seems fairly simple and straightforward (at
> > > > least, it does to me tongue.gif). Basically what I am wanting to do is
> > > > trap an event that occurs when a dialog box is shown to the screen,
> > > > but I only want it to happen once (being the first time that the form
> > > > is displayed to screen after its initial loading).
>
> You can make your own event to do this.  In the dialog's OnInitDialog
> do PostMessage.  Add a message handler for this custom message.  It
> will be called after the dialog is visible on the screen.  For details
> on using a custom message see
>
> http://vcfaq.mvps.org/mfc/12.htm
>
> The progress bar is not going to update while you are doing the
> lengthy control updates, because a lengthy code operation blocks
> message processing. So the progress bar does not receive WM_PAINT.
> You can, however, force the progress bar to update by calling its
> UpdateWindow method every time you change the progress position.

That still doesnt appear to be working as expected. The form is still
displaying to the screen fully loaded and if I display a message box
in the event handler it appears before the form does. Is there some
sort of definitive way that I can test to see exactly when the event
is being triggered?