Forum > LCL
[SOLVED] Application.ProcessMessages does not work as expected
erol:
Hello All,
I have a simple form which has only a button. Function check if a number is prime number or not. I can move window but can not close. There is no value come back from function. If I comment out Application.ProcessMessages, function returns after a few secs. I use Lazarus 3.6 (64-bit) and Windows 10.
--- 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) Button1: TButton; procedure Button1Click(Sender: TObject); private public function asal(x:dword):boolean; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } function TForm1.asal(x:dword):boolean;var i:dword;begin if (x mod 2)=0 then if x=2 then result:=true else result:=false else begin i:=3; while i<x do begin if (x mod i)=0 then begin result:=false; exit; end; i:=i+2; Application.ProcessMessages; end; result:=true; end;end; procedure TForm1.Button1Click(Sender: TObject);begin if asal(587100037) then showmessage('bu sayı asal') else showmessage('bu sayı asal değil')end;end.
Thaddy:
If there is no room to process, Application.processmessages will not work.
It is not a magic wand. Your code is simply not correct.
Gigatron:
Hi,
Application.ProcessMessages; freeze when the number is bigger in your code ;
try to comment this function;
--- 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) Button1: TButton; procedure Button1Click(Sender: TObject); private public function asal(x:dword):boolean; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } function TForm1.asal(x:dword):boolean; var i:dword; begin if (x mod 2)=0 then if x=2 then result:=true else result:=false else begin i:=3; while i<x do begin if (x mod i)=0 then begin result:=false; exit; end; i:=i+2; // Application.ProcessMessages; // freez application you can not move window or close during process !! end; result:=true; end; end; procedure TForm1.Button1Click(Sender: TObject); begin if asal(587100037) then showmessage('bu sayı asal') else showmessage('bu sayı asal değil') end; end.
Or try this code if it's working for you with Application.ProcessMessages;
--- 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";}};} ---function TForm1.asal(x: dword): boolean;var i: dword;begin if x < 2 then Exit(False); if x = 2 then Exit(True); if (x mod 2) = 0 then Exit(False); i := 3; while i * i <= x do begin if (x mod i) = 0 then Exit(False); i := i + 2; Application.ProcessMessages; end; Result := True;end; procedure TForm1.Button1Click(Sender: TObject);begin if asal(587100037) then showmessage('bu sayı asal') else showmessage('bu sayı asal değil')end;
Good luck;
alpine:
--- Quote ---There is no value come back from function.
--- End quote ---
Are you sure? Did you wait long enough?
Calling Application.ProcessMessages in such a loop can slowdown by a factor of a thousand.
However, using it is not a good idea anyway - it can cause an indirect recursion and rather inexplicable GUI behavior.
Martin_fr:
You don't really want to call ProcessMessages that often => that takes to much time.
For the user it is enough, if you call it ever 50 to 100 milliseconds. But rather than taking the time you may simple say you call it every time you did e.g. 100 loop iterations (100 divisions is likely still much faster than 50 ms).
Something like
--- 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";}};} ---if (i and 127) = 0 then // or i and 255 // or i and 1023 Application.ProcessMessages;
As for being able to close the form => It will wait for your loop to finish.
You could add on an OnCloseQuery (not sure name maybe similar) event. That should be called during ProcessMessages if the user tries to close the form.
In that you can set a flag (add a field FCloseRequestedByUser: boolean to the form). Then you can set that to true, and in your loop, after calling ProcessMessages, you can do "if FCloseRequestedByUser then exit;"
Navigation
[0] Message Index
[#] Next page