Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2012-03

TreeView sometimes calls Refresh instead of Invalidate

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

cobines

Hello.

In the TreeView there are many calls to TreeView.Invalidate but TTreeNodes.SetUpdateState and TTreeStrings.SetUpdateState call TreeView.Refresh instead. Refresh calls TWidgetSet.UpdateWindow which on Win32 and GTK2 causes repaint of the control via synchronous WM_PAINT. QT4 seems to only post a paint request to the message queue. Should it not be Invalidate instead of Refresh? Why the need for immediate Repaint? Multiple calls to Invalidate stack, so only one Paint is done later.

At least on Windows and GTK2 this causes the TreeView to be repainted twice instead of once:

TreeView1.Items.Add(nil, 'Something');

There seem to be redundant Invalidates as well. For example in TTreeNodes.InternalAddObject TreeView is invalidated after adding node:

...
    Result.InternalMove(Node,AddMode);
...
    if (FUpdateCount=0) and (Ownernil) then
      Owner.Invalidate;

But in TTreeNode.InternalMove there is already call to TreeView.EndUpdate in which there is:

  Items.EndUpdate;
  if Items.FUpdateCount=0 then begin
    // ToDo: only refresh if something changed
    UpdateScrollBars;
    Invalidate;
  end;

Items.EndUpdate causes repaint via UpdateWindow. Then there's Invalidate which will post another WM_PAINT to the message queue. And finally there's yet another Invalidate when it goes back to TTreeNodes.InternalAddObject, as shown above.

Similar thing is within TTreeNodes.Clear.

  BeginUpdate;
...
    if (FUpdateCount = 0) and Assigned(Owner) then
      Owner.Invalidate;
...
  EndUpdate;

The Owner.Invalidate is redundant, since EndUpdate will call Owner.Refresh anyway. Plus it will never be called anyway since we just increased FUpdateCount with BeginUpdate.

There are three more instances where Invalidate is called within Begin/EndUpdate block or just after EndUpdate.
Are the explicit calls to Invalidate needed?

cobines

Reply by email

Juha Manninen
to cobines
cobines wrote 12 lines
In the TreeView there are many calls to TreeView.Invalidate but TTreeNodes.SetUpdateState and TTreeStrings.SetUpdateState call TreeView.Refresh instead. Refresh calls TWidgetSet.UpdateWindow which on Win32 and GTK2 causes repaint of the control via synchronous WM_PAINT. QT4 seems to only post a paint request to the message queue. Should it not be Invalidate instead of Refresh? Why the need for immediate Repaint? Multiple calls to Invalidate stack, so only one Paint is done later. At least on Windows and GTK2 this causes the TreeView to be repainted twice instead of once:

[...]

Could you please create a patch. I will test and apply it.

Juha
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20120330/76868fa8/attachment.html>

Reply by email