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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
'NB: Les props BackColor, ForeColor, Location, ou
'Size, sont construites ad-hoc dans le controle de base CustomShape.
'ASTUCE:pour eviter de recreer brushes et pens chaque fois qu'une shape est dessinee, on peut creer brush
'& pen une seule fois et les memoriser comme variables membres.
'Mais alors=>il faut
'soit : s'assurer chaque fois que Brush et Pen n'ont pas ete change
'avant de commencer à dessiner
'soit: implementer les evenements ForeColorChanged & BackColorChanged events.
'
'
'Ajouter dans le Designer
'01 ContextMenuStrip nomme "mnuShape"
'et sa collection de 4 sous-menu:
'-mnuFillColorChange
'-mnuRemoveShape
'-mnuBringToFront
'-mnuBringToFront
Imports System.Drawing.Drawing2D
Public Class CustomShape
Inherits System.Windows.Forms.Control
'Met en surbrillance selection
Private selectionForeColor As Color = Color.Yellow
'BackStore du ForeColor pour retablir apres deselection
Private oldForeColor As Color
' Shape courant.
Private shape As ShapeType = ShapeType.Rectangle
Private path As GraphicsPath
' le type de shapes supporte par ce controle.
Public Enum ShapeType
Rectangle
Ellipse
Triangle
End Enum
Public Sub New()
' Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()
' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
'Affecte le ContextMenuStrip au controle
Me.ContextMenuStrip = Me.mnuShape
oldForeColor = Me.ForeColor
End Sub
Public Property Type() As ShapeType
Get
Return shape
End Get
Set(ByVal value As ShapeType)
shape = value
RefreshPath()
Me.Invalidate()
End Set
End Property
' Cree le GraphicsPath correspondant pour shape,
' et l'affecte à la prop Region du controle .
' Rappel: le Region d'un controle est sa zone interactive
Private Sub RefreshPath()
If path IsNot Nothing Then path.Dispose()
path = New GraphicsPath()
Select Case shape
Case ShapeType.Rectangle
path.AddRectangle(Me.ClientRectangle)
Case ShapeType.Ellipse
path.AddEllipse(Me.ClientRectangle)
Case ShapeType.Triangle
Dim pt1 As Point = New Point(Me.Width / 2, 0)
Dim pt2 As Point = New Point(0, Me.Height)
Dim pt3 As Point = New Point(Me.Width, Me.Height)
path.AddPolygon(New Point() {pt1, pt2, pt3})
End Select
Me.Region = New Region(path)
End Sub
' Redefinition OnPaint
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
If path IsNot Nothing Then
Dim shapeBrush As New SolidBrush(Me.BackColor)
Dim shapePen As New Pen(Me.ForeColor, 5)
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.FillPath(shapeBrush, path)
e.Graphics.DrawPath(shapePen, path)
shapePen.Dispose()
shapeBrush.Dispose()
End If
End Sub
' Redefinition OnResize
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
RefreshPath()
Me.Invalidate()
End Sub
'Enfin le ConTextMenuStrip "mnuShape" propose 4 options.
'1ere , sur click autorise l'user à changer couleur
'de remplissage avec boite color dialog.
'Le code retrouve le control shape actif avec la prop
'SourceControl du ContextMenuStrip
Private Sub mnuColorChange_Click(ByVal sender As Object, ByVal e As EventArgs) Handles mnuFillColorChange.Click
Dim colorDlg As New ColorDialog
If colorDlg.ShowDialog() = DialogResult.OK Then
Me.mnuShape.SourceControl.BackColor = colorDlg.Color
End If
End Sub
'2eme option autorise l'user à supprimer le shape courant selectionne.
Private Sub mnuRemoveShape_Click(ByVal sender As Object, ByVal e As EventArgs) Handles mnuRemoveShape.Click
Dim ctrl As Control
ctrl = Me
ctrl.Parent.Controls.Remove(Me)
End Sub
'2eme option et 4eme option pour Z-Order.
Private Sub mnuBringToFront_Click(ByVal sender As Object, ByVal e As EventArgs) Handles mnuBringToFront.Click
Me.BringToFront()
End Sub
Private Sub mnuSendToBack_Click(ByVal sender As Object, ByVal e As EventArgs) Handles mnuSendToBack.Click
Me.SendToBack()
End Sub
'- Click : selection du control position.
'- Right-Click : affiche context menu, qui prevoit les option
' -Delete Objet
' -Change FillColor
' -BringToFront
' -SendToBack
'- Click Coin Bas-Droit :redimensionnenement
' Garder une trace quand Dragging ou Redimensionnement sont actives.
Private isDragging As Boolean = False
Private isResizing As Boolean = False
' Memorise position ou l'user a clicke sur le controle.
Private clickOffsetX, clickOffsetY As Integer
Private Sub ctrl_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
' Retrouve une reference du shape actif.
Dim currentCtrl As Control
currentCtrl = CType(sender, Control)
If e.Button = MouseButtons.Right Then
' Affiche context menu.
mnuShape.Show(currentCtrl, New Point(e.X, e.Y))
ElseIf e.Button = MouseButtons.Left Then
' Redimensionnement
clickOffsetX = e.X
clickOffsetY = e.Y
If currentCtrl.Cursor = Cursors.SizeNWSE Or _
currentCtrl.Cursor = Cursors.SizeNS Or _
currentCtrl.Cursor = Cursors.SizeWE Then
' pointeur souris est sur l'un des cotes
' aussi le redimensionnement est approprie.
isResizing = True
Else
' Sinon Mode Dragging est approprie.
isDragging = True
End If
End If
End Sub
'MouseMove change position ou taille suivant mode "drag" ou "resize"
'MouseMove change aussi le curseur (feedback user) à un "icon resize"
'pour alerter l'user quand pointeur souris est aligne sur l'un des cotes .
Private Sub ctrl_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseMove
' Retrouve une reference du shape Actif.
Dim currentCtrl As Control
currentCtrl = CType(sender, Control)
If isDragging Then
' deplace controle shape.
currentCtrl.Left = e.X + currentCtrl.Left - clickOffsetX
currentCtrl.Top = e.Y + currentCtrl.Top - clickOffsetY
currentCtrl.ForeColor = Me.selectionForeColor
ElseIf isResizing Then
' Redimensionne control shape , suivant "resize mode".
currentCtrl.ForeColor = Me.selectionForeColor
If currentCtrl.Cursor = Cursors.SizeNWSE Then
currentCtrl.Width = e.X
currentCtrl.Height = e.Y
ElseIf currentCtrl.Cursor = Cursors.SizeNS Then
currentCtrl.Height = e.Y
ElseIf currentCtrl.Cursor = Cursors.SizeWE Then
currentCtrl.Width = e.X
End If
Else
' Change cursor si pointeur souris est sur le cote droit et bas
' du controle shape.
If (e.X + 5) > currentCtrl.Width And _
(e.Y + 5) > currentCtrl.Height Then
currentCtrl.Cursor = Cursors.SizeNWSE
ElseIf (e.X + 5) > currentCtrl.Width Then
currentCtrl.Cursor = Cursors.SizeWE
ElseIf (e.Y + 5) > currentCtrl.Height Then
currentCtrl.Cursor = Cursors.SizeNS
Else
' ce curseur souris est le 4eme type de curseur pour le pointeur souris
' utilise souvent pour deplacer les objets.
currentCtrl.Cursor = Cursors.SizeAll
End If
End If
End Sub
'MouseUp termine dragging et redimensionnement.
Private Sub ctrl_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseUp
Me.ForeColor = Me.oldForeColor
isDragging = False
isResizing = False
End Sub
End Class |
Partager