Redimensionner une pictureBox avec la souris dans un panel

Résolu
spifspaf Messages postés 25 Date d'inscription samedi 14 juin 2014 Statut Membre Dernière intervention 26 avril 2021 - Modifié par BunoCS le 22/07/2016 à 17:34
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 - 25 juil. 2016 à 00:15
Bonjour, à tous
J'ai trouvé un script qui permet de pouvoir redimensionner une picturebox avec la souris dans une form .
j'ai essayé de l'appliquer dans mon programme, mais cela ne fonctionne pas corretement car mon picture se trouve dans un panel.
L'un de vous aurait la gentillesse m'aider, je dois avouer que j'ai vraiment du mal à comprendre le VB
Le code : ( fonctionne très bien dans une form ) mais si vous ajoutez un panel et la picturebox dans le panel cela n'est pas fonctionnel ( help me please ) :)

Public Class Form1
   Private handleSize As Integer = 5
    Private overHandle As Boolean
    Private inPB As Boolean = False
    Private resizing As Boolean = False
    Private rc1 As Rectangle
    Private rc2 As Rectangle
    Private rc3 As Rectangle
    Private rc4 As Rectangle
    Private startPoint As Point
    Private endPoint As Point
    Private lastPoint As Point
    Private screenRC As Rectangle

    Private Sub PictureBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseEnter
        UpdateHandles()
        inPB = True
        PictureBox1.Refresh()
    End Sub

    Private Sub UpdateHandles()
        rc1 = New Rectangle(0, 0, handleSize, handleSize)
        rc2 = New Rectangle(0, PictureBox1.Height - handleSize - 2, handleSize, handleSize)
        rc3 = New Rectangle(PictureBox1.Width - handleSize - 2, 0, handleSize, handleSize)
        rc4 = New Rectangle(PictureBox1.Width - handleSize - 2, PictureBox1.Height - handleSize - 2, handleSize, handleSize)
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        If inPB Then
            e.Graphics.FillRectangle(Brushes.Red, rc1)
            e.Graphics.FillRectangle(Brushes.Red, rc2)
            e.Graphics.FillRectangle(Brushes.Red, rc3)
            e.Graphics.FillRectangle(Brushes.Red, rc4)
        End If
    End Sub

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left AndAlso overHandle Then
            resizing = True
            If rc1.Contains(e.X, e.Y) Then
                startPoint = New Point(PictureBox1.Width, PictureBox1.Height)
                endPoint = New Point(0, 0)
            ElseIf rc2.Contains(e.X, e.Y) Then
                startPoint = New Point(PictureBox1.Width, 0)
                endPoint = New Point(0, PictureBox1.Height)
            ElseIf rc3.Contains(e.X, e.Y) Then
                startPoint = New Point(0, PictureBox1.Height)
                endPoint = New Point(PictureBox1.Width, 0)
            ElseIf rc4.Contains(e.X, e.Y) Then
                startPoint = New Point(0, 0)
                endPoint = New Point(PictureBox1.Width, PictureBox1.Height)
            End If
            lastPoint = New Point(e.X, e.Y)
            screenRC = PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint))
            ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        overHandle = rc1.Contains(e.X, e.Y) OrElse rc2.Contains(e.X, e.Y) OrElse rc3.Contains(e.X, e.Y) OrElse rc4.Contains(e.X, e.Y)
        If resizing Then
            ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
            endPoint.X = endPoint.X + (e.X - lastPoint.X)
            endPoint.Y = endPoint.Y + (e.Y - lastPoint.Y)
            lastPoint = New Point(e.X, e.Y)
            screenRC = PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint))
            ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        If resizing Then
            resizing = False
            ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
            Dim newPosition As Rectangle = Me.RectangleToClient(PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint)))
            PictureBox1.SuspendLayout()
            PictureBox1.Location = newPosition.Location
            PictureBox1.Size = newPosition.Size
            PictureBox1.ResumeLayout()
            UpdateHandles()
            PictureBox1.Refresh()
        End If
    End Sub

    Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
        inPB = False
        PictureBox1.Refresh()
    End Sub

    Private Function NormalizedRC(ByVal ptA As Point, ByVal ptB As Point) As Rectangle
        Return New Rectangle(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y), Math.Abs(ptA.X - ptB.X), Math.Abs(ptA.Y - ptB.Y))
    End Function

End Class

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ICI

Merci d'y penser dans tes prochains messages.

6 réponses

vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
Modifié par vb95 le 23/07/2016 à 21:02
Bonjour
A tester avec un panel Panel1 et une picturebox Picturebox1
Chez moi cela fonctionne nickel avec juste cela dans ma Form

Le problème est qu'il faut ramener les coordonnées des points à l'origine de la Form Form1 alors que sans modification les coordonnées des points sont à l'origine du Panel
Cela justifie l'ajout des 2 variables PanelLeft et PanelTop qui définissent la position du panel sur la Form

Public Class Form1

