2011-02-04 133 views
3

我从http://support.microsoft.com/kb/314945得到了代码来绘制一个可逆/橡皮筋矩形。我向它添加了代码,这样当我离开鼠标左键时,图像上也会创建一个矩形,然后用它来剪裁图像。绘制可逆矩形

此作品非常棒。唯一的问题是,橡皮圈的矩形不会从鼠标所在的位置开始或结束......这种差异很小,但仍然非常值得注意。之后我使用相同的合作伙伴绘制矩形,这正是我的鼠标开始和结束的地方。帮助将不胜感激。

这里是代码:(已修复问题 - 添加代码,其他人可以从中受益) 我已经使它成为控件,我在任何需要它的地方使用它!

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Data; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace CroppingControl 
{ 
    public partial class CroppingImage : UserControl 
    { 
     Rectangle rc = new Rectangle(); 
     Boolean bHaveMouse; 
     Point ptOriginal = new Point(); 
     Point ptLast = new Point(); 
     Image Pic; 

     public CroppingImage() 
     { 
      InitializeComponent(); 
      pictureBox1.MouseDown += new MouseEventHandler(MyMouseDown); 
      pictureBox1.MouseUp += new MouseEventHandler(MyMouseUp); 
      pictureBox1.MouseMove += new MouseEventHandler(MyMouseMove); 
      bHaveMouse = false; 
     } 


     public Image Image 
     { 
      set 
      { 
       pictureBox1.Image = value; 
       Pic = value; 
      } 
      get 
      { 
       return pictureBox1.Image; 
      } 
     } 

     public void MyMouseDown(Object sender, MouseEventArgs e) 
     { 
      pictureBox1.Image = Pic; 
      // Make a note that we "have the mouse". 

      bHaveMouse = true; 
      // Store the "starting point" for this rubber-band rectangle. 
      ptOriginal.X = e.X; 
      ptOriginal.Y = e.Y; 
      // Special value lets us know that no previous 
      // rectangle needs to be erased. 
      ptLast.X = -1; 
      ptLast.Y = -1; 
     } 

     // Convert and normalize the points and draw the reversible frame. 
     private void MyDrawReversibleRectangle(Point p1, Point p2) 
     { 
      Point px = p1; 
      Point py = p2; 

      // Convert the points to screen coordinates. 
      p1 = PointToScreen(p1); 
      p2 = PointToScreen(p2); 
      // Normalize the rectangle. 
      if (p1.X < p2.X) 
      { 
       rc.X = p1.X; 
       rc.Width = p2.X - p1.X; 
      } 
      else 
      { 
       rc.X = p2.X; 
       rc.Width = p1.X - p2.X; 
      } 
      if (p1.Y < p2.Y) 
      { 
       rc.Y = p1.Y; 
       rc.Height = p2.Y - p1.Y; 
      } 
      else 
      { 
       rc.Y = p2.Y; 
       rc.Height = p1.Y - p2.Y; 
      } 
      // Draw the reversible frame. 
      ControlPaint.DrawReversibleFrame(rc, Color.Black, FrameStyle.Dashed); 

      rc.X = px.X; 
      rc.Y = px.Y; 

     } 
     // Called when the left mouse button is released. 
     public void MyMouseUp(Object sender, MouseEventArgs e) 
     { 
      // Set internal flag to know we no longer "have the mouse". 
      bHaveMouse = false; 
      // If we have drawn previously, draw again in that spot 
      // to remove the lines. 
      if (ptLast.X != -1) 
      { 
       Point ptCurrent = new Point(e.X, e.Y); 
       MyDrawReversibleRectangle(ptOriginal, ptLast); 
       Graphics graphics = pictureBox1.CreateGraphics(); 
       Pen pen = new Pen(Color.Gray, 2); 
       pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot; 
       graphics.DrawRectangle(pen, rc); 

      } 
      // Set flags to know that there is no "previous" line to reverse. 
      ptLast.X = -1; 
      ptLast.Y = -1; 
      ptOriginal.X = -1; 
      ptOriginal.Y = -1; 
     } 
     // Called when the mouse is moved. 
     public void MyMouseMove(Object sender, MouseEventArgs e) 
     { 
      Point ptCurrent = new Point(e.X, e.Y); 
      // If we "have the mouse", then we draw our lines. 
      if (bHaveMouse) 
      { 
       // If we have drawn previously, draw again in 
       // that spot to remove the lines. 
       if (ptLast.X != -1) 
       { 
        MyDrawReversibleRectangle(ptOriginal, ptLast); 
       } 
       // Update last point. 
       ptLast = ptCurrent; 
       // Draw new lines. 
       MyDrawReversibleRectangle(ptOriginal, ptCurrent); 
      } 
     } 

    } 
} 
+0

您可以添加一些代码吗?你是如何获得鼠标坐标的,你如何使用这些坐标? – 2011-02-04 08:33:16

+0

做了示例代码工作没有什么差别?如果是这样 - 请发布您的代码 - 这样可以看到差异发生的位置。 – Gambrinus 2011-02-04 08:42:49

回答

2

ControlPaint.DrawReversibleFrame采用屏幕坐标绘制在屏幕上的一个矩形(即,不相对于你的应用程序的窗口)在拖动鼠标操作充当鼠标可能外侧移动的应用程序窗口的时,这是有用的。如果您在应用程序中使用这些非常相同的原始坐标来绘制,那么它们将作为关于控件起源(通常是其左上角)的控件的坐标来展开, 。

要使用屏幕坐标,首先需要使用您正在绘制的控件上的PointToClient()RectangleToClient()方法将它们转换为控件坐标,例如,

// panel`s OnPaint 
Rectangle screenRectangle = ... 
Rectangle clientRectangle = panel.RectangleToClient(screenRectangle); 
graphics.DrawRectangle(Pens.Red, clientRectangle);