21

When resizing a form with many controls, the form looks bad because of flickering. What are some tips to have a smoother form resizing?

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
zz1433
  • 3,528
  • 2
  • 28
  • 36

5 Answers5

17
procedure TForm1.WMEnterSizeMove(var Message:TWMMove);
begin
  Self.DisableAlign;
end;

procedure TForm1.WMExitSizeMove(var Message:TWMMove);
begin
  Self.EnableAlign;
end;
JosephStyons
  • 57,317
  • 63
  • 160
  • 234
A. Vrbic
  • 186
  • 2
  • That's fine at preventing flicker, but it also seems to prevent alignment altogether. I added an Invalidate call after enabling alignment: not perfect, because you cannot see exactly what effect the form resize is going to have, but at least it eliminates all flicker on a complex multi-panel form. – frogb Sep 23 '09 at 09:08
  • procedure WMEnterSizeMove(var Message:TWMMove); message WM_ENTERSIZEMOVE; procedure WMExitSizeMove(var Message:TWMMove); message WM_EXITSIZEMOVE; does not fire the aproporiate events. Actually forgot to mention it is a frame and not a form but I guessed that it would have been the same. – zz1433 Sep 23 '09 at 13:41
5

Try using WM_SETREDRAW (not LockWindowUpdate).

You might also have a look at DeferWindowPos.

Uli Gerhardt
  • 13,748
  • 1
  • 45
  • 83
  • 1
    +1, both very good pieces of advise in itself. These probably won't help with a complex VCL form using alignment, nested controls and so on, though. `DeferWindowPos()` is worth testing for manual placement in `OnResize` handler. – mghie Sep 21 '09 at 13:14
5

Complex forms are often made up of nested panels, and the repaint process may cause flickering. If this is the case with your project there are two easy solutions that might help:

  1. Disable the property FullRepaint on your panels.
  2. Enable the property DoubleBuffered on your form. You won't find this property on the object inspector, so put DoubleBuffered := true; in FormCreate.
Svein Bringsli
  • 5,640
  • 7
  • 41
  • 73
  • 1
    Note that `DoubleBuffered` trades less flicker for slower update speed, an effect that can be noticeable on large screens, where resizing may become "jumpy" with larger window sizes. – mghie Sep 21 '09 at 13:15
  • 1
    DoubleBuffered basically makes your app useless on Citrix and Terminal Server. – Jeroen Wiert Pluimers Sep 21 '09 at 16:24
  • 1
    >>> "DoubleBuffered basically makes your app useless on Citrix and Terminal Server" Can you specify why? – Alex Sep 21 '09 at 17:53
  • 1
    @Alexander: See the answers to http://stackoverflow.com/questions/1408664/why-is-doublebuffered-disabled-by-default – mghie Sep 21 '09 at 18:17
  • DoubleBuffered: see http://www.delphi3000.com/articles/article_1537.asp?SK= and http://stackoverflow.com/questions/1444830/does-anyone-know-about-issues-between-citrix-and-delphi-2007-applications-and-p – Jeroen Wiert Pluimers Sep 21 '09 at 19:08
  • @JeroenPluimers +1 for "paying your taxes" and detecting when you're in a terminal services session (e.g. Remote Desktop Connection) – Ian Boyd Dec 29 '11 at 00:24
1

I've got around this as follows:

  1. In the 'OnResize' event of the form, have a routine to hide all child controls and then start a timer with a tick of about 500ms.
  2. When the timer fires, disable it and then set all child controls to visible.

By playing around with this activity you get a form that goes blank whilst you are sizing it, but then populates itself neatly when you 'let go'.

Bri

Brian Frost
  • 13,334
  • 11
  • 80
  • 154
  • 1
    I think you would find that handling the enter/exit size move messages (with the modification noted in my comment above) produces a better user experience because you can at least see the (unsized) form while you resize the window. – frogb Sep 23 '09 at 09:11
0

I avoid flicker by aligning no more than 1 non-alClient component per parent, always paired with a alClient (e.g. a TPanel) to contain all other components. Group them in panels without borders.

Say you want to allign three things: alLeft, alTop and alClient for the main view. Dont do this: Form alTop alLeft alClient // your main view

But instead embed these as follows: Form alTop alClient // panel to avoid flicker alLeft alClient // your main view

Same story for embedding several alTop elements.

Barry Staes
  • 3,890
  • 4
  • 24
  • 30