Einzelnen Beitrag anzeigen

Kas Ob.

Registriert seit: 3. Sep 2023
346 Beiträge
 
#2

AW: Transparentes TCustomControl

  Alt 26. Sep 2023, 11:10
Does anyone have experience with or understand the Windows Paint cycle better than I do, especially with regard to DoubleBuffered?
I can't reproduce that annoying flicker, because on my Windows i have all theming and visual enhancement disabled even the Windows service is disabled.

But i barely notice an empty box around the mouse cursor as you move it, i think you referring to this barely noticeable behavior, which might be a flickering a lot on other Windows's.

Anyway, i don't have a definite answer or solution, but i can give thoughts about your code.
1) Assuming "invalids" is Invalidate as the demo, then you are invalidating a small rect at the parent then calling to full invalidate on self, here i am not sure if the sysetem will call to draw all the lower controls.
2) self is transparent, if it wasn't then repaint done right it should fully draw self, not only a rect, hence it should cause a redraw of all the lower levels, the form and the imagebox.
3) if you assigned even OnPaint on the form with do nothing (// as content) you should notice less flicker, as between Delphi and OS the Default paint procedure will be shorter, hence faster than left to Windows Message queue to fill and reach Delphi, as Windows remove and adjust and reorder Paint Messages as see fit.
4) the empty box i see is because the delay between draw the form then draw the image box, this is the meat of this behavior.

DoubleBuffering should help but to make use of it you should fully have drawn your custom and transparent control, at least once, this will complicate the procedure as you need to get all the lower level on your own, but this will leads to not use any ready to use transparent functionality.

My suggestion is : if it is possible and the background is not moving/changing (a lot), then cache it and don't use the InvalidateRect as it is the cause of the flickering box, and just redraw that box from you cache to remove your old red circle. (here you also can use smaller box at the size of the red circle)
Also smaller rect to invalidate will be less noticeable like using aRect := Rect(FX - 4, FY - 4, FX + 4, FY + 4); against aRect := Rect(FX - 3, FY - 3, FX + 3, FY + 3); against 5.
Find the best time to capture the canvas and use it as a cache to draw these small box's.

Hope that helps.
Kas
  Mit Zitat antworten Zitat