Private handleSize As Integer = 5
Private overHandle As Boolean
Private inPB As Boolean = False
Private resizing As Boolean = False
Private rc1 As Rectangle
Private rc2 As Rectangle
Private rc3 As Rectangle
Private rc4 As Rectangle
Private startPoint As Point
Private endPoint As Point
Private lastPoint As Point
Private screenRC As Rectangle
Private PanelTop As Integer
Private PanelLeft As Integer

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub

Private Sub PictureBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseEnter
UpdateHandles()
inPB = True
PictureBox1.Refresh()
End Sub

Private Sub UpdateHandles()

rc1 = New Rectangle(PanelLeft, PanelTop, handleSize, handleSize)
rc2 = New Rectangle(PanelLeft, PanelTop + PictureBox1.Height - (handleSize + 2), handleSize, handleSize)
rc3 = New Rectangle(PanelLeft + PictureBox1.Width - (handleSize + 2), PanelTop, handleSize, handleSize)
rc4 = New Rectangle(PanelLeft + PictureBox1.Width - (handleSize + 2), PanelTop + PictureBox1.Height - (handleSize + 2), handleSize, handleSize)

End Sub

Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If inPB Then
e.Graphics.FillRectangle(Brushes.Red, rc1)
e.Graphics.FillRectangle(Brushes.Red, rc2)
e.Graphics.FillRectangle(Brushes.Red, rc3)
e.Graphics.FillRectangle(Brushes.Red, rc4)
End If
End Sub

Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = MouseButtons.Left AndAlso overHandle Then
resizing = True
If rc1.Contains(e.X, e.Y) Then
startPoint = New Point(PanelLeft + PictureBox1.Width, PanelTop + PictureBox1.Height)
endPoint = New Point(PanelLeft, PanelTop)
ElseIf rc2.Contains(e.X, e.Y) Then
startPoint = New Point(PanelLeft + PictureBox1.Width, PanelTop)
endPoint = New Point(PanelLeft, PanelTop + PictureBox1.Height)
ElseIf rc3.Contains(e.X, e.Y) Then
startPoint = New Point(PanelLeft, PanelTop + PictureBox1.Height)
endPoint = New Point(PanelLeft + PictureBox1.Width, PanelTop)
ElseIf rc4.Contains(e.X, e.Y) Then
startPoint = New Point(PanelLeft, PanelTop)
endPoint = New Point(PanelLeft + PictureBox1.Width, PanelTop + PictureBox1.Height)
End If
lastPoint = New Point(e.X, e.Y)
screenRC = PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint))
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
End If
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
overHandle = rc1.Contains(e.X, e.Y) OrElse rc2.Contains(e.X, e.Y) OrElse rc3.Contains(e.X, e.Y) OrElse rc4.Contains(e.X, e.Y)
If resizing Then
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
endPoint.X = endPoint.X + (e.X - lastPoint.X)
endPoint.Y = endPoint.Y + (e.Y - lastPoint.Y)
lastPoint = New Point(e.X, e.Y)
screenRC = PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint))
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
End If
End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If resizing Then
resizing = False
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
Dim newPosition As Rectangle = Panel1.RectangleToClient(PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint)))
PictureBox1.SuspendLayout()
PictureBox1.Location = newPosition.Location
PictureBox1.Size = newPosition.Size
PictureBox1.ResumeLayout()
UpdateHandles()
PictureBox1.Refresh()
End If
End Sub

Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
inPB = False
PictureBox1.Refresh()
End Sub

Private Function NormalizedRC(ByVal ptA As Point, ByVal ptB As Point) As Rectangle
Return New Rectangle(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y), Math.Abs(ptA.X - ptB.X), Math.Abs(ptA.Y - ptB.Y))
End Function

End Class


La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. 
1
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
23 juil. 2016 à 23:44
Rebonsoir

Même mieux
Dans ton code d'origine une seule ligne à modifier :
Dim newPosition As Rectangle = Me.RectangleToClient(PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint)))

par
Dim newPosition As Rectangle = Panel1.RectangleToClient(PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint)))


c'est tout : on agit sur la picturebox dans le panel (Panel1) et non sur la Form (Me) . Me représente la Formelle-même

Les variables PanelTop et PanelLeft sont alors inutiles
1
Personne pour m'aider SVP ? :)

" Désolé pour les balises code mais elles n'apparaissent pas quand j'ai rédigé mon message .... je n'avais aucunes options "
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
23 juil. 2016 à 23:45
Va voir ma seconde réponse plus bas
0
Bonjour,
Merci avant tout :)
Apparemment les deux solution fonctionnent.

la 2eme en effet est beaucoup plus légère.

Par contre les variables PanelTop et PanelLeft peuvent être utiles pour une gestion de limitation de déplacement dans le panel ?
( ça va être ma prochaine étape :) )
0

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

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 juil. 2016 à 20:16
Bonjour (et un salut à vb95)
Apparemment les deux solution fonctionnent

