1.窗体打开时防止窗体闪烁
//C# 窗体程序,窗体上控件过多,会导致打开程序时窗体闪烁,下面有个不错的方法
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
2.禁掉清除背景消息
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) // 禁掉清除背景消息
return;
base.WndProc(ref m);
}
3.设置双缓存
public Form1()
{
InitializeComponent();
//根据我的理解,每个窗体的这地方加上以下几行代码就行了
this.DoubleBuffered = true;//设置本窗体
//采用双缓冲技术的控件必需的设置
//SetStyle(ControlStyles.UserPaint, true);
//SetStyle(ControlStyles.ResizeRedraw, true);
//SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
//SetStyle(ControlStyles.SupportsTransparentBackColor, true);
//SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
//SetStyle(ControlStyles.EnableNotifyMessage, true);
//SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(
ControlStyles.UserPaint//使用自定义的绘制方式
| ControlStyles.ResizeRedraw//当控件大小发生变化时就重新绘制
| ControlStyles.DoubleBuffer// 双缓冲
| ControlStyles.SupportsTransparentBackColor//则控件接受 alpha 组件数小于 255 个的 BackColor 来模拟透明度
| ControlStyles.AllPaintingInWmPaint//禁止擦除背景.则控件忽略窗口消息 WM_ERASEBKGND 以减少闪烁
| ControlStyles.EnableNotifyMessage//
// Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
| ControlStyles.OptimizedDoubleBuffer//则控件将首先绘制到缓冲区而不是直接绘制到屏幕,这可以减少闪烁
, true);
}
4.界面重绘
Image curChartImage;//为当前控件/窗体生成截图
private void DrawRectBackImage(Control c, int xStart, int yStart, int Width, int Height)
{
Bitmap bit = new Bitmap(c.Width, c.Height);//实例化一个和窗体一样大的bitmap
Graphics g = Graphics.FromImage(bit);
g.CompositingQuality = CompositingQuality.HighQuality;//质量设为最高
g.CopyFromScreen(this.Location.X +8+ c.Left, this.Location.Y+30 + c.Top, 0, 0, new Size(c.Width, c.Height));//保存整个窗体为图片
curChartImage = bit;
}
在内存中绘好图之后,绘图到界面
int xStart = 150, yStart = 150, xWidth = 100, yHeight = 100;
//虚拟时钟
//在内存中保存图像,直接刷新到界面
double num = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (curChartImage == null)
{
DrawRectBackImage(panel1, xStart, yStart, 2 * xWidth, 2 * yHeight);
}
if (panel1.Width == 0)
return;
Bitmap memoryCanvas = new Bitmap(panel1.Width, panel1.Height);
double x = xStart + xWidth * Math.Sin(num * Math.PI / 180);
double y = yStart - yHeight * Math.Cos(num * Math.PI / 180);
tsmi_tip.Text = Convert.ToString((num = num + 0.3));
Graphics memDc = Graphics.FromImage(memoryCanvas);
memDc.SmoothingMode = SmoothingMode.HighQuality;
memDc.DrawImage(curChartImage, 0, 0, panel1.Width, panel1.Height);
Pen p1 = new Pen(Color.Black, 1);
memDc.DrawLine(p1, (float)xStart, (float)yStart, (float)x, (float)y);
Graphics g = panel1.CreateGraphics();
g.DrawImage(memoryCanvas, xStart, yStart - 20, 2 * xWidth, 2 * yHeight);
panel1.BackgroundImage = memoryCanvas;
memDc.Dispose();
}