Recent

Author Topic: Question: other way to avoid flicker with TDragControlObjectEx (Windows)?  (Read 201 times)

d7_2_laz

  • Sr. Member
  • ****
  • Posts: 281
This is surely not a Lazarus issue but more a "howto", but i raise it because it might be of interest for others too.
For to have a special drag image on a custom treeview, i'd be using successfully
a TMyDragObject from class TDragControlObjectEx. 
At the beginning i had a flicker issue  using it. I avoided that by applying LockWindowUpdate (somehow similar: BeginUpdate/EndUpdate).

DirTreeDoOnStartDrag
    DragObject := TMyDragObject.CreateWith(Sender as TControl, FTvImageList, imgidx, aText);  // without this, no flicker
    LockWindowUpdate(Handle);    // without this, flicker when using "TMyDragObject"

DirTreeDoOnEndDrag
    LockWindowUpdate(0);
     .................. 

Now, for other things i'd like to do i need to revoke  this special LockWindowUpdate. And so the flicker issue does reappear at each mouse move.

Unfortunately, i don't see the flicker issue with a simple test project,
So i tracked down the coding in my app step by step. Nulling out by  "exit"s  in nearly every procedure that may interfere and cause side effects.
But even using "exit" as only statement within "DragOver" causes screen repainting on each dragging mouse move.
All components involved are doublebuffered.

Meanwhile i'm missing ideas why a simple “create a TDragControlObjectEx could be sufficient to cause flicker even the DragOver event callback is empty.

So i'd like to ask if somebody yet did encounter something similar and did solve it other than using LockWindowUpdate.
Every idea about possible causes is welcome. Why TDragControlObjectEx might cause repeated repaints?

Vice versa: is it possible to enforce a repaint of a single node although a LockWindowUpdate had been done? (probably not, but that would allow to keep the LockWindowUpdate)

PS: in this crenario, the drag is a node drag inside the treeview only. -  Potential scrolling does not play a role.

jamie

  • Hero Member
  • *****
  • Posts: 4667
maybe using clipping rectangles to the canvas of the background control so that only the part you want updated will paint for the moment, remember the remove that rectangle from the canvas.
The only true wisdom is knowing you know nothing

d7_2_laz

  • Sr. Member
  • ****
  • Posts: 281
Jamie, you mean it might be possible to (independently from customdraw) paint over the control using a clliprect, overruling the LockWindowUpdate?
Sounds interesting, i'll think about it; thank you!

d7_2_laz

  • Sr. Member
  • ****
  • Posts: 281
However i still asked myself: why the different behaviour between my app and a small test project?
Probably now i did find the main dependency that did cause the flicker

Some time ago i saw the issue that when maximizing the window black regions beyond the treeview became visible.
Finally i did solve that via:
)n FormCreate, applying SetClassLongPtrW either to the form's handle or panel handle or both:

Code: Pascal  [Select][+][-]
  1.    procedure TForm1.FormCreate(Sender: TObject);
  2.      ...........
  3.    // See: https://forum.lazarus.freepascal.org/index.php/topic,57167.msg425001.html#msg425001
  4.    // Set window background due to prob black region at maximize:
  5.       SetClassLongPtrW(handle, GCL_HBRBACKGROUND, 6);     // 5: lightgray   6: white

>>>>  Removing this line does remove the flicker with TDragControlObjectEx without LockWindowUpdate
>>>>  Applying this line in a simple test project does show up the flicker here too.

After a long time of usage that's the first time i saw a side-effect of this solution.
Of course now the original problem would be back again, that's the bad news.

But apparently it's possible to temporarely deactivate that call during the drag and to reactivate it later.
Alternatively, maybe somebody knows a better solution for the black regions when maximizing does exist ?

 

TinyPortal © 2005-2018