Créer un bouton d'aide contextuelle dans un formulaire Access

Ce document a pour but de vous montrer comment, de façon simpliste, créer un bouton d'aide contextuelle. Lorsque vous proposez une application avec des formulaires plutôt sophistiqués, il peut être intéressant de recourir à une petite aide dynamique permettant à tout utilisateur de bénéficier d'une explication en rapport avant de cliquer sur tel ou tel contrôle.

1 commentaire Donner une note à l'article (5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Avant-propos

Ce document a pour but de vous montrer comment, de façon simpliste, créer un bouton d'aide contextuelle.

Pourquoi simpliste ?
Parce qu'un formulaire Access et ses contrôles possèdent bien tout ce qu'il faut pour exploiter un fichier d'aide (*.chm ou *.hlp - contextuelle ou non) mais ne possèdent malheureusement pas de propriété WhatThisHelp (tout comme VB6 par exemple) ce qui fait que vous ne pourrez pas afficher une bulle d'aide comme l'illustre l'exemple issu de la boîte de dialogue Système vu à la section 6.

De ce fait, en affectant les propriétés Bouton d'aide et Contexte d'aide de votre formulaire, vous obtiendrez bien un bouton ? juxtaposé à côté de la croix de fermeture de la fenêtre (X), les boutons Min et Max devant être désactivés.

Cependant, lors du clic consécutif du ? et du contrôle interrogé, vous afficherez la page du fichier d'aide dans son contexte, si bien entendu, vous avez spécifié la propriété ContextID au contrôle...

Si la valeur 0 (zéro) reste au sein de cette propriété Contexte d'aide, ce sera l'aide de Microsoft Access qui sera affichée. Il est donc important de savoir que, si vous usez de cette propriété, il est fortement conseillé d'avoir un contexte d'aide (dans le fichier d'aide) pour chacun des contrôles.

Une fenêtre « couvrante » viendra alors s'afficher par-dessus votre application ce qui peut être un peu « lourd » pour l'action en cours.

Pour obtenir l'équivalent des petites bulles d'aide dynamiques, il faudrait alors faire appel aux API idoines ce qui tournerait la simplicité de ce tutoriel vers une approche plus sofistiquée et donc plus complexe, ce qui n'est pas sa vocation.
Cela fera sans doute l'objet d'un tutoriel spécifique ultérieurement...

En attendant, et si cela vous dit de continuer, voici le mode opératoire :

1-1. Niveau

Ce tutoriel s'adresse à toutes personnes connaissant l'environnement de développement Access et notamment la gestion des événements avec Visual Basic sur Microsoft Access.

1-2. Contact

Pour tous renseignements complémentaires, veuillez me contacter directement (Argyronet) par MP.

2. Préambule

Pourquoi une aide contextuelle ?

Lorsque vous proposez une application avec des formulaires plutôt sofistiqués, il peut être intéressant de recourir à une petite aide dynamique permettant à tout nouvel utilisateur de bénéficier d'une explication sur l'action qu'il s'apprête à effectuer avant de cliquer sur tel ou tel contrôle.

Et dans la vraie vie...

Dans le cadre du développement d'un projet pour un client, j'ai été amené à réaliser une application vouée à être internationalisée.
Aussi, pour parfaire son usage, j'ai pris la liberté de greffer à certains formulaires, du fait de leur relative complexité (d'un point de vue fonctionnel), un petit bouton d'aide contextuelle qui permet de connaître ce à quoi tel contrôle est voué et ce, dans le but de parer à toute confusion avant de l'utiliser et donc d'éviter une mauvaise manipulation.

J'ai alors décidé de vous faire profiter de cette petite fonctionalité, ma foi assez intéressante et presque utile...

3. Présentation du projet

Pour mettre en application ce tutoriel, il est nécessaire de disposer d'un fichier curseur représentant la flèche avec son point d'interrogation, que vous devez normalement trouver dans le dossier Cursors de Windows.

