问题是:闪屏的很厉害(尤其是在XP中,2000还不是很明显),我在程序中用了双缓冲啊,可是效果依旧,是不是我的程序有问题啊,希望大家能帮帮忙,看看程序。using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing.Drawing2D;namespace Test
{
/// <summary>
/// ActiveForm 的摘要说明。
/// </summary>
public class ActiveForm : System.Windows.Forms.Form
{
private Point np=new Point(0,0);//记录矩形的右下角的点
private Point op=new Point(0,0);//记录矩形的左上角的点
private Point om;//记录移动矩形时上次的点 private Boolean blLeftDown=false;
private Boolean blCanSelect=true;
private int RBTime=0;
public static Bitmap newImage; public ActiveForm()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
SetStyle(ControlStyles.DoubleBuffer, true);   
UpdateStyles();
this.BackgroundImage=Image.FromFile("c:\\test.jpg");
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{ }
base.Dispose( disposing );
} /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main() 
{

Application.Run(new ActiveForm());
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
// 
// ActiveForm
// 
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 273);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "ActiveForm";
this.Text = "ActiveForm";
this.TopMost = true;
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ActiveForm_MouseDown);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ActiveForm_MouseUp);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.ActiveForm_Paint);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ActiveForm_MouseMove); }
#endregion private void ActiveForm_MouseMove(object sender,System.Windows.Forms.MouseEventArgs e)
{
//改变鼠标的形状
if(e.X>op.X&&e.X<np.X&&e.Y>op.Y&&e.Y<np.Y)
{
this.Cursor=Cursors.SizeAll;

if(e.Button==MouseButtons.Left)//移动选择的矩形
{

op.X+=(MousePosition.X-om.X);
op.Y+=(MousePosition.Y-om.Y);
np.X+=(MousePosition.X-om.X);
np.Y+=(MousePosition.Y-om.Y);

om=MousePosition;
this.Invalidate();
}
}
else
{
this.Cursor=Cursors.Cross;
//鼠标左键按下并且处于可选定状态
if(e.Button==MouseButtons.Left&&blCanSelect==true)
{
this.blLeftDown=true;
//om=MousePosition;
this.Invalidate();
np=MousePosition;

}
}

} private void ActiveForm_MouseDown(object sender,  System.Windows.Forms.MouseEventArgs e)
{
//处于可选定状态时
if(e.Button==MouseButtons.Left&&blCanSelect==true)
{
op=MousePosition;
RBTime=0;
}
else if(e.Button==MouseButtons.Left)
{
om=MousePosition;
}
//鼠标右键按下时
if(e.Button==MouseButtons.Right)
{
if(blLeftDown==false)
{
this.Close();
}
blLeftDown=false;
blCanSelect=true;
RBTime++;
if(RBTime==2)
{
this.Close();
}
else
{
op.X=0;
op.Y=0;
np.X=0;
np.Y=0;
this.Invalidate();
}
} //鼠标指针在矩形区域内时
if(e.X>op.X&&e.X<np.X&&e.Y>op.Y&&e.Y<np.Y)
{
this.Cursor=Cursors.SizeAll;
}
else
{
this.Cursor=Cursors.Cross;
}
} private void ActiveForm_MouseUp(object sender,  System.Windows.Forms.MouseEventArgs e)
{
//当选定区域后,鼠标左键松开时
if(this.blLeftDown&&blCanSelect==true)
{
blCanSelect=false;
//op=MousePosition;
//this.Invalidate();
}
} private void ActiveForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{ Graphics display=e.Graphics;

Bitmap i=new Bitmap(ClientRectangle.Width,ClientRectangle.Height);
Graphics gTemp=Graphics.FromImage(i); Pen p=new Pen(Color.Red);
p.DashStyle=DashStyle.Dash;

Rectangle r=new Rectangle(op.X,op.Y,np.X-op.X,np.Y-op.Y);
gTemp.DrawRectangle(p,r);
display.DrawImage(i,ClientRectangle); p.Dispose();
i.Dispose();
gTemp.Dispose();

display.Dispose();

}
}
}

