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?
