2011-02-04 132 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);