解决方案 »

  1.   

    可能是你多次同时调用this.Invalidate();重绘所致.
    还有像:
    Pen p=new Pen(Color.Red);
    p.DashStyle=DashStyle.Dash;
    不要放Paint中,可做为模块级变量并在public ActiveForm()中初始化.这样就不需要总是实例化和释放了.
      

  2.   

    首先你的双缓冲用的就不对,你看看使用双缓冲的帮助说明吧,除了这个SetStyle(ControlStyles.DoubleBuffer, true);  
    还得使用个样式才真正启动了双缓冲
      

  3.   

    To 3tzjq(永不言弃):
    可能是你多次同时调用this.Invalidate();重绘所致me:我重绘的部分基本上是左拽鼠标时发生的,而且没有发现同时调用~还有像:
    Pen p=new Pen(Color.Red);
    p.DashStyle=DashStyle.Dash;
    不要放Paint中,可做为模块级变量并在public ActiveForm()中初始化.这样就不需要总是实例化和释放了.me:谢谢提醒啊,我已经改了,可以效果依旧,我哭~~to liujiwe79(专业做控件) :
    首先你的双缓冲用的就不对,你看看使用双缓冲的帮助说明吧,除了这个SetStyle(ControlStyles.DoubleBuffer, true);  
    还得使用个样式才真正启动了双缓冲me:除了这个,还要改哪些地方~~
      

  4.   

    to kkun_3yue3(把握生命里的每一分钟) :
    我还是刚刚学GDI+呢,只是想实现动态选定某个区域,可以闪屏确实太烦人呢,使用2000的人还不怎么感觉得到,可是到了XP中,那就太明显了,眼睛实在是受不了啊,希望高手门来指导一下!!!
      

  5.   

    具我分析:造成闪烁的原因是在Paint事件中频繁开辟内存空间导致耗用CPU太多
    Bitmap i = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
    位图放到Paint外绘制如果只是绘制一个框,有必要需要一个和窗体一样大的位图吗?
      

  6.   

    to zswang(伴水清清)(专家门诊清洁工) :具我分析:造成闪烁的原因是在Paint事件中频繁开辟内存空间导致耗用CPU太多
    Bitmap i = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
    位图放到Paint外绘制me:一语惊醒梦中人啊,我是看了别人怎么使用双缓冲才用了,i,gTemp,没有想到反而起了副作用,现在已经没有闪屏的现象了,不过对于在什么情况下使用,希望能给点意见,谢谢!!!
      

  7.   

    贴出修改后的代码:
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Drawing.Drawing2D;namespace Test
    {
    /// <summary>
    /// ActiveForm 的摘要说明。
    /// </summary>
    public class ActiveForm : System.Windows.Forms.Form
    {
    private Point np=new Point(0,0);//记录矩形的右下角的点
    private Point op=new Point(0,0);//记录矩形的左上角的点
    private Point om;//记录移动矩形时上次的点 private Boolean blLeftDown=false;
    private Boolean blCanSelect=true;
    private int RBTime=0;
    private Pen p; public ActiveForm()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent();
    p=new Pen(Color.Red);
    p.DashStyle=DashStyle.Dash;
    this.BackgroundImage=Image.FromFile("c:\\test.jpg");
    //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    { }
    base.Dispose( disposing );
    } /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main() 
    {

    Application.Run(new ActiveForm());
    }
    #region Windows 窗体设计器生成的代码
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    // 
    // ActiveForm
    // 
    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
    this.ClientSize = new System.Drawing.Size(292, 273);
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    this.Name = "ActiveForm";
    this.Text = "ActiveForm";
    this.TopMost = true;
    this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
    this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ActiveForm_MouseDown);
    this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ActiveForm_MouseUp);
    this.Paint += new System.Windows.Forms.PaintEventHandler(this.ActiveForm_Paint);
    this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ActiveForm_MouseMove); }
    #endregion private void ActiveForm_MouseMove(object sender,System.Windows.Forms.MouseEventArgs e)
    {
    //改变鼠标的形状
    if(e.X>op.X&&e.X<np.X&&e.Y>op.Y&&e.Y<np.Y)
    {
    this.Cursor=Cursors.SizeAll;
    }
    else
    {
    this.Cursor=Cursors.Cross;
    } //鼠标左键按下并且处于可选定状态
    if(e.Button==MouseButtons.Left&&blCanSelect==true)
    {
    this.blLeftDown=true;
    np=MousePosition;
    this.Invalidate();

    }
    else if(e.Button==MouseButtons.Left)//移动选择的图形区域
    {
    op.X+=(MousePosition.X-om.X);
    op.Y+=(MousePosition.Y-om.Y);
    np.X+=(MousePosition.X-om.X);
    np.Y+=(MousePosition.Y-om.Y);

    om=MousePosition;
    this.Invalidate();
    }

    } private void ActiveForm_MouseDown(object sender,  System.Windows.Forms.MouseEventArgs e)
    {
    //处于可选定状态时
    if(e.Button==MouseButtons.Left&&blCanSelect==true)
    {
    op=MousePosition;
    RBTime=0;
    }
    else if(e.Button==MouseButtons.Left)
    {
    om=MousePosition;
    }
    //鼠标右键按下时
    if(e.Button==MouseButtons.Right)
    {
    if(blLeftDown==false)
    {
    this.Close();
    }
    blLeftDown=false;
    blCanSelect=true;
    RBTime++;
    if(RBTime==2)
    {
    this.Close();
    }
    else
    {
    op.X=0;
    op.Y=0;
    np.X=0;
    np.Y=0;
    this.Invalidate();
    }
    } //鼠标指针在矩形区域内时
    if(e.X>op.X&&e.X<np.X&&e.Y>op.Y&&e.Y<np.Y)
    {
    this.Cursor=Cursors.SizeAll;
    }
    else
    {
    this.Cursor=Cursors.Cross;
    }
    } private void ActiveForm_MouseUp(object sender,  System.Windows.Forms.MouseEventArgs e)
    {
    //当选定区域后,鼠标左键松开时
    if(this.blLeftDown&&blCanSelect==true)
    {
    blCanSelect=false;
    this.Invalidate();
    }
    } private void ActiveForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    { Graphics display=e.Graphics;
    Rectangle r=new Rectangle(op.X,op.Y,np.X-op.X,np.Y-op.Y);
    display.DrawRectangle(p,r);
    display.Dispose();

    }
    }
    }
      

  8.   

    参考我写的这个方块,刷新的频率也是很高的,利用贴位图实现http://download.csdn.net/source/162553