Search code examples
delphic++builderc++builder-10.4-sydney

Prevent TPaintBox flicker when resizing


I have a TFrame with some controls, and a TPanel which is a container for a TPaintBox where I draw video.

When I resize the frame, the image on the paintbox flickers because of the infamous background erasing.

I googled for hours and tried everything (setting the PaintBox's ControlStyle to csOpaque, setting the panel's Brush to bsClear, changing the panel to double buffered, setting the panel's FullRepaint to false, etc) but the only thing that does the trick is intercepting the WM_ERASEBKGND message in my frame:

void __fastcall TFrameSample::WndProc(TMessage &Message)
{
    if (Message.Msg == WM_ERASEBKGND)
        Message.Result = 1;
    else
        TFrame::WndProc(Message);
}

However, this means nothing is being redrawn, including the frame's title bar and all its controls.

I know this is a very common problem, is there a solution at all?


Solution

  • Found the answer in an old post by Remy Lebeau, see http://www.delphigroups.info/2/81/414040.html

    There are several different ways to intercept messages on a per-control. Deriving a new class is only one of them. You could also subclass just the WindowProc property of an existing object instance. For example:

    private
        OldWndMethod: TWndMethod;
        procedure PanelWndProc(var Message: TMessage);
    constructor TForm1.Create(AOwner: TComponent);
    begin
        inherited Create(AOwner);
        OldWndMethod := Panel1.WindowProc
        Panel1.WindowProc := PanelWndProc;
    end;
    procedure TForm1.PanelWndProc(var Message: TMessage);
    begin
        if Message.Msg = WM_ERASEBKGND then
        begin
            //...
        end else
            OldWndMethod(Message);
    end;