0
votes

When I look at TWinControl, the Canvas is blanked out with clBtnFace and then the WM_PAINT is called. This causes an unavoidable flicker that I do not need. Also the canvas given allows drawing over the scroll bars making the scroll bars to be redrawn after a WM_PAINT event and creating more flicker.

GetMetrics and internal scrollbar Info gives the true canvas size. Correct me if I'm wrong, but I understand an HDC is a handle on the form that has a rectangular canvas to print on. So I'm thinking:

  1. how do I create a new HDC with a smaller width and height and not move the Top Left corner. I want to remove flicker by not using a WM_ERASEBKGND message if possible and not printing over scrollbars by allocating a newly sized HDC and then to set the Delphi canvas handle with the correct HDC.

  2. using a windows bitmap that I do not know if I should use and set the Bitmap canvas size for a BitBlt() copy as, TWinControl (Below).

    DC := GetDC(0);
    MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
    ReleaseDC(0, DC);
    MemDC := CreateCompatibleDC(0);
    OldBitmap := SelectObject(MemDC, MemBitmap);
    try
      DC := BeginPaint(Handle, PS);
      Perform(WM_ERASEBKGND, MemDC, MemDC);
      Message.DC := MemDC;
      WMPaint(Message);
      Message.DC := 0;
      BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
      EndPaint(Handle, PS);
    finally
      SelectObject(MemDC, OldBitmap);
      DeleteDC(MemDC);
      DeleteObject(MemBitmap);
    end;
    

I do not know what option is better in a flicker free result and how to implement it in Delphi.

1
So you are writing a custom TWinControl and the blob of code you are showing is the paint method? How about you make this question a bit clearer, it's a mess. Or are you painting in a Paintbox?Warren P
You are overthinking things. If what you said were true, all standard controls would have bad flickering as you have described. That is simply not true. Whatever is causing your flicker issue is likely in your own drawing code, not in how TWinControl manages its Canvas. Please show your actual code that you are having trouble with.Remy Lebeau
We need a minimal reproducible example to give you helpDavid Heffernan

1 Answers

1
votes

...the Canvas is blanked out with clBtnFace...

The background color is adjustable with setting Brush.Color.

and then the WM_PAINT is called. This causes an unavoidable flicker...

This can be prevented by by-passing the WM_ERASEBKGND message.

How do I create a new HDC with a smaller width and height?

That is not possible. A device context has no size. It is only limitted by the window which hosts it.

The canvas given allows drawing over the scroll bars making the scroll bars to be redrawn after a WM_PAINT event.

Native scroll bars are drawn by the system in WM_NCPAINT. If you can draw over them, then you have gotten a device context of the whole window, not its client space.

But overall speaking, the solution is really simple: do not draw beyond the client region of a window.

And as a tip: I suggest that you derive your control from TCustomControl instead of TWinControl because that class has already a canvas you can draw on which eliminates all your WinAPI code.