简单的说就是鼠标左键先按下,然后移动鼠标,就会出现一个矩形的以选择范围,就像windows里的操作一样,现在我已经基本可以实现这个功能,就是用GDI+画的那个矩形的边框一直在闪,我已经用了如双缓冲等技术,但还是闪的利害,请各位高手帮帮忙!
基本代码如下:        bool isChoose;
        int mouseX;
        int mouseY;
        Graphics myGraphics;
        Image bitmap;
public FrmAG()
        {
            InitializeComponent();
            bitmap = new Bitmap(this.Width, this.Height);
            myGraphics = Graphics.FromImage(bitmap);
            this.DoubleBuffered = true;
            SetStyle(ControlStyles.ResizeRedraw, true);
        }
private void FrmAG_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isChoose = true;
                mouseX = e.X;
                mouseY = e.Y;
            }
        }        private void FrmAG_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isChoose = false;
                Invalidate();
            }
        }        private void FrmAG_MouseMove(object sender, MouseEventArgs e)
        {
            if (isChoose)
            {
                myGraphics.DrawRectangle(new Pen(Color.Blue, 2), lastX, lastY, lastWidth, lastHeight);
                myGraphics.Clear(Color.Empty);                int width;
                int height;
                int x;
                int y;                if (mouseX < e.X)
                {
                    x = mouseX;
                    width = e.X - mouseX;
                }
                else
                {
                    x = e.X;
                    width = mouseX - e.X;
                }                if (mouseY < e.Y)
                {
                    y = mouseY;
                    height = e.Y - mouseY;
                }
                else
                {
                    y = e.Y;
                    height = mouseY - e.Y;
                }                lastHeight = height;
                lastWidth = width;
                lastX = x;
                lastY = y;                myGraphics.DrawRectangle(new Pen(Color.Blue, 2), x, y, width, height);
                this.Invalidate();                
}
        }        private void FrmAG_Paint(object sender, PaintEventArgs e)
        {
            if (isChoose == true)
            {
                Graphics graphics = this.CreateGraphics();
                graphics.DrawImage(bitmap, 0, 0);
            }
        }不管大家用gdi+、gdi或者api等什么技术都可以,只要能实现功能就好了,请大家多多指点!

解决方案 »

  1.   

    参考下这个代码(可以把代码直接放到一个Form上运行看效果):private Point m_LastPoint;
    private Point m_StartPoint;
    protected override void OnMouseDown(MouseEventArgs e)
    {
    base.OnMouseDown(e);
    this.m_StartPoint = e.Location;
    this.m_LastPoint = this.m_StartPoint;
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
    base.OnMouseMove(e);
    if (this.Capture)
    {
    Rectangle oldRect = Rectangle.FromLTRB(m_StartPoint.X, m_StartPoint.Y, this.m_LastPoint.X, this.m_LastPoint.Y);
    oldRect = this.RectangleToScreen(oldRect);
    ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed); Rectangle rect = Rectangle.FromLTRB(m_StartPoint.X, m_StartPoint.Y, e.X, e.Y);
    rect = this.RectangleToScreen(rect);
    ControlPaint.DrawReversibleFrame(rect, Color.Black, FrameStyle.Dashed);
    this.m_LastPoint = e.Location;
    }
    }
    protected override void OnMouseUp(MouseEventArgs e)
    {
    base.OnMouseUp(e);
    Rectangle oldRect = Rectangle.FromLTRB(m_StartPoint.X, m_StartPoint.Y, this.m_LastPoint.X, this.m_LastPoint.Y);
    oldRect = this.RectangleToScreen(oldRect);
    ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed);
    }
      

  2.   

    这儿对你有所帮助
    http://blog.csdn.net/wzuomin/archive/2006/12/13/1441007.aspx
      

  3.   

    如果确实需要在控件内绘制,可以这样来做(仅供参考):
    public partial class Form1 : Form
    {
    private Point m_LastPoint;
    private Point m_StartPoint;
    private Rectangle m_Rect;
    public Form1()
    {
    InitializeComponent();
    this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
    } protected override void OnMouseDown(MouseEventArgs e)
    {
    base.OnMouseDown(e);
    this.m_StartPoint = e.Location;
    this.m_LastPoint = this.m_StartPoint;
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
    base.OnMouseMove(e);
    if (this.Capture)
    {
    m_Rect = Rectangle.FromLTRB(m_StartPoint.X, m_StartPoint.Y, this.m_LastPoint.X, this.m_LastPoint.Y);
    this.m_LastPoint = e.Location;
    this.Invalidate();
    }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
    base.OnPaint(e);
    if (this.m_Rect != Rectangle.Empty)
    {
    e.Graphics.DrawRectangle(SystemPens.ControlText, this.m_Rect);
    }
    }
    protected override void OnMouseUp(MouseEventArgs e)
    {
    base.OnMouseUp(e);
    this.m_Rect = Rectangle.Empty;
    this.Invalidate();
    }
    }
      

  4.   

    去掉Paint事件把Move事件代码改为如下
    System.IntPtr DesktopHandle = GetDC(this.Handle);
    Graphics g = Graphics.FromHdc(DesktopHandle);
    g.DrawRectangle(new Pen(Color.Blue, 2), lastX, lastY, lastWidth, lastHeight);
    g.Clear(Color.FromName("control"));
    int width;
    int height;
    int x;
    int y;

    g.DrawRectangle(new Pen(Color.Blue, 2), x, y, width, height);
    去掉Invalidate引用API
    [DllImport("User32.dll")]
            public extern static System.IntPtr GetDC(System.IntPtr hWnd);
      

  5.   

    谢谢大家
    我的问题解决了
    用的是ControlPaint.DrawReversibleFrame方法
    这个效果比较好