views:

143

answers:

3

I have an app that has a ton of controls on it. And it has a massive amount of flicker, particularly on startup.

I applied the fix to it.

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
            return cp;
        }
    } 

This worked great - the flickering was reduced by a pretty unbelievable amount. However, the side effect is that the Minimize, Maximize and the Close buttons in the top right of the window don't animate when I move the mouse over or click on them (they still work though). This gives the app a hung feel.

How do I keep the WS_EX_COMPOSITED while still retaining the usability of Maximize, Minimize and Close buttons.

This happens on Wnidows XP. As @fallenidol pointed out, this is not an issue on Windows 7.

A: 

Your should try standard windows forms control property called DoubleBuffered. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx

Kru
That only works on a per-control basis. The example I provided forces double-buffering onto every control on the form.
AngryHacker
You can use reflection at the start of the app to fill this property of every control.
Kru
@Kru I can't do it for the 3rd party controls that don't expose this property.
AngryHacker
Hmmm, any third party control has to be inherited from Windows.Forms.Control. Even if this property is closed, you can use reflection to access any private or protected property as well.
Kru
+1  A: 

Try the following code. This should go in the main form and any other custom user controls you have.

        // Enable double duffering to stop flickering.
        this.SetStyle(ControlStyles.DoubleBuffer, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.SupportsTransparentBackColor, false);
        this.SetStyle(ControlStyles.Opaque, false);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.ResizeRedraw, true);
fallenidol
The whole point of the code I posted is that you do this once, not for every single user control (which there are hundreds + a ton of 3rd party controls).
AngryHacker
This is another option for other people seeing this page who might not have access to the whole app and are just developing a user control in isolation.Next time you are developing a single user control you can use my code snippet above. Then you might not end up in a situation where you have hundreds of flickering controls.
fallenidol
+1  A: 

I figured it out. The trick is to remove the WS_EX_COMPOSITED flag after the form is shown. The full explanation and code at my blog:

How to get rid of flicker on Windows Forms applications

AngryHacker