2011-02-04 3 views
3

J'ai reçu le code de http://support.microsoft.com/kb/314945 pour dessiner un rectangle réversible. J'ai ajouté du code pour que, lorsque je laisse le bouton gauche de la souris, un rectangle soit également créé sur l'image et que je l'utilise pour recadrer l'image.Dessin rectangle réversible

Cela fonctionne parfaitement. le seul problème est que le rectangle en caoutchouc ne commence pas ou ne se termine pas à l'endroit où se trouve la souris ... il y a très peu de différence mais c'est quand même assez remarquable. J'utilise les mêmes coordonnées pour dessiner le rectangle après lequel est dessiné exactement où ma souris a commencé et où est terminée. l'aide serait appréciée.

Voici le code: (Problème résolu - ajout de code pour que d'autres puissent en bénéficier) J'en ai fait un contrôle et je l'utilise partout où j'en ai besoin!

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

Pourriez-vous ajouter un nouveau code? Comment avez-vous obtenu les coordonnées de la souris, comment utilisez-vous ces coordonnées? –

+0

l'exemple de code a-t-il fonctionné sans la petite différence? Si c'est le cas, veuillez poster votre code afin que l'on puisse voir où la différence se produit. – Gambrinus

Répondre

2

ControlPaint.DrawReversibleFrame utilise écran les coordonnées pour dessiner un rectangle sur l'écran (à savoir sans égard aux fenêtres de votre application) qui est utile pour agir sur les actions de la souris de glisser que la souris peut se déplacer en dehors de la fenêtre de l'application. Si vous utilisez ces mêmes coordonnées brutes pour peindre dans votre application, alors elles seront hors comme les coordonnées sur le contrôle sur lequel vous peignez sont par rapport à l'origine du contrôle (généralement son coin en haut à gauche) . Pour utiliser les coordonnées de l'écran, vous devez d'abord les convertir en coordonnées de contrôle en utilisant les méthodes PointToClient() ou RectangleToClient() sur la commande sur laquelle vous peignez, par ex.

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

c'est le code que j'utilise public partielle classe Form2: Formulaire { Rectangle rc = new Rectangle(); Boolean bHaveMouse; Point ptOriginal = new Point(); Point ptLast = new Point(); PictureBox pic = null; Forme formulaire 1; Formulaire public2 (Form1 form1, PictureBox picturebox) pic = imagebox; pictureBox1.Image = picturebox.Image; forme = forme1; } – Umar

+0

Je suis nouveau sur ce site ... le code est assez long et je ne peux pas tout coller dans la boîte de commentaire ... mais je n'ai pas beaucoup changé le code et le problème est aussi à 20 pixels de l'endroit où je clique ... – Umar

+0

Tout d'abord, je vous remercie tous pour l'aide :-) Je viens de vérifier le code ... il n'y a pas de problème dans le code fourni dans le lien Microsoft ... le problème est dans mon code ... la différence est que le code fourni dessine un rectangle sur le formulaire et je l'ai changé pour dessiner sur la photo. Y at-il un moyen que je puisse coller tout mon code ici ?? – Umar