Forum > General

FormShow with QueueAsyncCall() different behaviour

(1/3) > >>

Moritz:
Hello :)

I recently upgraded to Lazarus 3.4, from 2.2.6 and noticed some (maybe) weird behaviour.

I was using Application.QueueAsyncCall() to execute some code (loading data) after FormShow().
The following code is a simplification of what I want to do. The form includes some random controls.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TMainForm.AfterShow(Ptr: IntPtr);begin  Sleep(4000);  // loading dataend; procedure TMainForm.FormShow(Sender: TObject);begin  Application.QueueAsyncCall(@AfterShow, 0);end; 
The code is compiled using the exact same settings and config (except the versions)

Lazarus 2.2.6: The form shows up with all it's controls (FormShow finishes), then it just stays busy for 4 seconds ("loading data").
Lazarus 3.4: The form shows up, but is white for 4 seconds ("loading data"), then after that it shows the content ("FormShow finishes).

In the never version it does not seem to be async at all. I was looking through the changelog of the never version, but could not find anything
specific which could be the reason for this difference. I'm also not entirely sure what is the root cause here (Forms, QueueAsyncCall, "@", ...).

To be absolutely sure, I reinstalled both Lazarus versions. I also tested version 3.0RC1, where it was the same as in 3.4.

System: Windows 10 (2004)

Thaddy:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TMainForm.FormShow(Sender: TObject);begin  Application.ProcessMessages;// to finish waiting paint updates  Application.QueueAsyncCall(@AfterShow, 0);end;You can also try Tform.begin/endupdate.

Moritz:
This does not work sadly. The form still stays white for 4 seconds (during the entire "async" call) until it actually shows it's controls... :(
Unless I find out why this has changed, I have to stick to Lazarus 2.2.6 for a bit longer I guess, at least for this project...

bpranoto:
Try this


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.FormShow(Sender: TObject);begin  Application.QueueAsyncCall(@Self.AfterShow,0);  Application.ProcessMessages;end; 

BrunoK:
Possible solution demo :

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls; type   { TForm1 }   TForm1 = class(TForm)    Label1: TLabel;    Memo1: TMemo;    procedure FormShow(Sender: TObject);  private    FOldOnIdle: TIdleEvent;    procedure AfterShow(Sender: TObject; var Done: Boolean);  public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.AfterShow(Sender: TObject; var Done: Boolean);var  Start: Qword;begin  Application.OnIdle := FOldOnIdle; // Restore catched OnIdle.  Label1.Caption:=Format('Sleep(4000)', [GetTickCount64-Start]);  Application.ProcessMessages;  Start:=GetTickCount64;  Sleep(4000);  // loading data  Memo1.Lines.Add(Format('Waited %d ticks', [GetTickCount64-Start]));  Memo1.ScrollBy(0, Memo1.Lines.Count);  Label1.Caption:=Format('Slept(%d)', [GetTickCount64-Start]);  Done := True;end; procedure TForm1.FormShow(Sender: TObject);begin  FOldOnIdle := Application.OnIdle; // Save current OnIdle.  Application.OnIdle:=@AfterShow;end; end.

Navigation

[0] Message Index

[#] Next page

Go to full version