我现在想做一个用来在图像上选择用的徒有矩形框(就是按住鼠标拖出一个矩形,在VC++中叫CRectTracker),我用了两种方法
1)先画出背景图.每移动一下鼠标改变选择矩形大小,并对需要重画的区域调用Invalidate.结果是闪烁严重
2)我把图形设成窗体的BackgroundImage,然后做上面的动作,不闪烁了,但移动时处理特别慢,感觉拖动不连贯.
不知道各们大侠是怎么为的?

解决方案 »

  1.   

    试试这个吧,管用using System;
    using System.Windows.Forms;
    using System.Drawing;namespace CaptureScreen
    {
    /// <summary>
    /// Rubberband 的摘要说明。
    /// 实现选择框的功能
    /// </summary>
    public class Rubberband
    {
    protected Control parent;
    private Point lastLeftTop = new Point();
    private Point lastRightBottom = new Point();
    private Point startPoint;
    public  Rectangle rect = Rectangle.Empty; public Rubberband(Control theParent, Point theStartingPoint)
    {
    this.startPoint = theStartingPoint;
    parent = theParent;
    parent.Capture = true;
    Cursor.Clip = parent.RectangleToScreen(parent.ClientRectangle);
    rect = new Rectangle(this.startPoint.X, this.startPoint.Y, 0, 0);
    } public Point SelectedLT
    {
    get{return this.startPoint;}
    set{this.startPoint = value;}
    } public Point SelectedRB
    {
    get{return this.lastRightBottom;}
    } public Point LeftTop
    {
    get{return rect.Location;}
    } public void End()
    {
    Cursor.Clip = Rectangle.Empty;
    parent.Capture = false; // erase the rubberband
    //Draw();
    rect = Rectangle.Empty;
    } public void Move(Point thePoint,int distX,int distY,Point startPoint)
    {
    rect.Location = new Point(thePoint.X - distX,thePoint.Y - distY);
    this.startPoint = rect.Location;
    //rect.Location = new Point(rect.Location.X + (thePoint.X - startPoint.X),rect.Location.Y + thePoint.Y - startPoint.Y);
    Draw();
    } public void ResizeTo(Point thePoint)
    {
    // erase the old rubberband
    Draw(); // get the new size of the rubberband
    rect.Width =  thePoint.X - rect.Left;
    rect.Height = thePoint.Y - rect.Top; // draw the new rubberband
    Draw();
    } public void Stop(Point thePoint,int distX,int distY)
    {
    rect.Location = new Point(thePoint.X - distX,thePoint.Y - distY);
    //this.startPoint = rect.Location;
    //rect = Bounds();
    Draw();
    } public Rectangle Bounds()
    {
    // return a normalized rectangle, i.e. a rect
    // where (left <= right) and (top <= bottom)
    if ( (rect.Left > rect.Right) || (rect.Top > rect.Bottom) )
    {
    int left = Math.Min(rect.Left, rect.Right);
    int right = Math.Max(rect.Left, rect.Right);
    int top = Math.Min(rect.Top, rect.Bottom);
    int bottom = Math.Max(rect.Top, rect.Bottom); /*
    this.lastLeftTop = new Point(left,top);
    this.lastRightBottom = new Point(right,bottom);
    */ return Rectangle.FromLTRB(left, top, right, bottom);
    } return rect;
    } // Reversible drawing method
    // Calling theis method the first time draws the rubberband.
    // Calling it a second time with the same rect erases the rubberband
    protected void Draw()
    {
    Rectangle r = parent.RectangleToScreen(rect);
    //Rectangle r = parent.RectangleToScreen(rect);
    ControlPaint.DrawReversibleFrame(r, Color.Black ,FrameStyle.Dashed);
    //ControlPaint.DrawReversibleFrame(r, Color.Black, FrameStyle.Dashed);
    }
    }
    }