Image non disponible
Curseur utilisé pour l'aide contextuelle

 
Dans le doute, je vous propose de le télécharger en cliquant ici.

C'est grâce à l'API SetCursor() que l'on changera le pointeur sur l'événement associé.

Ensuite, sur le formulaire de votre choix, vous pouvez directement mettre en application ce tutoriel.
Si vous souhaitez simplement tester la mise en oeuvre de ce tutoriel sans agir sur un de vos formulaires existants, vous pouvez créer un formulaire de test comme celui-ci :

Image non disponible
Formulaire de test à créer



Dans ce formulaire, j'ai posé les contrôles susceptibles de confronter des utilisateurs à des questions.

Bien entendu, à la place de choisir l'aide contextuelle telle qu'elle va être abordée ici, vous pourriez très bien sur l'événement approprié, afficher un message d'information (Msgbox()) où serait inscrit systématiquement ce à quoi est destiné le contrôle sollicité avec la possibilité de se rétracter (Bouton Oui/Non ou Yes/No) mais cela peut à la longue poser problème quant au côté UserFriendly de votre application qui serait plus « lourde » à utiliser.

Ces contrôles, pour la démonstration, sont donc :

  • un bouton de commande (cmdCommandButton) ;
  • une case à cocher (chkACheckBox) ;
  • une liste déroulante (cboListItem) ;
  • une zone de texte (txtTextbox) ;

Il est entendu que vous pouvez attaquer tout type de contrôle auquel vous pensez devoir affecter une telle fonctionnalité.

4. Mise en oeuvre du projet

Comment fonctionne l'ensemble ?

De par la simplicité de ce tutoriel, vous allez constater que le code événementiel associé à l'appel de l'aide contextuelle reste assez peu volumineux en nombre de lignes... En fait, c'est la redondance des appels qui forme l'ampleur du code contenu dans la page de la classe du formulaire.
C'est pourquoi, lorsque vous maîtriserez bien le sujet, vous serez en mesure de concevoir une seule fonction générique qui englobera tous les paramètres requis et pourra être appelée avec moins de répétions pour chacun des contrôles.

Les procédures d'aides contextuelles

Pour mettre en application ce code, deux procédures principales sont nécessaires... et autant d'appels de ces procédures sont à affecter à chacun des événements des contrôles concernés.

Les procédures sont les suivantes :

  1. Une procédure servant à changer ou restaurer le pointeur de la souris (ChangeMousePointer) ;
  2. Une procédure servant à afficher l'aide contextuelle (WhatThisHelp).

Les événements sont les suivants :

  1. L'événement Control_MouseMove() régit le changement du pointeur de la souris en appelant ChangeMousePointer
  2. L'événement Control_MouseUp() affiche l'aide contextuelle en appelant WhatThisHelp
  3. L'événement Control_Click()* exécute le code qui lui est affecté lorsque l'aide est désactivée

* L'événement Click() pour les contrôle utilisant ce dernier

Notez au passage que l'événement MouseUp() a été expressément choisi du fait qu'il précède l'événement Click().

Cela permet alors d'agir sur le pointeur comme souhaité et d'exécuter en conséquence, tout bloc de code prévu par le développeur pour tel ou tel contrôle.

4-1. Création du formulaire de test

Partant du principe que vous allez certainement mettre en application ce tutoriel sur un projet existant, je considère que vous possédez tous les éléments de base pour commencer.

Dans l'absolu, il est idéal que le bouton ? soit disposé sur le formulaire de telle sorte à ce qu'il soit visible d'un point de vue ergonomique,
- soit en haut à droite,
- soit en bas à droite,
en vous insipirant du look du formulaire de test par exemple.

Vous pouvez procéder à l'inverse si votre application est destinée à des pays où le sens de lecture est de droite à gauche.

Je ne fais que le répéter dans la plupart de mes tutoriels mais j'insiste sur le fait qu'il est important de bien nommer les contrôles pour le succès de l'opération d'une part et pour une meilleure lisibilité du code d'autre part.

Rappel:

