c'est un usercontrole composé d'un bouton et d'un label (comme un bouton normal quoi), sauf qu'il connait deux états, ON (bouton reste enfoncé/sunken) et OFF (bouton reste sorti/raised).
Il connait les propriétées suivantes:
- CaptionOFF (texte du bouton à l'état sorti)
- CaptionON (texte du bouton à l'état enfoncé)
- FireEventAfterChange (détermine si une évènement est lancé lorsque l'état du bouton est changé par du code)
- Look (2 états LookON ou LookOFF, peut être changé lors du design ou par code, avec/sans génération de l'évènement)
Il connait 2 évènements:
- ChangedToOn (envoyé après que l'utilisateur ait cliqué dessus et que le bouton devienne enfoncé)
- ChangedToOff (envoyé après que l'utilisateur ait cliqué dessus et que le bouton devienne sorti)
C'est pas très complexe, mais cela m'a été utile lors d'un projet, il montre:
- création complète d'un simple usercontrol
- comment générer des évèements
- utilisation de l'api DrawEdge
- utilisation d'un enum pour le choix de la propriété look du controle
- comment center un label sur bouton (représenté ici par le usercontrol)
- initialisation, sauvegarde et rappel des propriétés d'un usercontrol lors du design
Source / Exemple :
Option Explicit
' évènement lorsque l'utilisateur clique dessus et que le bouton devienne ON/enfoncé
Public Event ChangedToOn()
' évènement lorsque l'utilisateur clique dessus et que le bouton devienne OFF/sorti
Public Event ChangedToOff()
' structure qui tient l'aire du usercontrol (pour le repaint et le centrage du label)
Private m_ClientRec As RECT
' variable interne de la propriété - Texte lorsque le bouton est ON/enfoncé
Private m_CaptionON As String
' variable interne de la propriété - Texte lorsque le bouton est OFF/sorti
Private m_CaptionOFF As String
' variable interne de la propriété - état actuel du bouton
Private m_Look As LookType
' variable interne de la propriété - lancer un évènement lorsque l'état du bouton change par programmation
' l'évènement est toujours généré lorsque l'utilisateur clique dessus
Private m_FireEventAfterChangeLook
' enum de la propriété look du controle (la propriété se présente comme combobox)
Public Enum LookType
LookOff = 0
LookOn = 1
End Enum
' declarations Windows API
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Const BDR_RAISEDINNER = &H4 Or &H1
Private Const BDR_SUNKENOUTER = &H2 Or &H8
Private Const BF_RECT = &HF
Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, _
qrc As RECT, _
ByVal edge As Long, _
ByVal grfFlags As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Sub lblCaption_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
' si l'utilisateur clique sur le label
If Button = vbLeftButton Then
' changer l'apparance du bouton ON <-> OFF
If m_Look = LookOff Then
m_Look = LookOn
Else
m_Look = LookOff
End If
' redessiner le controle
UserControl_Paint
If m_Look = LookOn Then
' le bouton devient ON, lancer l'évènement
RaiseEvent ChangedToOn
Else
' le bouton devient OFF, lancer l'évènement
RaiseEvent ChangedToOff
End If
End If
End Sub
Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
' si l'utilisateur clique sur le usercontrol
If Button = vbLeftButton Then
' changer l'apparance du bouton ON <-> OFF
If m_Look = LookOff Then
m_Look = LookOn
Else
m_Look = LookOff
End If
' redessiner le controle
UserControl_Paint
If m_Look = LookOn Then
' le bouton devient ON, lancer l'évènement
RaiseEvent ChangedToOn
Else
' le bouton devient OFF, lancer l'évènement
RaiseEvent ChangedToOff
End If
End If
End Sub
Private Sub UserControl_Resize()
' le contrôle change de taille (par programmation ou lors du design)
' lire les nouvelles dimensions du contrôle
GetWindowRect UserControl.hwnd, m_ClientRec
' transformation des coordinés écran vers coordinés client
With m_ClientRec
.Right = .Right - .Left
.Bottom = .Bottom - .Top
.Left = 0
.Top = 0
End With
' redessiner le controle
UserControl_Paint
End Sub
Private Sub UserControl_Paint()
If Not UserControl.Ambient.UserMode Then
' permet d'insérer du code exécuté lors du design time
Else
' permet d'insérer du code exécuté lors du run time
End If
UserControl.Cls
If m_Look = LookOff Then
' changer le libellé du contrôle
lblCaption.Caption = m_CaptionOFF
' redessiner les bords sortis
DrawEdge UserControl.hdc, m_ClientRec, BDR_RAISEDINNER, BF_RECT
Else
' changer le libellé du contrôle
lblCaption.Caption = m_CaptionON
' redessiner les bords enfoncés
DrawEdge UserControl.hdc, m_ClientRec, BDR_SUNKENOUTER, BF_RECT
End If
' centrer le label sur le bouton/usercontrol
lblCaption.Top = (((m_ClientRec.Bottom - m_ClientRec.Top) * Screen.TwipsPerPixelY) - lblCaption.Height) / 2
lblCaption.Left = (((m_ClientRec.Right - m_ClientRec.Left) * Screen.TwipsPerPixelX) - lblCaption.Width) / 2
End Sub
Property Let CaptionOFF(c As String)
' exécuté lorsque le propriété est changée (run time et design time)
m_CaptionOFF = c
UserControl.Refresh
End Property
Property Get CaptionOFF() As String
' exécuté lorsque quelq'un demande le contenu de la propriété
CaptionOFF = m_CaptionOFF
End Property
Property Let CaptionON(c As String)
' exécuté lorsque le propriété est changée (run time et design time)
m_CaptionON = c
UserControl.Refresh
End Property
Property Get CaptionON() As String
' exécuté lorsque quelq'un demande le contenu de la propriété
CaptionON = m_CaptionON
End Property
Property Let Look(l As LookType)
' exécuté lorsque le propriété est changée (run time et design time)
m_Look = l
If m_FireEventAfterChangeLook Then
' lancer l'évènement que si la propriété 'FireEventAfterChangeLook' est vraie
' cela peut être le cas lors du design ou d'un changement par code
If m_Look = LookOn Then
RaiseEvent ChangedToOn
Else
RaiseEvent ChangedToOff
End If
End If
UserControl.Refresh
End Property
Property Get Look() As LookType
' exécuté lorsque quelq'un demande le contenu de la propriété
Look = m_Look
End Property
Property Let FireEventAfterChangeLook(f As Boolean)
' exécuté lorsque le propriété est changée (run time et design time)
' définit si le changement le l'état (effectué lors du design ou par code,
' pas par l'évènement clic) lance l'évènement ChangedToOn ou ChangedToOff
m_FireEventAfterChangeLook = f
End Property
Property Get FireEventAfterChangeLook() As Boolean
' exécuté lorsque quelq'un demande le contenu de la propriété
FireEventAfterChangeLook = m_FireEventAfterChangeLook
End Property
Private Sub UserControl_InitProperties()
' initialisation des propriétés lorsque le contrôle est mis sur un form
m_CaptionOFF = "Caption_OFF"
m_CaptionON = "Caption_ON"
m_Look = LookOff
m_FireEventAfterChangeLook = False
End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
' permet de récupérer le dernier état des propriétés lors du design et lors du lancement du code
m_CaptionOFF = PropBag.ReadProperty("CaptionOFF", "Caption_OFF")
m_CaptionON = PropBag.ReadProperty("CaptionON", "Caption_ON")
m_Look = PropBag.ReadProperty("Look", LookOff)
m_FireEventAfterChangeLook = PropBag.ReadProperty("FireEventAfterChangeLook", False)
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
' permet de sauver le dernier état des propriétés lors du design
PropBag.WriteProperty "CaptionOFF", m_CaptionOFF, "Caption_OFF"
PropBag.WriteProperty "CaptionON", m_CaptionON, "Caption_ON"
PropBag.WriteProperty "Look", m_Look, LookOff
PropBag.WriteProperty "FireEventAfterChangeLook", m_FireEventAfterChangeLook, False
End Sub
Conclusion :
Il suffit d'ajouter cmdOnOff.ctl au projet (préférable à du copier/coller du code car dans ce cas il faut encore y ajouter le label), il va se rajouter à la barre des controles. Depuis là, mettez le sur un form et éditez ses propriétés.
J'ai cherché un peu sur le web, mais je n'ai rien trouvé de finalisé et utilisable, donc j'ai consacré 2 heures à en faire un moi même. Il est encore pensable de l'étendre avec une image, mais à vous de la faire ...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.