milleratotago wrote:
> On Jun 13, 3:10 am, Dale.Ing...@[EMAIL PROTECTED]
wrote:
>> I have several child forms that open as modal dialogs; I fill them in
(they're all listviews) in the OnShow event handlers, but sometimes the
processing can take a long time, so the user (me) sits there staring at
nothing for quite a while until the form suddenly pops up all filled in or
processed.
>
> Here's a dirty trick--pretty ugly, but it works.
>
> 1. Put a timer on the form with a very small interval,
> and set it's enabled to false.
>
> 2. In FormShow, just enable the timer.
>
> 3. Put the code to load up the form into the OnTimer event
> handler (and be sure to set its enabled back to false here).
The essence of the dirty trick is that the timer message won't be
handled until the program's message loop begins or resumes running.
The part that makes it dirty is that you're using a timer for something
that's obviously not periodic, and then the timer sticks around for the
duration of the form's lifetime even though there's nothing to time.
To resolve that, take out the timer and just use a message. It doesn't
need to be a timer message. Any message will do. Use PostMessage to put
the message on the end of the queue, _after_ all the messages that have
already been queued to make the form appear. When the message loop runs,
that message will work its way to the front of the queue.
Define a message:
const
am_InitForm = wm_User + 1;
Then change the Timer1Timer method to handle the message instead:
private
procedure AMInitForm(var Message: TMessage); message am_InitForm;
> Here is a small example with just a memo and a timer on the form:
>
> procedure TForm1.FormShow(Sender: TObject);
> Var i : Integer;
> begin
> Timer1.Enabled := True;
Instead of enabling the timer, post the message:
PostMessage(Handle, am_InitForm, 0, 0);
> {
> If you include this code here (without the
> timer), then the form only shows up after
> 20 sec and the memo already has its 10 lines.
> For i := 1 to 10 Do Begin
> Memo1.Lines.Add(IntToStr(i));
> Sleep(2000);
> End;
> }
> end;
>
> procedure TForm1.Timer1Timer(Sender: TObject);
Rename this and change the signature to match AMInitForm above.
> Var I : integer;
> begin
> Timer1.Enabled := False; // Don't forget this one!
No need to disable the timer anymore. The very fact that you don't post
another am_InitForm message will be sufficient to prevent initialization
from occurring again.
> { If you load up the memo with this timer event handler,
> then the form will show immediately and the new lines
> will appear every 2 sec. }
> For i := 1 to 10 Do Begin
> Memo1.Lines.Add(IntToStr(i));
> Sleep(2000);
> End;
> End;
>
> Hope that helps,
>
--
Rob


|