Pour plus d'informations sur la convention de nommage des objets, vous pouvez lire ce tutoriel.

Vous concevez donc ce formulaire de test en y posant les quatre contrôles spécifiés ci-avant et au bas de celui-ci, un contrôle Bouton Bascule que vous nommerez tglWhatThisHelp.

Vous pouvez en parallèle exploiter aussi la propriété Texte d'Info-bulle (ControlTipText) de manière à ce que l'utilisateur puisse prendre connaissance de façon succincte le rôle du contrôle survolé par le pointeur de la souris.
Le court résumé pour le bouton à bascule d'aide contextuelle serait alors :

« Cliquez-ici pour obtenir de l'aide sur l'usage des contrôles... »

(Voir illustration ci-après...)

Vous légenderez les contrôles de test comme bon vous semble et poserez un ? sur le bouton à bascule.

Vous devez alors obtenir cet écran une fois basculé en mode formulaire.

Image non disponible
Formulaire de test en mode formulaire

4-2. Mise en place du code du formulaire de test

Le programme dans son ensemble reste simple du fait que le code événementiel qui figure dans la classe du formulaire lui-même est répétitif...

La gestion de l'aide et du curseur à proprement parler sont incluses dans un module externe afin de pouvoir les partager avec d'autres formulaires dans le même cas si nécessaire.

4-2-1. Le code d'en-tête de module de classe du formulaire

Dans l'en-tête de ce module se trouvent les déclarations des constantes contenant les messages d'aide contextuelle d'une part, et une variable de module est déclarée pour vérifier que l'appel de l'aide est effective d'autre part.

Dans l'absolu, il aurait été préférable de stocker ces messages dans une table, le gestion n'en serait que plus facile : aussi, je vous laisse le soin de procéder à cette évolution si toutefois vous le jugez nécessaire.



Le code de l'en-tête de module

L'en-tête de module
Sélectionnez

