Site: | Cours VB.net |
E 4.3 | Exemples:Dessin avec souris |
Un source très simple très didactique, pour dessiner avec la souris:
On appuie sur le bouton de la souris, on déplace la souris: cela dessine un trait.
Si on clique sur les boutons Rouge, Vert, Bleu cela change la couleur du trait.
Comment faire?
Dans Form1 on crée :
Une PictureBox définissant la zone de dessin: PictureBox1
Les boutons ButtonRouge, ButtonVert, ButtonBleu ayant dans leur propriété text respectivement 'Rouge', 'Vert', 'Bleu'.
Au niveau de la Classe on crée les variables ThePen de type Pen contenant la couleur en cours et PreviousPoint de type Point qui désigne le dernier point ou était la souris.
Les évènements Click des boutons
ButtonRouge, ButtonVert, ButtonBleu modifie la
couleur en cours:
ThePen.Color =
Color.Blue
Le dessin est effectué par les procédures évènement de la souris:
MouseDown enregistre le précédent Point (les coordonnées de la souris sont fournis par le paramètre e, ce sont e.X et e.Y)
MouseMove: On teste si la souris est 'capturée' sur le PictureBox (c'est à dire si on est en glissé: déplacement de la souris bouton appuyé, cela donne à PictureBox1.Capture la valeur True).
Si la souris est capturée:
If PictureBox1.Capture Then
On récupère le Graphics de PictureBox1:
Dim NewGraphic As Graphics = PictureBox1.CreateGraphics()
On trace sur le graphics une ligne du PreviousPoint au Point actuel avec ThePen:
NewGraphic.DrawLine(ThePen, PreviousPoint, NewPoint)
On détruit le graphics, puis on met dans PreviousPoint le point actuel.
Cela donne:
Imports System.Drawing
Public Class Form1
Inherits System.Windows.Forms.Form
Private PreviousPoint As Point ' Dernier point de la souris
Private ThePen As New System.Drawing.Pen(Color.Red) 'Un Pen pour dessiner.
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim NewPoint As New Point(e.X, e.Y)
PreviousPoint = NewPoint
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If PictureBox1.Capture Then
Dim NewPoint As New Point(e.X, e.Y)
Dim NewGraphic As Graphics = PictureBox1.CreateGraphics()
NewGraphic.DrawLine(ThePen, PreviousPoint, NewPoint)
NewGraphic.Dispose()
PreviousPoint = NewPoint
End If
End Sub
Private Sub ButtonRouge_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRouge.Click
ThePen.Color = Color.Red
End Sub
Private Sub ButtonVert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonVert.Click
ThePen.Color = Color.Green
End Sub
Private Sub ButtonBleu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonBleu.Click
ThePen.Color = Color.Blue
End Sub
End Class
Dans une version VB6 de ce programme, je n'utilisais pas Capture, aussi j'utilisais une variable Globale 'Tracer': MouseDown lui donnait la valeur True, MouseUp la valeur False et dans MouseMove on traçait si 'Tracer' était à True.
Mais c'est plus facile avec Capture.
Problème:
Si une fenêtre est positionnée sur notre fenêtre de dessin puis enlevée, le dessin disparaît!!
En VB6, la propriété AutoRedraw de l'image permettait de rappeler automatiquement le BitMap du dessin et de faire réapparaître l'image, cela n'existe plus en VB.Net!!
A- On peut écrire une nouvelle méthode OnPaint de l'image (on la substitue grâce à Overrides), elle est déclenchée à chaque fois que le contrôle est redessiné; on y met du code qui redessine (forme géométrique..).
Exemple afficher une ligne dans une form, qui restera affichée même si on redimensionne.
Protected
Overrides Sub OnPaint(ByVal e As PaintEventArgs) Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Red) Dim formGraphics As System.Drawing.GraphicsformGraphics =
Me.CreateGraphics()formGraphics.DrawLine(myPen, 0, 0, 200, 200)
myPen.Dispose()
formGraphics.Dispose()
End Sub
mais dans notre programme à moins d'enregistrer dans un tableau les coordonnées et couleur de chaque point puis de les redessiner un à un, ce n'est pas possible.
B- Comment faire l'équivalent de l'autoRedraw?
Class Form1
Private
PreviousPoint As Point ' Dernier point de souris Private ThePen As New System.Drawing.Pen(Color.Red) Private MyBitMap As Bitmap = New Bitmap(200, 200) 'Je crée un BitMapPrivate NewPoint As New Point 'point actuel
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
NewPoint =
New Point(e.X, e.Y)PreviousPoint = NewPoint
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If PictureBox1.Capture Then
Dim NewPoint As New Point(e.X, e.Y) Dim newgraphic As Graphics = Graphics.FromImage(MyBitMap) 'je crée un Graphics à partir du BitMapnewgraphic.DrawLine(ThePen, PreviousPoint, NewPoint) 'je dessine sur le Graphics
PictureBox1.Image = MyBitMap 'je passe le BitMap dans le PictureBox1
PreviousPoint = NewPoint
End If End Sub
End Class
Quand on crée un
Graphics depuis un contrôle comme dans la première version, le graphics ne
pointe pas sur la propriété image mais sur son affichage à l'instant T. Ce n'est
pas mémorisé.
Beaucoup de contrôles .net ont une propriété image. A chaque rafraîchissement du
contrôle si un bitMap est "attaché" à la propriété, le fond du contrôle est
affiché automatiquement. Le picturebox est le plus simple de ces contrôles ...
il ne fait que ça.
Donc en fait pour dessiner sur un contrôle (quel qu'il soit) tu n'as que 2
possibilités :
- Redessiner tout à chaque fois dans l'évènement Onpaint
- Lui affecter une image de fond et travailler sur celle ci