Flickering in a Windows Forms app

主宰稳场 提交于 2019-11-26 16:24:09

问题


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.


回答1:


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




回答2:


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;
}



回答3:


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);



回答4:


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




回答5:


I just came across this post and realize it is a little old. However, I am having the same issue with my form and discovered (for XP, anyway) an inelegant solution seems to be not enabling visual styles.



来源:https://stackoverflow.com/questions/3286373/flickering-in-a-windows-forms-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!