''' ************************************************************************************
''' Project name        :   Simple WhatThisHelp
''' Module              :   Form_frmTest (Simple WhatThisHelp)
''' Type                :   Document VBA
''' Purpose             :   Formulaire de test principal
'''-------------------------------------------------------------------------------------
''' Created on          :   28/07/2010
''' Author              :   Jean-Philippe AMBROSINO
'''-------------------------------------------------------------------------------------
''' Contact WEB         :   http://argyronet.developpez.com
''' ************************************************************************************

Option Compare Database
Option Explicit

'Contenu des messages d'aide contextuelle
'Ces messages peuvent très bien être stockés dans une table
Private Const HLP_MSG_CHECKBOX                             As String = _
			"Le contrôle Case à cocher :" & vbCrLf & vbCrLf & _
			"Les événements régis sont les mêmes que ceux d'un bouton de commande..."
Private Const HLP_MSG_COMBOBOX                             As String = _
			"Le contrôle Liste déroulante :" & vbCrLf & vbCrLf & _
			"Les événements régis sont les mêmes que ceux de la zone de texte..."
Private Const HLP_MSG_COMMAND_BUTTON                       As String = _
			"Le contrôle Bouton de commande :" & vbCrLf & vbCrLf & _
			"Les événements régis sont :" & vbCrLf & _
			" - MouseMove pour obtenir le curseur," & vbCrLf & _
			" - MouseUp pour afficher l'aide" & vbCrLf & _
			" - Click pour exécuter la procédure attachée au bouton..."
Private Const HLP_MSG_TEXTBOX                              As String = _
			"Le contrôle Zone de texte :" & vbCrLf & vbCrLf & _
			"Les événements régis sont les mêmes que ceux d'un bouton de commande mais " & _
			"on exploite aussi l'argument Button pour vérifier que c'est le gauche qui est cliqué"
'Variables de module respectivement pour l'aide activée et pour le fichier curseur
Private m_blnWhatThisHelpOn                            As Boolean


4-2-2. Le code événement pour les contrôles

Les appels de procédures depuis les événements réagissent en fonction de l'activation de l'aide contextuelle, en d'autres termes, que la variable de module m_blnWhatThisHelpOn est passée à True.

Seul l'événement Click()* diffère dans son contenu du fait qu'il exécute autre chose qui sort du contexte de l'aide qui lui est associée.

* L'événement Click() pour les contrôles utilisant ce dernier



Le code du bouton de commande

Le bouton de commande
Sélectionnez

Private Sub cmdCommandButton_Click()
    If m_blnWhatThisHelpOn Then
        Exit Sub
    End If
    MsgBox "Procédure exécutée par le bouton de commande"
End Sub

Private Sub cmdCommandButton_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    ChangeMousePointer m_blnWhatThisHelpOn
End Sub

Private Sub cmdCommandButton_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lngTop                                             As Long
Dim lngLeft                                            As Long

    If m_blnWhatThisHelpOn Then
        With Me.cmdCommandButton
            lngTop = .Top + .Height * 2 + Me.WindowTop \ 2
            lngLeft = .Left + .Width * 2 + Me.WindowLeft \ 2
        End With
        WhatThisHelp HLP_MSG_COMMAND_BUTTON, cmdCommandButton.Caption, lngTop & ";" & lngLeft
    End If
End Sub

Dans l'événement Click() du Bouton de commande, on affiche un message pour la forme.

Il représente le comportement de ce même événement traduit par votre propre code qui serait effectivement exécuté par ce bouton.

Image non disponible



Le code de la case à cocher

La case à cocher
Sélectionnez


Private Sub chkACheckBox_Click()
    If m_blnWhatThisHelpOn Then
        Exit Sub
    End If
    MsgBox "Procédure exécutée par la case à cocher"
End Sub

Private Sub chkACheckBox_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    ChangeMousePointer m_blnWhatThisHelpOn
End Sub

Private Sub chkACheckBox_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lngTop                                             As Long
Dim lngLeft                                            As Long

    If m_blnWhatThisHelpOn Then
        With Me.chkACheckBox
            lngTop = .Top + .Height * 2 + Me.WindowTop \ 2
            lngLeft = .Left + .Width * 2 + Me.WindowLeft \ 2
        End With
        WhatThisHelp HLP_MSG_CHECKBOX, Me.lblCheckBox.Caption, lngTop & ";" & lngLeft
    End If
End Sub

Même code et même comportement que le Bouton de commande.

Cette Case à cocher est seule et ne dépend pas d'un contrôle Groupe d'option.
De ce fait, elle régit seule son propre jeu d'événements.

Dans le cas de l'usage d'un Groupe d'options (Control Frame), vous devrez agir sur la valeur de retour de ce dernier traduite par la valeur de l'option qui a été cochée par l'utilisateur.

En d'autres termes, user d'un
Select Case fraControlName.Value
ou d'un
Select Case Me!fraControlName
où fraControlName représente bien entendu le nom du contrôle.

Il vous appartiendra alors d'associer un message contextuel pour chacun des boutons d'option du cadre.

Dans l'événement Click() de la Case à cocher, on affiche un message avec la valeur du contrôle.

Il représente le comportement de ce même événement traduit par votre propre code qui serait effectivement exécuté par cette case.

Image non disponible



Le code de la zone de texte

La zone de texte
Sélectionnez


Private Sub txtTextbox_Click()
    If m_blnWhatThisHelpOn Then
        Exit Sub
    End If
    MsgBox "Pas de procédure exécutée par la zone de texte sur cet événement., Change étant plus approprié"
End Sub

Private Sub txtTextbox_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    ChangeMousePointer m_blnWhatThisHelpOn
End Sub

Private Sub txtTextbox_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lngTop                                             As Long
Dim lngLeft                                            As Long

    If Button = 1 Then
        If m_blnWhatThisHelpOn Then
            With Me.txtTextbox
                lngTop = .Top + .Height * 2 + Me.WindowTop \ 2
                lngLeft = .Left + .Width * 2 + Me.WindowLeft \ 2
            End With
            WhatThisHelp HLP_MSG_TEXTBOX, Me.lblTextBox.Caption, lngTop & ";" & lngLeft
        End If
    End If
End Sub

Dans le cas d'un type de contrôles autorisant la saisie ou la sélection de texte, on peut également intercepter et gérer l'événement MouseUp() ; toutefois, ce type de contrôles peut, de façon intuitive, (pour les adeptes du clic droit) tenter l'utilisateur de cliquer sur le bouton droit de la souris afin de bénéficier des options de texte en regard.

Par conséquent, on peut greffer à l'événement MouseUp() la condition permettant de vérifier par l'intermédiaire de l'argument Button, que l'utilisateur a bien utilisé le bouton gauche de la souris.

Dans l'événement Click() de la Zone de texte, on affiche également un message pour la forme.

Il représente le comportement de ce même événement traduit par votre propre code qui serait effectivement exécuté lorsque l'on clique dans la zone.

Image non disponible



Le code de la zone de liste déroulante

La liste déroulante
Sélectionnez


Private Sub cboListItem_Click()
    If m_blnWhatThisHelpOn Then
        Exit Sub
    End If
    MsgBox "Procédure exécutée par la zone de liste :" & vbCrLf & vbCrLf & "Selection = " & Me!cboListItem
End Sub

Private Sub cboListItem_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    ChangeMousePointer m_blnWhatThisHelpOn
End Sub

Private Sub cboListItem_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lngTop                                             As Long
Dim lngLeft                                            As Long

    If Button = 1 Then
        If m_blnWhatThisHelpOn Then
            With Me.cboListItem
                lngTop = .Top + .Height * 2 + Me.WindowTop \ 2
                lngLeft = .Left + .Width * 2 + Me.WindowLeft \ 2
            End With
            WhatThisHelp HLP_MSG_COMBOBOX, Me.lblComboBox.Caption, lngTop & ";" & lngLeft
        End If
    End If
End Sub

Dans le cas du contrôle Zone de liste déroulante (ComboBox), tout comme d'ailleurs une Zone de liste (ListBox), on exploite les mêmes événements qu'un contrôle de type bouton de commande car ces contrôles permettent la sélection de valeur(s) par l'intermédiaire de la souris de façon systématique.

Il est en effet rare de sélectionner des valeurs en utilisant les touches du clavier, sauf en cas de sélection par recherche littérale des premiers caractères.

J'ai ici aussi pris la liberté de procéder comme pour la zone de texte au niveau de la gestion de l'événement MouseUp().

Dans l'événement Click() de la Zone de liste déroulante, on affiche également un message avec la valeur de l'élément choisi.

Il représente le comportement de ce même événement traduit par votre propre code qui serait effectivement exécuté lorsque l'on clique sur un des éléments de liste.

Image non disponible



4-2-3. Le code événementiel du formulaire

Le seul événement de formulaire exploité ici est celui exécuté au chargement du formulaire (Form_Load()) avec la simple initialisation des contrôles.


Le code du chargement du formulaire

 
Sélectionnez

Private Sub Form_Load()
Dim R                                                  As Integer
Dim strRowSource                                       As String

    m_blnWhatThisHelpOn = False
    Me.tglWhatThisHelp.Value = False
    Me.chkACheckBox = False
    Me.txtTextbox = vbNullString

    For R = 1 To 10
        strRowSource = strRowSource & "Valeur # " & R & IIf(R = 10, vbNullString, ";")
    Next

    With Me.cboListItem
        .Value = vbNullString
        .RowSourceType = "Value List"
        .RowSource = strRowSource
    End With
End Sub

Pour la forme, je force expressément le contenu de la zone de liste, juste histoire d'avoir un élément à sélectionner.

4-2-4. Le code des procédures contextuelles

Les procédures de l'affichage de l'aide contextuelle figurent dans le même module que la gestion du pointeur effectuée par l'API SetCursor().



Les procédures d'aide contextuelles

Les procédures d'aide contextuelles
Sélectionnez


Public Sub WhatThisHelp(ByVal HelpMessage As String)
    DoCmd.OpenForm "frmContextHelp", , , , acFormAdd, , HelpMessage
End Sub

Public Sub ChangeMousePointer(ByVal ShowHelpCursor As Boolean)
Dim strCursorFilename                                  As String
    strCursorFilename = Application.CurrentProject.Path & "\Pictures\cntx_help.cur"
    If Dir(strCursorFilename, 0) = CUR_HELPCONTEXT_FILENAME Then
        If ShowHelpCursor Then
            ChangeCursor strCursorFilename
        Else
            Screen.MousePointer = 0
        End If
    End If
End Sub

- La procédure WhatThisHelp() se contente d'ouvrir un formulaire en mode Popup avec l'argument OpenArgs. Ce dernier est affecté avec le contenu de l'aide contextuelle à afficher, concaténé aux coordonnées du formulaire, dans un tableau de String.

- La procédure ChangeMousePointer() initialise le fichier curseur et s'il existe (ce qui est inévitable dans l'absolu) et que l'argument ShowHelpCursor est égal à True*, alors le pointeur prend la forme du curseur Aide/Flèche.
Si ShowHelpCursor est égal à False*, le pointeur retrouve sa forme par défaut.

* La valeur est représentée par la variable de module m_blnWhatThisHelpOn passée en paramètre

4-2-5. Le code de la gestion du pointeur

Le changement du pointeur est régi par la fonction ChangeCursor() qui utilise l'API SetCursor().

Elle exploite en amont l'API LoadCursorFromFile() qui créée un curseur basé sur une donnée contenue dans le fichier *.cur.

Gestion du pointeur
Sélectionnez

Private Declare Function LoadCursorFromFile Lib "user32" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As Long
Private Declare Function SetCursor Lib "user32" (ByVal hCursor As Long) As Long

Public Function ChangeCursor(ByVal CursorFilename As String) As Long
Dim lngRet                                   As Long

    On Error GoTo Error_On_ChangeCursor
    If Dir(CursorFilename) <> vbNullString Then
        lngRet = LoadCursorFromFile(CursorFilename)
        ChangeCursor = SetCursor(lngRet)
    End If

Exit_ChangeCursor:
    Exit Function
Error_On_ChangeCursor:
    Resume Exit_ChangeCursor
End Function

En cas d'erreur, aucun message ne s'affiche et donc n'empêche pas le déroulement de la procédure d'aide.
Dans ce cas, le pointeur garde son aspect par défaut.

Rappel

Le fichier curseur est à télécharger ici.

4-3. Création du formulaire d'aide contextuelle

Le formulaire d'aide doit s'afficher sous forme de « mini Popup » et donc être conçu avec une taille suffisamment petite pour ne pas encombrer le formulaire Parent d'une part et être auto-extensible en fonction du contenu qu'il devra afficher lorsqu'il sera ouvert d'autre part.

J'ai donc eu l'idée de m'inspirer (fortement il faut le reconnaître) du formulaire Post-It pour pouvoir fabriquer celui-ci.

Pour concevoir ce formulaire, vous pouvez vous référer au tutoriel expliquant comment concevoir un gestionnaire de Post-It que j'ai écrit précédemment, en cliquant ici

Il ne vous restera plus qu'à modifier :

  • un petit peu le contenu (suppression des contrôles inutiles) ;
  • le nom du contrôle principal recevant le contenu du message ;
  • l'îcône que vous pouvez télécharger ici ;
  • le nom du formulaire lui-même, en le nommant frmHelp ;
  • et enfin le code en conséquence que nous allons voir ci-après...
Image non disponible



Le code n'est pas tellement éloigné de la source initiale puisque ce formulaire a également besoin d'ajuster le contenu du texte par le biais de la fonction GetTextLength().

Vous recopierez ou importerez au sein de votre projet, le Module basPostIt depuis la page cible du tutoriel évoqué ci-dessus.
Lorsque le formulaire sera chargé, le texte affiché sera lisible dans son intégralité (sans troncature) grâce à ce procédé.

Il est confortable de pouvoir réutiliser un bloc de code, un formulaire ou tout autre élément déjà développé précédemment ; cela permet de gagner un temps non négligeable dans la phase du développement de vos projets.

4-3-1. Le code du formulaire frmHelp

Le formulaire frmHelp reçoit le code nécessaire à sa position sur l'écran ainsi que sa taille en fonction du message à afficher, tout comme le faisait le petit Post-It dans le tutoriel où vous avez recopié le module source.

La disposition est calculée au sein de l'événement Form_Load() et le recalcul de la hauteur nécessaire pour afficher l'ensemble du message est effectuée par le biais de l'événement Form_Current().
Je ne reviendrai pas sur les explications relatives à cette caractéristique issue de la fonction GetTextLength(), celles-ci étant abordées dans le tutoriel source.

Les autre blocs événementiels sont réservés à la possibilité (facultative) de pouvoir déplacer le formulaire depuis n'importe quelle zone physique qui le compose.

 
Sélectionnez

''' ************************************************************************************
''' Project name        :   Simple WhatThisHelp
''' Module              :   Form_frmHelp (Simple WhatThisHelp)
''' Type                :   Document VBA
''' Purpose             :   Popup d'Aide affichée en fonction du contexte
'''                         Ajustement de la hauteur en fonction du texte qu'il contient
'''-------------------------------------------------------------------------------------
''' Created on          :   28/07/2010
''' Author              :   Jean-Philippe AMBROSINO
'''-------------------------------------------------------------------------------------
''' Contact WEB         :   http://argyronet.developpez.com
''' ************************************************************************************

Option Compare Database
Option Explicit

Private Sub Form_Current()
'---------------------------------------------------------------------------
' Procedure     : Form_Current
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Calcule la hauteur nécessaire pour la zone de texte devant
'                 contenir le message avec la fonction GetTextLength()
'.......................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
Const MARGIN_HEIGHT                                    As Integer = 32

    Me.txtMessage.Height = GetTextLength(Me!txtMessage)
    Me.Section("Detail").Height = Me.txtMessage.Top + Me.txtMessage.Height + MARGIN_HEIGHT
    Me.InsideHeight = Me.Section("Detail").Height + MARGIN_HEIGHT
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
'---------------------------------------------------------------------------
' Procedure     : Form_KeyDown
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Ferme le formulaire
'...........................................................................
' Parameters    : KeyCode - Shift
' Return Codes  : Aucun
'---------------------------------------------------------------------------
Dim intAnswer                                          As Integer
    If KeyCode = vbKeyEscape Then
        DoCmd.Close acForm, Me.Name
    End If
End Sub

Private Sub Form_Load()
'---------------------------------------------------------------------------
' Procedure     : Form_Load
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Initialise la disposition du formulaire
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
Dim strMessage                                         As String
Dim strTitle                                           As String
Dim vntArgs                                            As Variant
Dim strArgs()                                          As String
Dim L                                                  As Long
Dim T                                                  As Long

    vntArgs = Me.OpenArgs

    strArgs = Split(vntArgs, "&#164;")
    If Not IsNull(vntArgs) Then
        strMessage = Replace(strArgs(0), "|", vbCrLf)
        strTitle = strArgs(1)
        Me.txtMessage.Value = strMessage
        Me.lblTitle.Caption = strTitle
    Else
        DoCmd.Close acForm, Me.Name
    End If

    T = CLng(Split(Nz(strArgs(2), 0), ";")(0))
    L = CLng(Split(Nz(strArgs(2), 0), ";")(1))

    If Me.Moveable Then
        Me.Move Left:=L, Top:=T
    End If
End Sub

Private Sub imgInfo_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : imgInfo_MouseMove
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    DragForm Me.hwnd
End Sub

Private Sub imgPostit_DblClick(Cancel As Integer)
'---------------------------------------------------------------------------
' Procedure     : imgPostit_DblClick
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Ferme le formulaire
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    DoCmd.Close acForm, Me.Name
End Sub

Private Sub imgPostit_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
' Procedure     : imgPostit_MouseMove
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    DragForm Me.hwnd                                      '---------------------------------------------------------------------------
End Sub

Private Sub lblTitle_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : lblTitle_MouseMove
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    DragForm Me.hwnd
End Sub

Private Sub txtMessage_DblClick(Cancel As Integer)
    DoCmd.Close acForm, Me.Name
End Sub

Private Sub txtMessage_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : txtMessage_MouseMove
' DateTime      : 28/07/2010
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    DragForm Me.hwnd
End Sub

Un bref commentaire explique le rôle de chacun des blocs.

Concernant plus particulièrement la position du formulaire, elle est calculée avec les valeurs des propriétés Left et Top du formulaire Parent, additionnées avec les propriétés Width et Height du contrôle émetteur de l'appel...

On passe alors ces valeurs au sein de l'argument OpenArgs du formulaire dans lequel se trouve également le contenu du message...

L'ensemble est alors décomposé à l'aide de la fonction Split() qui reconstitue les valeurs respectives selon le séparateur à savoir :

  • ¤ pour séparer le message des valeurs de position ;
  • | pour séparer les retours à la ligne dans le message ;
  • ; pour séparer la valeur Left de la valeur Top.

C'est la méthode Move() qui se charge de repositionner le formulaire au moment de son chargement...

5. Mise en exécution

Une fois cette étape terminée, vous basculez de nouveau sur votre formulaire (Alt+Tab) ou bien vous quittez l'éditeur Visual Basic Editor depuis le menu Fichier.

Vous enregistrez de manière à ne pas perdre votre travail et vous passez en Mode Formulaire.


Lorsque vous cliquez sur un des contrôles, il exécute le code événementiel associé soit par exemple, pour la zone de liste déroulante :

Image non disponible



À cet instant, lorsque vous cliquez sur le bouton à bascule, le pointeur change au profit du fameux curseur flèche + ? et le comportement du code change également en conséquence :

Image non disponible



Chacun des événements sur les contrôles vérifiera si la propriété est passée à True et exécutera, le cas échéant, l'appel de la procédure d'aide en rapport.

 

6. La propriété WhatThisHelp au sein de Windows

J'ai évoqué ici une méthode simple pour afficher une aide contextuelle selon un événement.

Dans l'environnement Windows ou encore dans les outils de développement dignes de ce nom comme Visual Basic 6.0 (et versions ultérieures), la propriété WhatTisHelp est native pour les contrôles.
Pour la mettre en application, il faut user d'un fichier d'aide CHM ou HLP dont les paragraphes sont attachés à un identifiant HelpContextID ce dernier étant le numéro devant figurer justement au sein de cette propriété, et ce, pour chaque contrôle visé.

Vous disposez ici d'un tutoriel pour concevoir un tel fichier.

Un exemple caractéristique est présent dans la boîte de dialogue Système du Panneau de configuration.

Image non disponible

7. Conclusion

Ce petit tutoriel relativement simple permettra aux personnes désireuses d'agrémenter leurs formulaires de mettre en place cette routine ma foi pratique et utile.

En dehors de son objectif initial, vous avez pu apprendre à gérer des événements émanant du périphérique de référence à votre environnement Windows, à savoir la souris et les contrôles de formulaire associés. Il semble de ce fait évident que ce tutoriel ouvre quelques perspectives dérivées pour profiter de ce cours et de les appliquer à d'autres usages similaires.

8. Remerciements

Je tiens à remercier toutes celles et ceux qui ont participé à la relecture de ce document en y incluant leurs remarques et en particulier :

- littledaem
- Caro-Line
- jacques_jean
- Ormonth
- Arkham46
- Philippe JOCHMANS
- GAYOT
- Claude Leloup pour la relecture correctrice.

9. Téléchargement

Vous pouvez télécharger la base exemple en cliquant ici

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.