Recent

Author Topic: (solved)Form Loading Issue  (Read 1056 times)

ShungFeng

  • New Member
  • *
  • Posts: 20
(solved)Form Loading Issue
« on: February 20, 2020, 07:44:28 pm »
My main form creates a dialog and if the user clicks "yes", another form should show, but none of its controls show until the rest of the procedure has completed:

Code: Pascal  [Select][+][-]
  1. procedure showdialog;
  2. begin
  3.   if MessageDlg('warning', 'msg', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  4.     begin
  5.       Form2.Show; // Form2 shows, but none of the components load until after the next part has completed...
  6.       for { } to { } do
  7.       begin
  8.         { Execute external process }
  9.       end;
  10.     // Now after the external process has completed, the components on Form2 finally load
  11.     end;
  12. end;
  13.  
  14. procedure TForm1.Button1Click(Sender: TObject);
  15. begin
  16.   showdialog;
  17. end;

Why does this not work, does TForm.Show not also include showing all of the components on the form? If not, what can I do instead?

Thank you
« Last Edit: February 20, 2020, 11:09:51 pm by ShungFeng »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Form Loading Issue
« Reply #1 on: February 20, 2020, 07:58:43 pm »
Showing both the form and the controls is a relatively lenghty process done in cooperation between the application and the window/composition manager, and is normally done by sending various messages back an forth. However, your application is quite busy doing something other than responding to those messages, so all that has to wait until you finally exit the procedure.

The usual way to prevent that is doing something like:

Code: Pascal  [Select][+][-]
  1. procedure showdialog;
  2. begin
  3.   if MessageDlg('warning', 'msg', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  4.     begin
  5.       Form2.Show;
  6.       Application.ProcessMessages;
  7.       for { } to { } do
  8.       begin
  9.         { Execute external process }
  10.       end;
  11.     end;
  12. end;
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

ShungFeng

  • New Member
  • *
  • Posts: 20
Re: Form Loading Issue
« Reply #2 on: February 20, 2020, 08:23:43 pm »
Thank you, that solves most of the problem - all of the form components become visible now. But there's just one issue: the form that appears also has a ttimer which influences some of the components graphically; is there any way to ensure that that ttimer can run normally?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Form Loading Issue
« Reply #3 on: February 20, 2020, 10:03:38 pm »
Hi!

How is the timer not running "normally"???

Unless you put heavy load on your machine it runs normally.

If you do heavy computings then put again a

application.processMessages

especialiy in loops.

But you have to explain what is nor running "normally".

Winni

ShungFeng

  • New Member
  • *
  • Posts: 20
Re: Form Loading Issue
« Reply #4 on: February 20, 2020, 10:12:26 pm »
Hi!

How is the timer not running "normally"???

Unless you put heavy load on your machine it runs normally.

If you do heavy computings then put again a

application.processMessages

especialiy in loops.

But you have to explain what is nor running "normally".

Winni

Hi!

The form has some shapes that move, and they move based off of a timer's tick. If the form were to start normally, all of the shapes move about, but right now, they don't move at all until AFTER the process in the loop has complete.

I appreciate your help!   :)

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Form Loading Issue
« Reply #5 on: February 20, 2020, 10:21:45 pm »
Hi!

Take Lucamars example an enhance it a little bit.
As I said: Put application.ProcessMessages in the loop so that it does not grab all resources but give other events "time to breath".


Code: Pascal  [Select][+][-]
  1.    procedure showdialog;
  2.     begin
  3.       if MessageDlg('warning', 'msg', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  4.         begin
  5.           Form2.Show;
  6.           Application.ProcessMessages;
  7.           for { } to { } do
  8.           begin
  9.             { Execute external process }
  10.            Application.ProcessMessages;  // <-- HERE
  11.           end;
  12.         end;
  13.     end;

Winni

ShungFeng

  • New Member
  • *
  • Posts: 20
Re: Form Loading Issue
« Reply #6 on: February 20, 2020, 11:09:32 pm »
Thanks winni, that's better now :D

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Form Loading Issue
« Reply #7 on: February 21, 2020, 01:50:22 am »
Take Lucamars example an enhance it a little bit.
As I said: Put application.ProcessMessages in the loop so that it does not grab all resources but give other events "time to breath".

I would instead do it like:

Code: Pascal  [Select][+][-]
  1.    procedure showdialog;
  2.     begin
  3.       if MessageDlg('warning', 'msg', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  4.         begin
  5.           Form2.Show;
  6.           for { } to { } do
  7.           begin
  8.             Application.ProcessMessages; { <- Better HERE ;) }
  9.             { Execute external process }
  10.           end;
  11.         end;
  12.     end;

It's generally considered better to use ProcessMessages sparingly (if at all); this way you avoid the extra call after Form2.Show;
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4459
  • I like bugs.
Re: Form Loading Issue
« Reply #8 on: February 21, 2020, 02:02:50 am »
Thanks winni, that's better now :D
Better but still a bit jerky, isn't it?
You should use a thread in this case. Apparently the external process results are not needed immediately, making the thread's synchronization easy.
Just call Thread.WaitFor before you need the result, then free the thread.
If the thread has finished by then, it will not slow down the main process at all.
Threads should be used more because CPUs have more and more cores. Typically only one of them is busy at a time while others idle.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

 

TinyPortal © 2005-2018