IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Drag 'n Drop entre PictureBox visible à la souris


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 80
    Par défaut Drag 'n Drop entre PictureBox visible à la souris
    Malgré de nombreuses recherches ici et là je n'arrive pas à solutionner les problèmes suivant :
    J'ai des pictureBox indicées (dynamiques) Cartes(i,j) qui contiennent des images de jeu de cartes.
    Le Drag 'n Drop entre ces cartes fonctionnent parfaitement mais je voudrais que lors du déplacement
    d'une carte(,) vers une autre carte(,) la carte-source(pictutebox) se déplace avec la souris jusqu'à
    destination au relâcher de la souris...

    1 - comment faire lors du déplacement avec la souris la carte(,) se déplace au gré de la souris jusqu'à
    destination ?

    2 - Il y a bien sûr la méthode API de Windows que j'ai testé et qui fonctionne parfaitement mais dans ce
    cas je n'arrive pas à détecter le passage sur la carte cible(celle qui reçoit la source)..

    A toute fin utile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        Public Const WM_NCLBUTTONDOWN = &HA1           ' Windows Message Non Client CODE &HA1
        Public Const HTCAPTION = 2
     
        Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
        Public Declare Sub ReleaseCapture Lib "user32" ()
     
    -------------------------------------------------------------------------------------------------
    Public Sub Cartes_MouseDown(sender As Object, e As MouseEventArgs) Handles ......  
       Source = sender : X0 = Source.Location.X : Y0 = Source.Location.Y
       Source.BackColor=color
       Source.BringToFront()
       Dim lHwnd As Int32 = CType(Source.Handle.ToString, Int32) 
       If lHwnd = 0 Then Exit Sub
       Me.Cursor = Cursors.Hand
       ReleaseCapture()
       SendMessage(lHwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&)                    ' On déplace la Carte
    End Sub
    Merci d'avance à tous ceux qui se pencheront sur mes 2 problèmes.

  2. #2
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour

    Si c'est pour deplacer un PictureBox sur un container control (panel,form) ,tu t'egares simplement dans GDI....

    - MouseDown,MouseMove et MouseUp respondent au besoin...
    - Control.Bounds definit le rectangle par rapport au Container et permets de tester les positions relatives de 2 controls ou plus (chevauchement ou pas) ...
    NB: à ne pas confondre avec le rectangle designe par ClientRectangle qui se refere à la zone cliente et dont l'origine est toujours (0,0)...

    Ce simple bout de code te montrera ,que si le coursier n'as pas la bride bien tenue ,il peut nous emmener loin(expression de chez nous: le coursier s'est emporte et evade avec le cavalier)....

    code exemple .vb avec 2 PictureBoxes :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
     
    Public Class Form4
        Private isDragging As Boolean
        Private ptDown As Point
        Private draggedControl As PictureBox
     
        Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
            draggedControl = CType(sender, PictureBox)
            draggedControl.BringToFront()
            If e.Button = MouseButtons.Left Then
                draggedControl.BackColor = Color.Green
                isDragging = True
                ptDown = e.Location
            End If
        End Sub
     
        Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
            draggedControl = CType(sender, PictureBox)
            If isDragging And e.Button = MouseButtons.Left Then
                draggedControl.Left += e.Location.X - ptDown.X
                draggedControl.Top += e.Location.Y - ptDown.Y
            End If
        End Sub
     
        Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
            draggedControl = CType(sender, PictureBox)
            If isDragging And e.Button = MouseButtons.Right Then
     
                If draggedControl.Bounds.IntersectsWith(PictureBox2.Bounds) Then
                    PictureBox2.BackColor = Color.Yellow
                End If
                draggedControl.SendToBack()
                draggedControl.BackColor = SystemColors.Control
                draggedControl = Nothing
                ptDown = Point.Empty
                isDragging = False
            End If
        End Sub
    End Class
    le 2eme code exemple à l'aide d'un damier de PictureBoxes avec un List(of PictureBox)' bien plus souple qu'un Array ,son inconvenient majeur etant la manip des indices pour retrouver un element) est bien plus etoffe et montre comment à l'aide des Event Handlers Souris et Control.Bounds:
    - sauvergarder le Location initial du Pic Source dans la variable P0(point)
    - tester l'intersection avec le Pic Dest ,Dropper le Pic Source avec un Swap du Pic Source et Dest (mais si c'est une capture il faut un remove du Pic Dest dans le liste Cartes,si c'est etc....!!!):



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
     
    Public Class FormCartes
        Private INTERVAL As Integer = 20
        Private SPAWNX As Integer = 20
        Private SPAWNY As Integer = 20
        Private Columns As Integer = 8
        Private Rows As Integer = 8
        Private colWidth As Integer = 64
        Private rowHeight As Integer = 64
        Private Cartes As New List(Of PictureBox)
        Private Sub FormCartes_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Me.AutoSize = True
     
            AddCartes()
        End Sub
     
        Private Sub AddCartes()
            Me.Cartes.Clear()
            Me.Controls.Clear()
            Dim pic As PictureBox
            Dim X, Y As Integer
            For i As Integer = 0 To Rows - 1
     
                For j As Integer = 0 To Columns - 1
                    X = SPAWNX + j * (colWidth + INTERVAL)
                    Y = SPAWNY + i * (rowHeight + INTERVAL)
                    pic = New PictureBox
                    pic.BorderStyle = BorderStyle.FixedSingle
                    pic.BackColor = Color.Blue
                    pic.Location = New Point(X, Y)
     
                    pic.Size = New Size(colWidth, rowHeight)
                    Cartes.Add(pic)
                    pic.Text = "No " + Cartes.IndexOf(pic).ToString
                    AddHandler pic.Paint, AddressOf PicPaint
                    AddHandler pic.MouseDown, AddressOf FormMouseDown
                    AddHandler pic.MouseMove, AddressOf FormMouseMove
                    AddHandler pic.MouseUp, AddressOf FormMouseUp
     
                Next
            Next
            Me.Controls.AddRange(Cartes.ToArray())
     
     
     
        End Sub
     
        Private Sub PicPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
            Dim item As PictureBox = CType(sender, PictureBox)
            Dim gr As Graphics = e.Graphics
            Dim rect As Rectangle = item.ClientRectangle
            rect.Inflate(-15, -15)
            Using fnt As New Font("Arial", 8.0)
                Using br As New SolidBrush(Color.White)
                    gr.DrawString(item.Text, fnt, br, item.Width / 4, item.Height / 4)
                End Using
            End Using
     
        End Sub
        Private isDragging As Boolean
        Private ptDown As Point
        Private draggedControl As PictureBox
        Private P0 As Point = Point.Empty
        Private P1 As Point = Point.Empty
        Private Sub FormMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
            draggedControl = CType(sender, PictureBox)
            draggedControl.BringToFront()
            If e.Button = MouseButtons.Left Then
                P0 = draggedControl.Location
                isDragging = True
                ptDown = e.Location
            End If
        End Sub
     
        Private Sub FormMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
            draggedControl = CType(sender, PictureBox)
            If isDragging And e.Button = MouseButtons.Left Then
                draggedControl.Left += e.Location.X - ptDown.X
                draggedControl.Top += e.Location.Y - ptDown.Y
            End If
        End Sub
        Private Sub FormMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
            draggedControl = CType(sender, PictureBox)
            If isDragging And e.Button = MouseButtons.Right Then
     
                Dim foundItem As PictureBox = Nothing
                For Each item As PictureBox In Cartes
                    If item Is draggedControl Then Continue For
                    If draggedControl.Bounds.IntersectsWith(item.Bounds) Then
                        foundItem = item
                        foundItem.BackColor = Color.Magenta
     
                        Exit For
                    End If
                Next
                If foundItem IsNot Nothing Then
                    SwapPictures(draggedControl, foundItem)
                Else
                    draggedControl.Location = P0
                    draggedControl.SendToBack()
                End If
                draggedControl = Nothing
                ptDown = Point.Empty
                P0 = Point.Empty
                P1 = Point.Empty
     
                isDragging = False
            End If
        End Sub
        Private Sub SwapPictures(ByVal draggedPic As PictureBox, ByVal 
    targetPic As PictureBox)
            P1 = targetPic.Location
            targetPic.Location = P0
            draggedPic.Location = P1
     
     
        End Sub
    End Class
    bon code....

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 80
    Par défaut apres essai il reste problème à résoudre
    Après avoir testé la 1ère solution que je connaissais par ailleurs, il reste un problème à solutionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If draggedControl.Bounds.IntersectsWith(PictureBox2.Bounds) Then
    cette fonction est limitative dans mon cas car elle teste l'intersection entre 2 picturebox déjà connues
    à l'avance ( draggedcontrol(source) et picturebox2(cible)... Or dans mon problème la source bien sûr
    est connue, donc pas de soucis mais la cible se fait au gré de la souris...
    C'est un jeu de cartes ou les cibles sont soit source soit cible. Indicées de la manière suivante, Cartes(i,j)
    la source sera par exemple Cartes(0,1) et la cible se fera au gré de la souris selon critère à définir.. C'est
    donc quand la souris passera au-dessus de la cible et que le bouton de la souris sera relâché que dans
    l'exemple de code pré-cité PICTUREBOX2 devra être connu et donc comment la reconnaître ..
    j'espère m'être bien fait comprendre... merci d'avance de votre aide.

  4. #4
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    bonsoir,

    Ce que tu expliques est un faux probleme. Dejà en te basant sur l exemple de mabrouki tu ne peux plus recuperer une carte de cette manière :
    ...puisque maintenant les cartes sont stockés dan une list (of picturebox)....brefff...
    Si tu veux connaitre l etat de la carte a un instant "T" il te suffit soit d ajouter la valeur que tu veux dans la propriété .tag de n importe quelle carte que tu manipules dans le code. En gardant a l esprit que tu peux creer une classe avec des propriétés particulieres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class cardState
     
    public property isSource as boolean
    public property isTarget as boolean
     
    public sub new()
    end sub
     
    end class
    et affecter l instance dans cette dite propriété .tag de l instance d une carte (picturebox) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cartes(2).tag = new cardstate with {.issource = true, .istarget = false}
    ...plus tard tu recuperes la valeur dans ton programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if trycast(cartes(2).tag, cardstate).issource then
    '...... 
    end if
    ou il est egalement possible d'etendre les propriétés d un controle picturebox en creant une classe PictureboxEx qui herite de pictureBox :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class PictureboxEx
    inherits picturebox
     
    public property isSource as boolean
    public property isTarget as boolean
     
    end class
    ainsi dans ton code tu appelles cette extension de classe (pictureboxEx) au lieu de celle d origine (pictureBox) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private draggedControl As PictureBoxEx
    Private Cartes As New List(Of PictureBoxEx)
    '.....etc.....
    PS : dsl pour les fautes il y en a car j ai ecris depuis mon mobile....

    Bon codage.
    a+

  5. #5
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour
    comme souligne par wallace ton probleme -savoir si une cible est valide ou, non - est specifique au jeu en question ( jeu de cartes que ignorons totalement ) et c'est une affaire de design qui n'as rien à voir avec le post initial concernant le deplacement d'un picturebox et le hit-testing d'un control par rapport à un autre....

    Comme suggere par wallace l'astuce consiste en general ,lorsque on utilize un control comme carte ou piece à stocker dans un class separe fourre-tout les infos pertinentes sur la piece picbox : type ,valeur, player de la piece picbox, validite ,index de position etc...
    Ce class sera conserve dans le tag du picbox lors de l'initialisation du jeu et requite lors des tests de deplacement de la piece picbox.,et mis à jour bien entendu....
    Il reflete l'etat de la piece à tout instant du jeu....
    bon code...

  6. #6
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour
    Oups !!!
    comme souligne par wallace ton probleme -savoir si une cible est valide ou, non - est specifique au jeu en question ( jeu de cartes que ignorons totalement ) et c'est une affaire de design qui n'as rien à voir avec le post initial concernant le deplacement d'un picturebox et le hit-testing d'un control par rapport à un autre....

    Comme suggere par wallace l'astuce consiste en general ,lorsque on utilise un control comme carte ou piece de jeu , à stocker dans un class separe fourre-tout les infos pertinentes sur la carte picbox : type ,valeur, player de la piece picbox, validite ,index de position etc...
    Ce class correctement renseigne est affecte à la prop Tag du du picbox lors de l'initialisation du jeu
    Ensuite requite lors des tests de deplacement de la carte picbox.,et mis à jour bien entendu....
    Il reflete l'etat de la carte à tout instant du jeu....
    bon code...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de Drag & Drop entre PictureBox V2
    Par Tuttu dans le forum Windows Forms
    Réponses: 15
    Dernier message: 02/09/2009, 10h04
  2. Drag and Drop entre 2 JTree
    Par Lebas dans le forum Composants
    Réponses: 1
    Dernier message: 07/02/2007, 11h59
  3. [Débutant(e)][VB.NET] Drag and drop entre 2 treeviews
    Par - Manuella Leray - dans le forum Windows Forms
    Réponses: 8
    Dernier message: 13/10/2005, 15h54
  4. [FLASH MX2004] Drag and drop entre deux List
    Par aldo-tlse dans le forum Flash
    Réponses: 15
    Dernier message: 24/09/2005, 01h10
  5. Drag and Drop entre listbox
    Par zwoke dans le forum C++Builder
    Réponses: 2
    Dernier message: 05/07/2004, 14h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo