how to refresh/repaint/invalidate a component in firemonkey? [Edit]

Hi,

I try to update a component text property periodically ...

example: 

put a TBbutton on a form,

add the following code to the OnClick event:

{code}
procedure TForm1.Button1Click(Sender: TObject);

  var i : integer;

  begin
    for i := 1 to 1000000 do begin
      if i mod 1000 = 0 then begin
        button1.Text := inttostr(i);
        button1.Repaint;
        // have tried "Realign" too...
      end;
    end;
  end;
{code}

From my point of view, this routine should update the component 
every thousand steps... I have tried .realign too... without success...

Any idea how to refresh a firemonkey component or the whole form/scene?

Tia,

Peter

Edited by: Peter Wichenthaler-Sternbach on Nov 7, 2011 2:40 AM
0
Peter
11/7/2011 10:41:11 AM
embarcadero.delphi.firemonkey 4901 articles. 4 followers. Follow

12 Replies
11889 Views

Similar Articles

[PageSpeed] 27

> {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> Hi,
> 
> I try to update a component text property periodically ...
> 
> example: 
> 
> put a TBbutton on a form,
> 
> add the following code to the OnClick event:
> 
> {code}
> procedure TForm1.Button1Click(Sender: TObject);
> 
>   var i : integer;
> 
>   begin

The form will repaint if you use TForm1.Invalidate.  Try that.

Scott
>     for i := 1 to 1000000 do begin
>       if i mod 1000 = 0 then begin
>         button1.Text := inttostr(i);
>         button1.Repaint;
>         // have tried "Realign" too...
>       end;
>     end;
>   end;
> {code}
> 
> From my point of view, this routine should update the component 
> every thousand steps... I have tried .realign too... without success...
> 
> Any idea how to refresh a firemonkey component or the whole form/scene?
> 
> Tia,
> 
> Peter
> 
> Edited by: Peter Wichenthaler-Sternbach on Nov 7, 2011 2:40 AM
0
Scott
11/7/2011 3:30:02 PM
> {quote:title=Scott Hochberg wrote:}{quote}
> > {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> > Hi,
> > 
> > I try to update a component text property periodically ...
> > 
> > example: 
> > 
> > put a TBbutton on a form,
> > 
> > add the following code to the OnClick event:
> > 
> > {code}
> > procedure TForm1.Button1Click(Sender: TObject);
> > 
> >   var i : integer;
> > 
> >   begin
> 
> >     for i := 1 to 1000000 do begin
> >       if i mod 1000 = 0 then begin
> >         button1.Text := inttostr(i);
> >         button1.Repaint;
> >         // have tried "Realign" too...
> >       end;
> >     end;
> >   end;
> > {code}
> > 
> > From my point of view, this routine should update the component 
> > every thousand steps... I have tried .realign too... without success...
> > 
> > Any idea how to refresh a firemonkey component or the whole form/scene?
> > 
> > Tia,
> > 
> > Peter
> > 
> > Edited by: Peter Wichenthaler-Sternbach on Nov 7, 2011 2:40 AM

Sorry, let me try this again - my reply got stuck in the middle of your question --

The form will repaint if you use TForm1.Invalidate.  Try that.

Scott
0
Scott
11/7/2011 3:32:50 PM
> {quote:title=Scott Hochberg wrote:}{quote}
> > {quote:title=Scott Hochberg wrote:}{quote}
> > > {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> > > Hi,
> > > 
> > > I try to update a component text property periodically ...
> > > 
> > > example: 
> > > 
> > > put a TBbutton on a form,
> > > 
> > > add the following code to the OnClick event:
> > > 
> > > {code}
> > > procedure TForm1.Button1Click(Sender: TObject);
> > > 
> > >   var i : integer;
> > > 
> > >   begin
> > 
> > >     for i := 1 to 1000000 do begin
> > >       if i mod 1000 = 0 then begin
> > >         button1.Text := inttostr(i);
> > >         button1.Repaint;
> > >         // have tried "Realign" too...
> > >       end;
> > >     end;
> > >   end;
> > > {code}
> > > 
> > > From my point of view, this routine should update the component 
> > > every thousand steps... I have tried .realign too... without success...
> > > 
> > > Any idea how to refresh a firemonkey component or the whole form/scene?
> > > 
> > > Tia,
> > > 
> > > Peter
> > > 
> > > Edited by: Peter Wichenthaler-Sternbach on Nov 7, 2011 2:40 AM
> 
> Sorry, let me try this again - my reply got stuck in the middle of your question --
> 
> The form will repaint if you use TForm1.Invalidate.  Try that.
> 
> Scott


Hello Scott,

I've tried Form1.Invalidate too, still no effect here. Btw, I'm using  update 2, it did not work under update 1 either...

Regards,

Peter
0
Peter
11/7/2011 3:50:55 PM
Peter Wichenthaler-Sternbach wrote:
> Any idea how to refresh a firemonkey component or the whole
> form/scene?

Weird. This should work. But it does not, indeed. It does work when you
use an Application.ProcessMessages, but that slows stuff down too much.
0
Dominique
11/7/2011 4:33:09 PM
Peter Wichenthaler-Sternbach wrote:
> button1.Text := inttostr(i);

Compromise, but fast, is to use

button1.Text := inttostr(i);
Application.HandleMessage

No Repaint necessary.
0
Dominique
11/7/2011 4:55:15 PM
> {quote:title=Dominique Willems wrote:}{quote}
> Peter Wichenthaler-Sternbach wrote:
> > button1.Text := inttostr(i);
> 
> Compromise, but fast, is to use
> 
> button1.Text := inttostr(i);
> Application.HandleMessage
> 
> No Repaint necessary.

Super - many thanks - this is really working. I haven't noticed that Application.ProcessMessages
& co is aboard in Firemonkey now...
0
Peter
11/8/2011 5:17:28 AM
I've tried to apply the suggestions in this thread to my solve my problem, but it's not working. I have a FireMonkey TListBox that won't repaint. I've tried:
ListBox1.InvalidateRect(RectF(0,0,width,height));
ListBox1.Realign;
Application.ProcessMessages;
Application.HandleMessage;
None of the above work. Any thoughts?


> {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> > {quote:title=Dominique Willems wrote:}{quote}
> > Peter Wichenthaler-Sternbach wrote:
> > > button1.Text := inttostr(i);
> > 
> > Compromise, but fast, is to use
> > 
> > button1.Text := inttostr(i);
> > Application.HandleMessage
> > 
> > No Repaint necessary.
> 
> Super - many thanks - this is really working. I haven't noticed that Application.ProcessMessages
> & co is aboard in Firemonkey now...
0
Daryl
1/17/2012 6:03:41 PM
> {quote:title=Daryl Erwin wrote:}{quote}
> I've tried to apply the suggestions in this thread to my solve my problem, but it's not working. I have a FireMonkey TListBox that won't repaint. I've tried:
> ListBox1.InvalidateRect(RectF(0,0,width,height));
> ListBox1.Realign;
> Application.ProcessMessages;
> Application.HandleMessage;
> None of the above work. Any thoughts?
> 
> 
> > {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> > > {quote:title=Dominique Willems wrote:}{quote}
> > > Peter Wichenthaler-Sternbach wrote:
> > > > button1.Text := inttostr(i);
> > > 
> > > Compromise, but fast, is to use
> > > 
> > > button1.Text := inttostr(i);
> > > Application.HandleMessage
> > > 
> > > No Repaint necessary.
> > 
> > Super - many thanks - this is really working. I haven't noticed that Application.ProcessMessages
> > & co is aboard in Firemonkey now...

Hello,

Well if you want to repaint the form while still in executing the callback of a button, you shall start a new Thread, because the callback actualy blocks your interface.

Stefan
0
Stefan
1/18/2012 11:56:10 AM
> {quote:title=Stefan Baciu wrote:}{quote}
> > {quote:title=Daryl Erwin wrote:}{quote}
> > I've tried to apply the suggestions in this thread to my solve my problem, but it's not working. I have a FireMonkey TListBox that won't repaint. I've tried:
> > ListBox1.InvalidateRect(RectF(0,0,width,height));
> > ListBox1.Realign;
> > Application.ProcessMessages;
> > Application.HandleMessage;
> > None of the above work. Any thoughts?
> > 
> > 
> > > {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> > > > {quote:title=Dominique Willems wrote:}{quote}
> > > > Peter Wichenthaler-Sternbach wrote:
> > > > > button1.Text := inttostr(i);
> > > > 
> > > > Compromise, but fast, is to use
> > > > 
> > > > button1.Text := inttostr(i);
> > > > Application.HandleMessage
> > > > 
> > > > No Repaint necessary.
> > > 
> > > Super - many thanks - this is really working. I haven't noticed that Application.ProcessMessages
> > > & co is aboard in Firemonkey now...
> 
> Hello,
> 
> Well if you want to repaint the form while still in executing the callback of a button, you shall start a new Thread, because the callback actualy blocks your interface.
> 
> Stefan

I'm not sure I follow what you mean. I'll give a little more detail. I've built a simple client/server chat program. A message comes in from the client, which is displayed in TListBox. Then the server app waits until a TCheckBox is checked, then sends a response back to the client, and displays it response in its TListBox. Here's my procedure: 
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var str: string;
begin
  str:= AContext.Connection.IOHandler.ReadLn();
  ListBox1.Items.Add(AContext.Connection.Socket.Binding.PeerIP + ':' + IntToStr(AContext.Connection.Socket.Binding.PeerPort) + ': ' + str);
  ListBox1.ItemIndex:= ListBox1.Items.Count -1;
  while not DoneCheck.IsChecked do
     Delay(500);
  AContext.Connection.IOHandler.WriteLn(ReplyEdit.Text);
  ListBox1.Items.Add('Me: ' + ReplyEdit.Text);
  ListBox1.ItemIndex:= ListBox1.Items.Count -1;
  DoneCheck.IsChecked:= False;
end;
0
Daryl
1/18/2012 4:30:42 PM
I had a similar problem. Windows 32 bit behaves a bit differently from Windows 64 (on the same 32 bit exe)
I managed to solve this using Canvas.Clear(0) method..
0
Paolo
1/18/2012 8:02:20 PM
> {quote:title=Daryl Erwin wrote:}{quote}
> > {quote:title=Stefan Baciu wrote:}{quote}
> > > {quote:title=Daryl Erwin wrote:}{quote}
> > > I've tried to apply the suggestions in this thread to my solve my problem, but it's not working. I have a FireMonkey TListBox that won't repaint. I've tried:
> > > ListBox1.InvalidateRect(RectF(0,0,width,height));
> > > ListBox1.Realign;
> > > Application.ProcessMessages;
> > > Application.HandleMessage;
> > > None of the above work. Any thoughts?
> > > 
> > > 
> > > > {quote:title=Peter Wichenthaler-Sternbach wrote:}{quote}
> > > > > {quote:title=Dominique Willems wrote:}{quote}
> > > > > Peter Wichenthaler-Sternbach wrote:
> > > > > > button1.Text := inttostr(i);
> > > > > 
> > > > > Compromise, but fast, is to use
> > > > > 
> > > > > button1.Text := inttostr(i);
> > > > > Application.HandleMessage
> > > > > 
> > > > > No Repaint necessary.
> > > > 
> > > > Super - many thanks - this is really working. I haven't noticed that Application.ProcessMessages
> > > > & co is aboard in Firemonkey now...
> > 
> > Hello,
> > 
> > Well if you want to repaint the form while still in executing the callback of a button, you shall start a new Thread, because the callback actualy blocks your interface.
> > 
> > Stefan
> 
> I'm not sure I follow what you mean. I'll give a little more detail. I've built a simple client/server chat program. A message comes in from the client, which is displayed in TListBox. Then the server app waits until a TCheckBox is checked, then sends a response back to the client, and displays it response in its TListBox. Here's my procedure: 
> procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
> var str: string;
> begin
>   str:= AContext.Connection.IOHandler.ReadLn();
>   ListBox1.Items.Add(AContext.Connection.Socket.Binding.PeerIP + ':' + IntToStr(AContext.Connection.Socket.Binding.PeerPort) + ': ' + str);
>   ListBox1.ItemIndex:= ListBox1.Items.Count -1;
>   while not DoneCheck.IsChecked do
>      Delay(500);
>   AContext.Connection.IOHandler.WriteLn(ReplyEdit.Text);
>   ListBox1.Items.Add('Me: ' + ReplyEdit.Text);
>   ListBox1.ItemIndex:= ListBox1.Items.Count -1;
>   DoneCheck.IsChecked:= False;
> end;


Well, try this out, for me it works,

unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, IdContext, IdBaseComponent,
  IdComponent, IdCustomTCPServer, IdTCPServer, FMX.Layouts, FMX.ListBox,
  FMX.Edit;
type MyThread = class(TThread)
    protected
    procedure Execute; override;
    public
    AContext: TIdContext;
    constructor Create; overload;
    destructor Destroy; override;
  end;
type
  TForm2 = class(TForm)
    DoneCheck: TCheckBox;
    ListBox1: TListBox;
    IdTCPServer1: TIdTCPServer;
    ReplyEdit: TEdit;
    procedure IdTCPServer1Execute(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

constructor MyThread.Create;
begin
  inherited Create(true); // suspended to allow creation of stuff before run
  FreeOnTerminate := true;
end;
destructor MyThread.Destroy;
begin
  inherited;
end;

procedure MyThread.Execute;
var
  str : string;
  host : string;
  port : string;
begin
  while NOT Form2.DoneCheck.IsChecked do
    Sleep(500);
  AContext.Connection.IOHandler.WriteLn(Form2.ReplyEdit.Text);
  Form2.ListBox1.Items.Add('Me: ' + Form2.ReplyEdit.Text);
  Form2.ListBox1.ItemIndex:= Form2.ListBox1.Items.Count -1;
  Form2.DoneCheck.IsChecked:= False;
end;

procedure TForm2.IdTCPServer1Execute(AContext: TIdContext);
var str: string;
    MT : MyThread;
begin
  str:= AContext.Connection.IOHandler.ReadLn();
  ListBox1.Items.Add(AContext.Connection.Socket.Binding.PeerIP + ':' + IntToStr(AContext.Connection.Socket.Binding.PeerPort) + ': ' + str);
  ListBox1.ItemIndex:= ListBox1.Items.Count -1;
  MT := MyThread.Create;
  MT.AContext:=AContext;
  MT.Start;
end;

end.

Regards, 

Stefan
0
Stefan
1/19/2012 12:02:24 PM
> {quote:title=Paolo Francesco Ingraito wrote:}{quote}
> I had a similar problem. Windows 32 bit behaves a bit differently from Windows 64 (on the same 32 bit exe)
> I managed to solve this using Canvas.Clear(0) method..

I am indeed running 32 bit. Your idea seems to help, but parts of the text go invisible sometimes. So I took your suggestion and then run through the items setting them to visible. This helps, but then I randomly get sections/all of the TListBox turning black. So this doesn't seem to be a full solution either. Here's my new code:
canvas.Clear($FFFFFF);  
for i := 0 to ListBox1.items.count-1 do
  ListBox1.ItemByIndex(i).Visible:= true;
0
Daryl
1/20/2012 5:54:08 PM
Reply: