Bouger un Rectangle et une PictureBox ensemble

Résolu
cs_JLuc01 Messages postés 206 Date d'inscription samedi 17 janvier 2009 Statut Membre Dernière intervention 5 mars 2013 - 22 janv. 2013 à 23:20
cs_JLuc01 Messages postés 206 Date d'inscription samedi 17 janvier 2009 Statut Membre Dernière intervention 5 mars 2013 - 26 janv. 2013 à 00:32
Bonsoir,

Je voudrais dessiner un Rectangle, mettre une PictureBox a l'interieur et bouger les 2 ensemble.
Quel est la meilleure strategie pour arriver a bouger les 2 ensembles?

J'arrive a faire bouger une PictureBox avec "PictureBox.MouseMove" event.
J'arrive a faire bouger un Rectangle avec "MyBase.MouseMove" event et "MyBase.Paint" event.
Mais les faire bouger ensemble (dans une classe, sinon j'y arrive), je ne vois pas par quel bout m'y prendre.

En fait, j'essaye de creer une classe qui permettra d'instancier une PictureBox avec un Rectangle autour.
En d'autres termes, une classe permettant d'instancier un objet (= PictureBox + Rectangle).

Par exemple, dois-je creer une classe pour ma PictureBox, une classe pour mon Rectangle, faire un Inherit de mon Rectangle dans ma classe PictureBox ou bien je commence a raconter n'importe quoi!

En esperant avoir ete clair...
Comme toujours, toutes les idees sont les bienvenues.
Merci,

A+
JLuc01

21 réponses

cs_JLuc01 Messages postés 206 Date d'inscription samedi 17 janvier 2009 Statut Membre Dernière intervention 5 mars 2013 1
24 janv. 2013 à 20:48
Salut a tous,
Et merci pour les differentes options.

ucfoutu,
A vrai dire, j'ai vraiment besoin du Rectangle, car je prevois d'utiliser certaines proprietes du Rectangle plus tard.

Shaw,
J'ai essaye ta deuxieme version, si on met "Refresh" (ou encore "Update" suivi de "Invalidate") a la fin de DrawFrame, on se rapproche de l'objectif, mais ca clignote un peu trop. Il faut surement trouver la bonne syntaxe pour empecher ce clignotement, bref a creuser. Par contre le Rectangle n'est plus gere dans la Classe.
Pour l'option du rectangle dans la PictureBox, je crois qu'on peut y arriver avec les proprietes Padding et BackColor de la PictureBox. Mais, desole d'etre embetant, je prefere le Rectangle independant du PictureBox.

EhJoe,
Oui, le RectangleShape existe vraiment dans la ToolBox. D'ailleurs, je me demande quels sont les differences entre un RectangleShape et un Rectangle (cree en code), bref quelquechose a verifier.
En general, je dirais interessant et relativement simple. La PictureBox se coince dans le RectangleShape, mais il faut surement ajuster les valeurs Top, Left, Right et Bottom de la PictureBox par rapport au RectangleShape pour les bouger ensemble.
Je devrais pouvoir adapter tout cela a ma classe, bref je vais me pencher ce week-end sur le sujet. Autre chose a verifier: "PointToClient(Control.MousePoint)", car je ne suis pas sur de comprendre ce que ca fait exactement, bref je regarderais l'aide pour approfondir.

En tout cas, merci a tous, cela m'a ouvert d'autres options ou chemin a approfondir.
Je ferme le sujet, mais si vous avez d'autres idees ou commentaires, n'hesitez pas.
A+
JLuc01
3
ehjoe Messages postés 728 Date d'inscription samedi 4 avril 2009 Statut Membre Dernière intervention 30 mars 2014 4
23 janv. 2013 à 00:17
Bonjour,

Par exemple, dans ton évènement de mobilité de la pictureBox tu peux mettre par rapport à cette dernière : le left et le top de ton rectangle, ainsi il devrait suivre.

Cordialement, Joe.
0
cs_ShayW Messages postés 3253 Date d'inscription jeudi 26 novembre 2009 Statut Membre Dernière intervention 3 décembre 2019 57
23 janv. 2013 à 11:34
Salut

un truc de ce genre

 Public Class Frame
' The class sets an image and resizes the 'picturebox size matching
'the image size 
'It also moves itself onto the screen when the 'mousedown and mousemove event are raised   
    Inherits PictureBox

    Private lastmouselocation As New Point
    Public Property myimage() As Image
        Get
            Return Me.Image
        End Get
        Set(ByVal value As Image)
            Me.Image = value
            Me.Size = value.Size
        End Set
    End Property
    Private Sub DrawFrame(ByVal gr As System.Drawing.Graphics)
        gr.DrawRectangle(New Pen(Color.Blue, 3), Me.ClientRectangle)
    End Sub

    Private Sub Frame_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        lastmouselocation = New Point(e.Location)
    End Sub

    Private Sub Frame_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Left += e.Location.X - lastmouselocation.X
            Me.Top += e.Location.Y - lastmouselocation.Y
        End If
    End Sub

    Private Sub Frame_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        DrawFrame(e.Graphics)
    End Sub
End Class


Public Class Form1
Private myframe As New Frame

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
myframe.myimage = Image.FromFile(Application.StartupPath & "\im1.jpg")
myframe.Location = New Point(10, 10)
Me.Controls.Add(myframe)
End Sub
End Class
0
cs_ShayW Messages postés 3253 Date d'inscription jeudi 26 novembre 2009 Statut Membre Dernière intervention 3 décembre 2019 57
23 janv. 2013 à 11:35
Public Class Form1 
Private myframe As New Frame 

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
myframe.myimage = Image.FromFile(Application.StartupPath & "\im1.jpg") 
myframe.Location = New Point(10, 10) 
Me.Controls.Add(myframe) 
End Sub 
End Class
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_JLuc01 Messages postés 206 Date d'inscription samedi 17 janvier 2009 Statut Membre Dernière intervention 5 mars 2013 1
23 janv. 2013 à 22:55
Salut,

Shaw,
Merci pour le code, il marche tres bien.
Cependant, je voudrais dessiner le Rectangle a l'exterieur de la PictureBox (et avoir un espace entre les deux eventuellement).
Autrement dit, je voudrais la PictureBox dans le Rectangle et pas l'inverse, le Rectangle etant independant du PictureBox.

Joe,
Si je suis sur la meme longueur d'onde que toi, c'est ce que j'essaye de faire.
Mais, cela me parait assez complique, car on doit gerer le Paint event a chaque fois qu'on bouge le Rectangle/PictureBox.
Et, du fait que le Paint event se trouve dans la Classe PictureBox, je crois que je cree/repeins le Rectangle dans la PictureBox ou quelquechose d'horrible comme ca... et non sur la Form1 (Rectangle independant etant a l'exterieur de la PictureBox).
Bref, pour l'instant je me melange les pinceaux.

