Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flickering in a Windows Forms app

Tags:

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 this 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 Windows XP. As @fallenidol pointed out, this is not an issue on Windows 7.

like image 445
AngryHacker Avatar asked Jul 20 '10 01:07

AngryHacker


2 Answers

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

like image 129
AngryHacker Avatar answered Sep 24 '22 09:09

AngryHacker


I know this question is a little old, but better late than never. I used your original example you linked to come up with one that toggles it on when resizing, then toggles it back off to draw everything else perfectly. Hopefully it helps others searching for a solution to this problem. As the OP knows, DoubleBuffering alone properties don't solve flickering issues.

Here's a work-around to stop flickering when a user resizes a form, but without messing up the drawing of controls such as DataGridView, NumericUpDown, etc. Provided your form name is "Form1":

int intOriginalExStyle = -1; bool bEnableAntiFlicker = true;  public Form1() {     ToggleAntiFlicker(false);     InitializeComponent();     this.ResizeBegin += new EventHandler(Form1_ResizeBegin);     this.ResizeEnd += new EventHandler(Form1_ResizeEnd); }  protected override CreateParams CreateParams {     get     {         if (intOriginalExStyle == -1)         {             intOriginalExStyle = base.CreateParams.ExStyle;         }         CreateParams cp = base.CreateParams;          if (bEnableAntiFlicker)         {             cp.ExStyle |= 0x02000000; //WS_EX_COMPOSITED         }         else         {             cp.ExStyle = intOriginalExStyle;         }          return cp;     } }   private void Form1_ResizeBegin(object sender, EventArgs e) {     ToggleAntiFlicker(true); }  private void Form1_ResizeEnd(object sender, EventArgs e) {     ToggleAntiFlicker(false); }  private void ToggleAntiFlicker(bool Enable) {     bEnableAntiFlicker = Enable;     //hacky, but works     this.MaximizeBox = true; } 
like image 28
John Suit Avatar answered Sep 25 '22 09:09

John Suit