La règle est alors de libérer' la discussion (un click sur le tag RESOLU au niveau du premier message). Merci_ d'y penser.
Et( si l'on a d'autres questions ===>autre discussion (c'est là une raison de "santé").
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
25 juil. 2016 à 00:15
Bonsoir Uc ! j'espère que la pèche est bonne du coté du golfe de Gascogne !

Bonsoir Spifspaf
tu as marqué : Apparemment les deux solution fonctionnent

Évidemment dans mon premier code j'ai bien dimensionné PanelTop et PaneLeft mais je n'ai attribué aucune valeur à ces 2 variables : ce qui fait qu'elles contiennent 0 et mon code est équivalent à ton premier code présenté ( mis à part la fameuse ligne à modifier pour agir au niveau du Panel et non de la Form)
0
Désolé vais le valider donc :)

je voulais simplement améliorer le code et en faire profiter ;)

Sinon pour info v'la le même code avec le déplacement au click droit ( mais pas limité dans le panel, ça fera office d'un autre sujet ;) )

Merci encore à vous


Public Class Form4


Private handleSize As Integer = 5
Private overHandle As Boolean
Private inPB As Boolean = False
Private resizing As Boolean = False
Private rc1 As Rectangle
Private rc2 As Rectangle
Private rc3 As Rectangle
Private rc4 As Rectangle
Private startPoint As Point
Private endPoint As Point
Private lastPoint As Point
Private screenRC As Rectangle

Dim Gauche As Integer
Dim Haut As Integer
Dim no As Boolean = False



Private Sub PictureBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseEnter
UpdateHandles()
inPB = True
PictureBox1.Refresh()
End Sub

Private Sub UpdateHandles()
rc1 = New Rectangle(0, 0, handleSize, handleSize)
rc2 = New Rectangle(0, PictureBox1.Height - handleSize - 2, handleSize, handleSize)
rc3 = New Rectangle(PictureBox1.Width - handleSize - 2, 0, handleSize, handleSize)
rc4 = New Rectangle(PictureBox1.Width - handleSize - 2, PictureBox1.Height - handleSize - 2, handleSize, handleSize)
End Sub

Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If inPB Then
e.Graphics.FillRectangle(Brushes.Red, rc1)
e.Graphics.FillRectangle(Brushes.Red, rc2)
e.Graphics.FillRectangle(Brushes.Red, rc3)
e.Graphics.FillRectangle(Brushes.Red, rc4)
End If
End Sub

Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Try

Gauche = e.X
Haut = e.Y
If e.Button = Windows.Forms.MouseButtons.Right Then
PictureBox1.Cursor = Cursors.SizeAll
End If

Catch ex As Exception
Exit Sub
End Try



If e.Button = Windows.Forms.MouseButtons.Left AndAlso overHandle Then
resizing = True
If rc1.Contains(e.X, e.Y) Then
startPoint = New Point(PictureBox1.Width, PictureBox1.Height)
endPoint = New Point(0, 0)
ElseIf rc2.Contains(e.X, e.Y) Then
startPoint = New Point(PictureBox1.Width, 0)
endPoint = New Point(0, PictureBox1.Height)
ElseIf rc3.Contains(e.X, e.Y) Then
startPoint = New Point(0, PictureBox1.Height)
endPoint = New Point(PictureBox1.Width, 0)
ElseIf rc4.Contains(e.X, e.Y) Then
startPoint = New Point(0, 0)
endPoint = New Point(PictureBox1.Width, PictureBox1.Height)
End If
lastPoint = New Point(e.X, e.Y)
screenRC = PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint))
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
End If
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
overHandle = rc1.Contains(e.X, e.Y) OrElse rc2.Contains(e.X, e.Y) OrElse rc3.Contains(e.X, e.Y) OrElse rc4.Contains(e.X, e.Y)

If e.Button = Windows.Forms.MouseButtons.Right Then
PictureBox1.Location = New Point(PictureBox1.Left + e.X - Gauche, PictureBox1.Top + e.Y - Haut)

End If

If resizing Then
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
endPoint.X = endPoint.X + (e.X - lastPoint.X)
endPoint.Y = endPoint.Y + (e.Y - lastPoint.Y)
lastPoint = New Point(e.X, e.Y)
screenRC = PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint))
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
End If
End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If Not no = False Then
Windows.Forms.Cursor.Clip = Nothing
no = False
End If

If resizing Then
resizing = False
ControlPaint.DrawReversibleFrame(screenRC, PictureBox1.BackColor, FrameStyle.Dashed)
Dim newPosition As Rectangle = Panel1.RectangleToClient(PictureBox1.RectangleToScreen(NormalizedRC(startPoint, endPoint)))
PictureBox1.SuspendLayout()
PictureBox1.Location = newPosition.Location
PictureBox1.Size = newPosition.Size
PictureBox1.ResumeLayout()
UpdateHandles()
PictureBox1.Refresh()
End If



End Sub

Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
inPB = False
PictureBox1.Refresh()
End Sub

Private Function NormalizedRC(ByVal ptA As Point, ByVal ptB As Point) As Rectangle
Return New Rectangle(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y), Math.Abs(ptA.X - ptB.X), Math.Abs(ptA.Y - ptB.Y))
End Function





End Class
0
Rejoignez-nous