En resume: une PictureBox a l'interieur d'un Rectangle, deux controles independants (PictureBox et Rectangle) bougeant sur la Form1 en meme temps.
Gerer les evenements de ces 2 controles (D'ailleurs, le Rectangle est-il vraiment un controle?) est un casse tete pour moi.

Merci tout de meme,
A+
JLuc01
0
cs_ShayW Messages postés 3253 Date d'inscription jeudi 26 novembre 2009 Statut Membre Dernière intervention 3 décembre 2019 57
24 janv. 2013 à 01:54
Salut

le rectangle n'est pas un control il est
dessiné dans un control container comme form
picturebox
donc si tu veux le rectangle en dehors du picturebox il faut le dessiner dans ta form
mais le problème est quand tu vas bouger ton picturebox les rectangles précedents ne s'effacent pas

Public Class Frame
    ' The class sets an image and resizes the 'picturebox size matching
    'the image size 
    'It also moves itself onto the screen when the 'mousedown and mousemove event are raised   
    Inherits PictureBox

    Private lastmouselocation As New Point
    Public Property myimage() As Image
        Get
            Return Me.Image
        End Get
        Set(ByVal value As Image)
            Me.Image = value
            Me.Size = value.Size
            
        End Set
    End Property
    

    Private Sub Frame_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        lastmouselocation = New Point(e.Location)

    End Sub

    Private Sub Frame_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Left += e.Location.X - lastmouselocation.X
            Me.Top += e.Location.Y - lastmouselocation.Y
        End If

    End Sub
    
End Class


Public Class Form1
    Private myframe As New Frame

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        myframe.myimage = Image.FromFile(Application.StartupPath & "\happy3.JPG")
        myframe.Location = New Point(10, 10)
        Me.Controls.Add(myframe)
    End Sub
   
 Private Sub DrawFrame(ByVal gr As System.Drawing.Graphics)
        gr.DrawRectangle(New Pen(Color.Blue, 3), myframe.Left - 4, myframe.Top - 4, myframe.Width + 8, myframe.Height + 8)
    End Sub

    
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        DrawFrame(e.Graphics)

    End Sub
End Class
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 janv. 2013 à 06:50
Bonjour,
ou mettre un label transparent, sans caption, "flat" et avec bordures tout autour de la picturebox et utiliser une même procédure de déplacement pour les deux, appelée au mousemove de chacun des deux.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
ehjoe Messages postés 728 Date d'inscription samedi 4 avril 2009 Statut Membre Dernière intervention 30 mars 2014 4
24 janv. 2013 à 08:39
Bonjour JLuc01,

Tu écris :


Je voudrais dessiner un Rectangle, mettre une PictureBox a l'interieur et bouger les 2 ensemble.


Tiens, voici ton programme testé, sufffit de recopier le code en mettant 3 objets :
- form
- rectangleShape1
- pictureBox
C'EST LA PICTURE QU'ON DEPLACE






Option Explicit On
Public Class Form1
  Private deplace As Nullable(Of Point)

  Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
    deplace = PointToClient(Control.MousePosition) - PictureBox1.Location
  End Sub

  Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
    deplace = Nothing
  End Sub

  Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
    If deplace Is Nothing Then Exit Sub
    PictureBox1.Location = PointToClient(Control.MousePosition) - deplace.Value
    RectangleShape1.Left = PictureBox1.Left - 20
    RectangleShape1.Top = PictureBox1.Top - 20
  End Sub
End Class


Cordialement, Joe.
0
cs_ShayW Messages postés 3253 Date d'inscription jeudi 26 novembre 2009 Statut Membre Dernière intervention 3 décembre 2019 57
24 janv. 2013 à 10:53
Salut Ehjoe

le rectangleShape1 n'apparait pas dans la boite

à outil
Salut JLuc01
je pense que le mieux est de dessiner le rectangle dans la picturebox dimensionner
la picturebox plus grand que l'image de fait en
donnant l'effet que le rectangle est à l'extérieur du picturebox

encore un essaie
Public Class Frame
      
    Inherits PictureBox

    Private lastmouselocation As New Point
    Public Property myimage() As Image
        Get
            Return Me.Image
        End Get
        Set(ByVal value As Image)
            Me.SizeMode = PictureBoxSizeMode.CenterImage
            Me.Image = value
            Me.Width = value.Width + 30
            Me.Height = value.Height + 30
        End Set
    End Property
    Private Sub DrawFrame(ByVal gr As System.Drawing.Graphics)
        gr.DrawRectangle(New Pen(Color.Blue, 2), Me.Location.X, Me.Location.Y, Me.Width - 20, Me.Height - 20)
    End Sub

    Private Sub Frame_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        lastmouselocation = New Point(e.Location)
    End Sub

    Private Sub Frame_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Left += e.Location.X - lastmouselocation.X
            Me.Top += e.Location.Y - lastmouselocation.Y
        End If
    End Sub

    Private Sub Frame_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        DrawFrame(e.Graphics)
    End Sub
End Class


Public Class Form1
    Private myframe As New Frame

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        myframe.myimage = Image.FromFile(Application.StartupPath & "\happy3.JPG")
        myframe.Location = New Point(10, 10)
        Me.Controls.Add(myframe)
    End Sub

End Class
0
ehjoe Messages postés 728 Date d'inscription samedi 4 avril 2009 Statut Membre Dernière intervention 30 mars 2014 4
24 janv. 2013 à 11:33
Suite...

Mais si, mais si... le rectangle est dans les outils, (affiches tous les outils alphabétiquement), regarde à :

RectangleShape

Cordialement.
0
Utilisateur anonyme
24 janv. 2013 à 22:22
Bonsoir,

Et pourquoi ne pas faire un Contrôle utilisateur tout simplement avec un fond de la couleur de ton fameux rectangle et un picturebox placé et centré au milieu ?
Avantages : Facilité de déplacement, de codage, événements et propriétés intactes...
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 janv. 2013 à 22:25
Bonjour, banana32,
la raison se cache probablement dans cette réponse :
A vrai dire, j'ai vraiment besoin du Rectangle, car je prevois d'utiliser certaines proprietes du Rectangle plus tard.



________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
Utilisateur anonyme
25 janv. 2013 à 16:55
A vrai dire, j'ai vraiment besoin du Rectangle, car je prevois d'utiliser certaines proprietes du Rectangle plus tard.

Raison de plus alors.

Bien le bonsoir ucfoutu
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
25 janv. 2013 à 17:06
Raison de plus alors

Pas certain du tout, notamment s'il veut personnaliser le périmètre dans certaines circonstances.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
Utilisateur anonyme
25 janv. 2013 à 17:41
Cher ucfoutu,

A cause de toi, j'ai été obligé de me justifier par un exemple concret sous forme de code commenté que JLuc01 pourra tester si ça lui dit.

Cet exemple montre comment déplacer un rectangle (picturebox) contenant un autre picturebox (image par exemple). Lors du clic gauche, on vient 'régionner' le picturebox contenant l'image. Le contenant est donc creux pendant le déplacement (comme si on avait enlevé le centre). Lors du relachement du bouton de la souris, on annule le 'régionnage'. Le contenant n'est plus creux et l'image revient.

A noter qu'on peut aisément se servir des propriétés existantes des deux picturebox pour effectuer diverses actions supplémentaires.

A tester dans un projet vierge.

Public Class Form1
    'déclaration d'un picturebox de fond rouge
    Dim WithEvents MonPictRectangle As New PictureBox With {.Parent Me, .BackColor Color.Red, .Size = New Size(200, 200)}
    'déclaration d'un picturebox enfant de MonPictRectangle (de fond rouge ou avec une image)
    Dim WithEvents MonPictImage As New PictureBox With {.Parent MonPictRectangle, .BackColor Color.Blue, .Size = New Size(150, 150), .Location = New Point(25, 25)}
    'déclaration d'un poijnt
    Dim MonPoint As Point

    Private Sub MonPictRectangle_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MonPictRectangle.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            'mémorisation du point en vue du déplacement
            MonPoint = e.Location
            'préparation du régionnage (centre du picturebox découpé)
            Dim MesPoints() As Point = {New Point(0, 0), _
                                        New Point(200, 0), _
                                        New Point(200, 200), _
                                        New Point(0, 200), _
                                        New Point(0, 0), _
                                        New Point(25, 25), _
                                        New Point(175, 25), _
                                        New Point(175, 175), _
                                        New Point(25, 175), _
                                        New Point(25, 25)}
            Dim _types(MesPoints.Length - 1) As Byte
            For x = 0 To MesPoints.Length - 1
                _types(x) = Ctype(Drawing2D.PathPointType.Line,byte)
            Next
            Dim gp As New Drawing2D.GraphicsPath(MesPoints, _types)
            'régionnage
            MonPictRectangle.Region = New Region(gp)
        End If
    End Sub

    Private Sub MonPictRectangle_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MonPictRectangle.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            'calcul de la position du picturebox pendnant le déplacement
            MonPictRectangle.Location = Point.Subtract(Cursor.Position, _
                                              New Size(Me.Left + MonPoint.X, _
                                              Me.Top + MonPoint.Y + SystemInformation.CaptionHeight))
        End If
    End Sub

    Private Sub MonPictRectangle_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MonPictRectangle.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            'annulation du régionnage
            MonPictRectangle.Region = Nothing
        End If
    End Sub
End Class
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
25 janv. 2013 à 17:49
Tu n'as pas compris, je pense, ce que j'entendais par personnalisation du périmètre du rectangle.
Ni la bordure d'un contenant, ni sa couleur de fond, ni la "fausse bordure" résultant d'un positionnement de l'image au sein du contenant ne sauraient par exemple transformer à la demande et selon les circonstances (signaler par exemple son "accrochage" en vue de redimensionnement ou autre) l'aspect du périmètre du rectangle (pointillés, tirets, etc...).
Le demandeur n'est pas revenu, mais je suis impatient de savfoir pourquoi il a fait la remarque qu'il a faite sur son voeu de garder à tout prix son rectangle.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
Utilisateur anonyme
25 janv. 2013 à 18:02
Ni la bordure d'un contenant, ni sa couleur de fond, ni la "fausse bordure" résultant d'un positionnement de l'image au sein du contenant ne sauraient par exemple transformer à la demande et selon les circonstances (signaler par exemple son "accrochage" en vue de redimensionnement ou autre) l'aspect du périmètre du rectangle (pointillés, tirets, etc...).


On peut absolument tout modifier et à n'importe quel moment. Rien de plus simple que de dessiner ce que l'on souhaite à l'intérieur du contenant ou de son enfant d'ailleurs (pointillés, texte, couleurs, ...) ainsi que changer sa forme (mon exemple ci-dessus) etc...

Mais attendons de lire plus de précisions de JLuc01...
0
cs_JLuc01 Messages postés 206 Date d'inscription samedi 17 janvier 2009 Statut Membre Dernière intervention 5 mars 2013 1
25 janv. 2013 à 21:51
Bonsoir tout le monde,

Donc, voila plus de precision en esperant satisfaire votre curiosite.
En fait, c'est simple: j'essaye de reproduire la PictureBox qu'on voit en Design, avec possibilite de bouger l'image, de l'agrandir..., le tout dans une Classe.

Pour expliquer, voila 2 images qui montre une partie de ce que j'ai fais.

Et apres agrandissement dans le sens Bottom-Right:

Dans l'apercu, on ne voit pas les images. Je ne suis pas sur que ca marchera quand j'enverrais le message.
(EhJOe!, dis-moi comment tu as reussi a mettre une image dans ton message)

Enfin bref, j'ai une image dans un PictureBox avec un Rectangle autour que je peux agrandir ou retrecir a l'aide de 8 petits rectangles places tout autour qui apparaissent lorsque je clique sur la souris (un peu comme le PictureBox en Design). Lorsque la souris se trouve sur le PictureBox, le curseur et le Rectangle change...

Pour l'instant, j'arrive a le faire, mais pas dans une classe. Mon but etant de creer une classe pour ce morceau de code (500 lignes). Une fois arrive a cet objectif, je prevois d'ajouter plus de proprietes et fonctions, pour que cela ressemble en mieux a la PictureBox qu'on voit en Design. Bon! Je suis peut-etre pretentieux quand je dis "en mieux" ou tout simplement optimiste. Quoiqu'il en soit, c'est mon objectif actuel et j'essaye de m'en approcher.

C'est certainement un exercice challenging pour un amateur comme moi.

Banana,
Ton morceau de code est aussi interessant, car je note que tu n'utilise pas l'evenement Paint. Peut-etre quelquechose a creuser avec "Region".
Mon week-end ne va pas etre assez long pour verifier toutes les idees recues.

Merci a tous,
A+
JLuc01
0
cs_JLuc01 Messages postés 206 Date d'inscription samedi 17 janvier 2009 Statut Membre Dernière intervention 5 mars 2013 1
25 janv. 2013 à 21:54
Bon! Je re-essaye pour les images en jpeg cette fois ci au lieu de png.


Et


A+
JLuc01
0
Utilisateur anonyme
25 janv. 2013 à 21:59
Heu... Les images doivent être stockées ailleurs que sur ta machine tu t'en doutes
0
Rejoignez-nous