Forum > LCL

[SOLVED] Application.ProcessMessages does not work as expected

(1/3) > >>

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

Go to full version