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

Concevez un gestionnaire de Post-It pour vos applications Access

5 commentaires Donner une note à l´article (5)

Article lu   fois.

L'auteur

Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Avant-propos

Ce document a pour but de vous montrer comment concevoir un mini gestionnaire de Post-It pour vos applications Access.
Finalement, vous-même ou un utilisateur êtes informés d'une remarque – que vous ou un tiers avez enregistrée – par l'apparition d'un message à chaque lancement de l'application ou chargement d'un formulaire en particulier.

Ce petit plus qui enrichira votre application permettra de laisser un ou plusieurs messages (en quelque sorte privés) à un utilisateur de votre choix ou bien un message d'information visant à l'avertir de ne pas oublier d'effectuer telle ou telle opération comme la mise à jour d'une ou plusieurs fiches par exemple…

Pour réaliser ce tutoriel, je me suis intéressé de près au tutoriel de Cafeine : Un formulaire autoextensible pour Access.

I-A. Niveau

Ce tutoriel s'adresse plus particulièrement aux développeurs intermédiaires avec un bon niveau d'approche de la base de données Access.
La notion de savoir-faire en matière de programmation et de conception de formulaires graphiques est particulièrement requise.

Je vous recommande de lire le tutoriel sur les conventions typographiques ; cela vous permettra de mieux comprendre la nomenclature que j'adopte systématiquement pour nommer variables et contrôles…

I-B. Contact

Pour tous renseignements complémentaires, veuillez me contacter directement (Argyronet) par MP.
Pour des questions d'ordre technique, ayez la gentillesse de poster sur le forum en priorité.

I-C. Images

Les images représentant l'icône du bouton et le Post-It ont été dessinées à l'aide de Photoshop.
Elles ne sont pas disponibles en téléchargement.

I-D. Langue

Les commentaires du code de ce tutoriel sont rédigés en français.
Les noms des contrôles et les procédures de code sont, quant à eux, en anglais.

I-E. Versions

Ce tutoriel est applicable pour vos applications qui ont été développées à partir de la version 97 de Microsoft Access.
(Avec quelques adaptations pour la version 97.)

II. Présentation du projet

Lorsque j'ai créé l'application de « Gestion des traitements PeopleSoft » pour une entreprise dans laquelle j'ai travaillé, j'avais implémenté un gestionnaire de Post-It pour que les utilisatrices puissent se souvenir que telle tâche était à effectuer ou bien d'échanger avec des collègues des messages qui ne concernaient que l'application elle-même.

Il faut bien entendu se mettre dans le contexte pour comprendre la philosophie de l'ERP PeopleSoft et ce que les traitements nécessitent comme enrichissement d'informations et éviter d'oublier d'ajouter ou modifier telle ou telle tâche pour un job donné…
L'idée de mettre ce Mini Gestionnaire de Post-It permettait la mise en mémoire de messages pour soi-même ou pour un collègue sans passer par la messagerie interne et ainsi, éviter d'encombrer sa boîte à mails, qui plus est, avec le risque de ne pas les lire.

En effet, le gestionnaire de Post-It proposé ici est obligatoirement affiché pour l'utilisateur ciblé dès le chargement de l'application et ne peut donc pas l'ignorer, si peu que vous ayez tout mis en place pour.
C'est ce que je vais tenter de vous montrer dans ce tutoriel.

II-A. Idée de bouton pour générer un message

Dans l'illustration ci-dessous qui représente un menu principal (volontairement éclairci et flouté), j'ai mis en évidence le bouton d'appel du générateur de messages. Un clic sur ce bouton exécute l'ouverture du formulaire de rédaction d'un nouveau message…

Image non disponible

III. Gestion des messages

Pour mettre en œuvre ce tutoriel, il est nécessaire de concevoir deux formulaires :

- un pour la rédaction des messages ;
- un pour l'affichage des Post-It en mode Popup à partir du formulaire de votre choix.

Le formulaire dédié à la rédaction des messages est composé d'une liste déroulante qui contient les utilisateurs potentiels de votre application associée à une case à cocher qui permet de libérer cette liste pour choisir un autre utilisateur que vous-même.
Cette option est définie par défaut à l'ouverture du formulaire.
Il est effectivement sous-entendu dans ce projet que l'affichage des Post-It est dédié plutôt à vous-même comme un pense-bête. À partir du moment où vous affectez un message à un utilisateur en particulier, c'est cet utilisateur qui verra son application ouverte avec un message au premier plan avant qu'il puisse accéder à l'application.

En revanche, il n'est pas prévu dans ce projet de pouvoir choisir plusieurs destinataires d'un même message, mais rien ne vous empêche, et ce sans grosses modifications, de mettre cette option en place auquel cas il faudra adapter le code d'une part et ajouter un contrôle de Zone de liste qui se substituera à la Zone de liste déroulante.

Vous pourrez alors sélectionner un ou plusieurs utilisateurs, rédiger votre message et enfin l'enregistrer.

Le formulaire dédié à l'affichage des messages est un formulaire doté de propriétés particulières en ce qui concerne l'alimentation de la zone de texte puisque celle-ci adapte sa hauteur dynamiquement en fonction du contenu à afficher. Pour ce faire, une procédure qui calcule la hauteur nécessaire en fonction de la police de caractères est appelée systématiquement avant d'ouvrir le formulaire.
Sur ce formulaire, j'ai également ajouté la possibilité de le faire glisser à l'aide de la souris du fait que celui-ci est dépourvu de barre de titre.

III-A. Création du formulaire de rédaction des messages

Le formulaire permettant de rédiger des messages est composé de 11 contrôles…

Image non disponible


Tant que le message est en cours de rédaction, vous avez la possibilité de choisir un autre utilisateur ou d'annuler la rédaction de celui-ci.

III-A-1. Mode création

Pour réaliser ce formulaire, j'ai choisi une disposition verticale pour rappeler une feuille au format A4 en mode portrait.

Image non disponible

En haut du formulaire et en arrière-plan, se trouvent :

  • une image représentant une feuille cornée ;
  • sur celle-ci, au premier plan vous disposerez une autre image représentant l'illustration du bouton du menu principal vu ci-avant ;
  • une étiquette dans laquelle vous saisirez l'intitulé « Créer un message » ;
  • et enfin, un champ texte caché dont la source de contrôle* est l'identifiant du Post-It, à savoir IDPostIt.

* Source de contrôle : propriété facultative

Juste en dessous de cette image à quelques pixels, vous poserez :

  • Une case à cocher dont l'intitulé est « Pour un autre utilisateur que moi… »
  • La liste déroulante, quant à elle est disposée sur le même bord gauche que la case à cocher et contient la liste des utilisateurs avec leur identifiant.

Exemple de requête pour alimenter la liste déroulante :

 
Sélectionnez
SELECT IDUtilisateur, Prenom & " " & NomFamille AS NomComplet
FROM TBLUtilisateurs
WHERE IDUtilisateur <> 123456789;
ORDER BY NomFamille

Dans mon application, l'ID qui représente ma personne n'est pas, bien entendu 123456789, celui-ci étant stipulé comme tel pour la forme.

Il vous appartiendra d'adapter la condition WHERE en conséquence surtout si l'ID des utilisateurs de votre application est sous la forme

Alphabétique ou Alphanumérique.

Cette requête liste tous les utilisateurs potentiellement enregistrés dans la base de données en excluant intentionnellement l'utilisateur 123456789 qui est censé être vous-même à partir du moment où la case est cochée.

Dans la première colonne, c'est-à-dire la Colonne 0, l'IDUtilisateur est inscrit et la colonne est masquée.
En effet, la propriété Largeurs colonnes de la liste déroulante est égale à 0cm;4cm
C'est ce champ qui identifie l'utilisateur par une valeur unique en faisant office de Clé primaire.

Dans la seconde colonne, c'est-à-dire la Colonne 1, le champ NomComplet représente la concaténation des champs Prenom et Nom.
On suppose bien entendu que vous avez fait en sorte d'enregistrer ces informations avec la casse adéquate.

Si ce n'était pas le cas, rien ne vous empêche de forcer la mise en forme des caractères dans la requête elle-même avec respectivement

les fonctions StrConv() et UCase().

Pour plus d'informations concernant ces deux fonctions, je vous invite à consulter l'aide de Microsoft Access.

Vous dessinerez ensuite la Zone de texte devant recevoir le message juste en dessous de cette liste déroulante et encore au-dessous de celle-ci, un Rectangle dans lequel vous poserez :

  • Un bouton de commande intitulé Annuler
  • Un autre bouton de commande intitulé Enregistrer

Vous dessinerez enfin un autre Rectangle qui lui, détoure à la fois la zone de texte et la zone des boutons et ferez en sorte de faire mourir la bordure Haut de cette zone de texte sur la bordure Bas de l'image représentant la feuille cornée.

Image non disponible
Détail de la disposition des contrôles



Vous disposerez ce rectangle de manière à ce qu'il soit positionné en arrière-plan par rapport à tous les autres contrôles comme le montre la figurine ci-dessus…

III-A-2. Mode création (vue éclatée)

Pour plus de commodités en ce qui concerne la mise en place des contrôles, je vous propose de regarder la figurine ci-après qui représente la vue éclatée du formulaire. Ainsi, vous pouvez avoir un meilleur aperçu des contrôles utilisés et mieux appréhender leur agencement.

Image non disponible

Les informations détaillées qui concernent la disposition des contrôles se trouvent dans le tableau ci-après.

III-A-3. Tableau des contrôles du formulaire

Dans le tableau ci-dessous sont listés les 11 contrôles nécessaires à l'élaboration de ce formulaire.
Il y a donc :

  • 2 contrôles Textboxes (Zone de texte)
  • 2 contrôles Label (Étiquette) dont un attaché à sa Case à cocher
  • 2 contrôles Image (Image)
  • 1 contrôle Checkbox (Case à cocher)
  • 1 contrôle ComboBox (Liste déroulante)
  • 2 contrôles Shape (Rectangle)
  • 2 contrôles CommandButton (Bouton de commande)

Nom du contrôle

Type du contrôle

Haut*

Gauche*

Source de contrôle

Visible

Description

txtPostItContent

Zone de texte

150

1650

PostItContent

Oui

Zone de texte du message
(avec barre de défilement verticale)

imgPostIt

Image

30

30

-

Oui

Image représentant le Post-It corné

imgInfo

Image

120

90

-

Oui

Image représentant l'icône du bouton Post-It

lblTitle

Étiquette

1095

285

-

Oui

Intitulé « Créer un message »

lblOtherUser

Étiquette

375

975

-

Oui

Intitulé …« Pour un autre utilisateur que moi… »

chkAnotherUser

Case à cocher

150

1005

Shown

Non

Détermine si le message est adressé à un tiers

cmbUsers

ComboBox

150

1275

-

Oui

Identifiant de l'utilisateur (dans le code)

txtIDPostIt

TextBox

3570

180

IDPostIt

Non

Identifiant du Post-It (Clé primaire)

cmdCancel

Bouton

2340

5760

-

Oui

Bouton d'annulation

cmdSave

Bouton

3540

5760

-

Oui

Bouton de création du Post-It

shpBorder

Boîte

45

885

-

Oui

Cadre du formulaire

shpButtons

Boîte

150

5670

-

Oui

Cadre des boutons

* Les valeurs des positions Gauche et Haut sont définies en Twips.


Notez que la bordure dessinée illustrant une feuille cornée autant que celle de la zone de texte txtPostItContent sont de la même couleur. Toutefois, l'image ne possède pas de bordure Bas (dessinée graphiquement dans l'image elle-même), mais seulement une en haut, une à gauche et l'autre à droite.
Dans cet exemple, la couleur de bordure choisie est un gris semi-foncé (#8A8A61 en hexa).
Les autres contrôles voient leur bordure transparente.

Vous enregistrerez ce formulaire, une fois créé. Dans mon application, j'ai nommé ce formulaire : frmPopupPostIt_New.

L'ensemble du code de ce formulaire est vu plus loin à la section 6.

III-B. Rédaction d'un nouveau message

Pour rédiger un nouveau message, il suffira de passer en Mode formulaire, de cocher éventuellement la case si toutefois vous voulez affecter ce message à un autre utilisateur, le cas échéant, le choisir dans la liste et enfin, saisir le message dans la zone de texte prévue à cet effet.
Dans cette même zone de texte, il n'est pas prévu d'appuyer sur la touche Entrée pour passer à la ligne, mais vous pouvez forcer cette option en utilisant la combinaison de touches Ctrl+Entrée.

Au moment de l'ouverture du formulaire, seul le bouton Annuler est accessible ; il permet ainsi d'annuler la rédaction du message pour retourner à l'écran précédent. À partir du moment où vous avez commencé à saisir du texte, le bouton Enregistrer est disponible et vous permet d'enregistrer votre message pour qu'il soit pris en compte.

Il n'a pas été prévu de limitation ni de vérification en ce qui concerne le contenu du texte du message…

Il est sous-entendu que ce module complémentant votre application doit être utilisé à bon escient, même si de façon détournée, on peut à sa découverte s'amuser un peu avec, entre collègues…

Les messages sont stockés jusqu'à suppression par une confirmation.

IV. Affichage, Masquage d'un message avec suppression du Post-It

Le message s'affiche automatiquement à l'ouverture d'un formulaire défini.
Il est impossible de travailler sur l'application tant que ce message n'est pas masqué…

IV-A. Affichage du Post-It avec son message

Dès qu'un utilisateur ou vous-même possédez au moins un message, c'est le second formulaire (vu ci-après) qui est ouvert et s'affiche une fois que le formulaire appelant est lui-même chargé et affiché.

Image non disponible


J'entends par formulaire appelant, le formulaire depuis lequel vous redirigerez le code nécessaire à l'appel de la vérification de la présence de messages en fonction de l'utilisateur en cours et le cas échéant, appeler la procédure d'ouverture du formulaire Post-It.

IV-B. Masquage du Post-It avec suppression optionnelle

La seule possibilité prévue pour masquer le Post-It, c'est d'appuyer sur la touche Echap.

 
Sélectionnez
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyEscape Then
        '........... [Code vu plus loin]
    End If
End Sub

Une procédure est alors appelée et affiche le message suivant :

Image non disponible


Dans cette fenêtre, il est proposé de supprimer le message une fois ce dernier masqué.
Le bouton par défaut est le bouton Annuler.

  • Si vous cliquez sur Oui, le message est effacé de la table et ne peut plus être récupéré.
  • Si vous cliquez sur Non, le message est conservé et le Post-It fera de nouveau son apparition dans les mêmes circonstances.
  • Si vous cliquez sur Annuler, rien ne se passe, la fenêtre est simplement masquée

V. Conception du formulaire Post-It

La conception du formulaire du Post-It nécessite une plus grande attention.

Il existe une grande similitude entre le formulaire de Rédaction des messages et le formulaire d'Affichage des messages.
À la limite, pour gagner un petit peu de temps et éviter la redondance de travail, vous pouvez très bien dupliquer le formulaire de rédaction des messages que vous venez de créer et l'enregistrer sous le nom frmPopupPostIt ainsi que je l'ai fait dans mon application…
Vous n'aurez alors que peu de modifications à apporter, les plus grandes se résumant à la suppression des contrôles inutilisés et la rédaction du code correspondant.

La petite difficulté qui se greffe à la conception de ce formulaire se situe au niveau de la zone de texte qui contient donc le message : elle doit être disposée tout comme vous l'avez fait tout à l'heure avec le rectangle, à savoir, faire superposer sa bordure Haut juste en dessous de la bordure Bas de l'image représentant la feuille cornée.

V-A. La table des Post-It


Il est d'abord nécessaire de créer la table dans laquelle seront stockés les enregistrements correspondants à chacun des messages pour un utilisateur donné : chaque nouveau message enregistré est stocké dans une table.

Image non disponible
Table où sont stockés les messages



La Base de données
Il est important de noter que la base de données et l'application sont dissociées.
J'entends par là que vous devez, pour que le procédé de distribution des messages puisse être mis en œuvre, avoir une architecture base de données dorsale sur un serveur de fichiers et les bases de données frontales qui sont en fait les applications clientes, sur chaque poste de travail.
Dans un contexte autre, il ne sera pas possible de faire fonctionner le projet correctement.

Image non disponible



Structure de la table
Cette table est composée de quatre champs dont la description est stipulée dans le tableau suivant :

Nom du champ

Type

Description

IDPostIt

Entier long (Clé primaire)

Ce champ identifie de façon unique un message

IDUser

Entier long

Ce champ identifie l'utilisateur destinataire du message

PostItContent

Mémo

Ce champ est le contenu du message

Shown

Oui/Non

Ce champ définit si le message a été vu par son destinataire


La figurine ci-dessous représente la table en mode création :

Image non disponible


Il n'y a pas de propriétés particulières à définir pour chacun des champs, vous laisserez donc les propriétés par défaut qui s'affecteront d'elles-mêmes au fur et à mesure que vous choisirez le type de champ durant de la conception de la table.

Vous enregistrerez cette table, une fois créée. Dans mon application, j'ai nommé cette table tout simplement : TBLPostIt.

V-B. Le formulaire des Post-It

Le formulaire permettant de rédiger des messages est composé de 7 contrôles…

Image non disponible

V-B-1. Mode création

Pour réaliser ce formulaire (si peu que vous ayez choisi de le créer plutôt que de partir d'une copie), j'ai choisi une disposition horizontale.
Lorsque celui-ci sera affiché, la zone de texte contenant le message verra sa hauteur s'agrandir dynamiquement en fonction du nombre de messages s'il y en a plusieurs.

La source de contrôle du formulaire est bien entendu, la table que vous avez créée précédemment.

Image non disponible

En haut du formulaire et en arrière-plan, se trouvent :

  • une image représentant une feuille cornée ;
  • sur celle-ci, au premier plan vous disposerez une autre image représentant l'illustration d'une icône Infomation issue de la collection des icônes de la fonction MsgBox() ;
  • une étiquette dans laquelle vous saisirez l'intitulé « Vous avez un message » ;
  • et enfin, deux champs texte cachés dont les sources de contrôle sont respectivement :
    - l'identifiant du Post-It, à savoir IDPostIt,
    - l'identifiant de l'Utilisateur, à savoir IDUser.

Juste en dessous de cette image à quelques pixels, vous dessinerez ensuite la Zone de texte devant recevoir le message avec une hauteur d'environ 1,6 cm.

V-B-2. Mode création (vue éclatée)

Tout comme je vous l'ai proposé avec le précédent formulaire pour ce qui concerne la mise en place des contrôles, la figurine ci-après représente la vue éclatée du formulaire.

Image non disponible

Les informations détaillées qui concernent la disposition des contrôles se trouvent dans le tableau ci-après.

V-B-3. Tableau des contrôles du formulaire

Dans le tableau ci-dessous sont listés les 7 contrôles nécessaires à l'élaboration du formulaire.
Il y a donc :

  • 3 contrôles Textboxes (Zone de texte) ;
  • 1 contrôle Label (Étiquette) ;
  • 2 contrôles Image (Image) ;
  • 1 contrôle Checkbox (Case à cocher).

Nom du contrôle

Type du contrôle

Haut

Gauche

Source de contrôle

Visible

Description

txtPostItContent

Zone de texte

45

900

PostItContent

Oui

Zone de texte du message

imgPostIt

Image

30

30

-

Oui

Image représentant le Post-It corné

imgInfo

Image

105

90

-

Oui

Image représentant l'icône Info

lblTitle

Étiquette

705

210

-

Oui

Intitulé « Vous avez un message »

chkShown

Case à cocher

3135

630

Shown

Non

Détermine si le message est masqué ou supprimé

txtIDUser

TextBox

1980

630

IDUtilisateur

Non

Identifiant de l'utilisateur

txtIDPostIt

TextBox

885

630

IDPostIt

Non

Identifiant du Post-It (Clé primaire)

* Les valeurs des positions Gauche et Haut sont définies en Twips.


De façon identique, les bordures illustrant la feuille cornée et celle de la zone de texte txtContent sont de la même couleur, à savoir un gris semi-foncé (#8A8A61 en hexa).

Vous enregistrerez ce formulaire, une fois créé. Dans mon application, j'ai nommé ce formulaire : frmPopupPostIt.

V-B-3-a. Propriétés de la zone de texte txtPostItContent

Cette zone de texte se voit octroyer des propriétés particulières afin de réagir en conséquence du texte qu'elle va contenir, quelle qu'en soit sa longueur.

J'ai mis en surbrillance rose dans la fenêtre de propriétés ci-dessous, les valeurs des propriétés que vous devez appliquer si vous voulez un rendu identique.

Image non disponible


Rappel : la bordure dessinée illustrant une feuille cornée est de la même couleur que la bordure de la zone de texte.
L'objectif ici est de positionner la zone de texte txtPostItContent un plan en dessous de l'image imgPostIt de manière à ce que la bordure Haut de la zone de texte soit masquée par la bordure Bas de l'image…

V-B-3-b. Caractéristiques du formulaire

Le formulaire quant à lui doit posséder les propriétés suivantes :

Au niveau du format

Image non disponible

Au niveau des données

Image non disponible

Au niveau des événements

Image non disponible

Au niveau des autres propriétés

Image non disponible


L'ensemble du code de ce formulaire est vu plus loin à la section 6.

Note :

1/ La propriété Aperçu des touches (KeyPreview) doit avoir la valeur Oui.

2/ Prenez en compte que la précision des positions des contrôles autant que la largeur du formulaire déterminera la qualité graphique de votre Post-It.

VI. Le code Visual Basic du projet

Ce projet, bien que coiffé de deux petits formulaires relativement simplifiés, possède un jeu de lignes de code assez volumineux.
Le code se décompose ainsi :

  • Formulaire de rédaction des messages ;
  • Formulaire d'affichage des messages ;
  • Extrait du Formulaire appelant (ici, le Menu principal) ;
  • Définition dynamique de la hauteur du contrôle Textbox.

Chaque formulaire désactive la molette de la souris à l'aide de la classe MouseWheel.CMouseWheel()
Pour plus d'informations à ce sujet, veuillez vous reporter dans la FAQ ou consulter les tutoriels concernés.

 

VI-A. Code du module de classe du formulaire de rédaction des messages

Ce formulaire possède deux événements :

  • un événement de Chargement du formulaire ;
  • un événement de Fermeture du formulaire.

Les autres événements sont régis par les différents contrôles du formulaire…
J'ai également posé des procédures privées qui sont appelées par certains de ces événements.

Module de classe du formulaire frmPostItNew
Sélectionnez
''' ************************************************************************************
''' Project name        :   Gestionnaire de Post-It pour applications Access
''' Purpose             :   Module dédié aux calculs nécessaires à l'ajustement du contrôle
'''                         du formulaire en fonction du texte qu'il contient
'''-------------------------------------------------------------------------------------
''' Module              :   frmPostItNew - Classe
''' Created on          :   28/07/2008
''' Author              :   Jean-Philippe AMBROSINO
'''-------------------------------------------------------------------------------------
''' Contact WEB         :   http://argyronet.developpez.com
''' ************************************************************************************

Option Compare Database
Option Explicit

''' Classe de la gestion de la molette de la souris
Private WithEvents clsMouseWheel As MouseWheel.CMouseWheel

Private Sub chkAnotherUser_Click()
'---------------------------------------------------------------------------
' Procedure     : chkAnotherUser_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement clic de la case à cocher permettant de choisir un autre utilisateur
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
Dim oQDF                                As DAO.QueryDef
Dim SQLSelect                           As String
Dim lngIDUser                           As Long

    ''' Requête contenant les utilisateurs
Const QUERY_USERLIST                       As String = "qry_Combo_GetListOfUsers"
    
    ''' Obtention de l'ID utilisateur
    lngIDUser = GetCurrentIDUser()
    ''' Construction de la chaîne SQL visant à mettre à jour la requête
    SQLSelect = "SELECT TBL_Users.IDUser, [LastName] &" & Chr(34) & " " & Chr(34) & _
    "& [FirstName] AS FullName"
    SQLSelect = SQLSelect & vbCrLf & "FROM TBL_Users"
    SQLSelect = SQLSelect & vbCrLf & "WHERE TBL_Users.IDUser <> " & lngIDUser & _
    " AND TBL_Users.IDUser <> " & DATA_IDU_NONE & " AND TBL_Users.IsActivated=True;"
    ''' Affectation d'un objet QueryDefs avec la nouvelle valeur SQL
    Set oQDF = CurrentDb.QueryDefs(QUERY_USERLIST)
    oQDF.SQL = SQLSelect
    '''Si c'est un autre utilisateur que vous
    If Me!chkAnotherUser Then
        ''' On affecte la requête à la propriété RowSource et toutes les propriétés corrélatives
        With cmbUsers
            .RowSource = QUERY_USERLIST
            .Enabled = True
            .Locked = False
            .SetFocus
            .Dropdown
        End With
    Else
        ''' On donne le focus directement à la zone de texte avec toutes les propriétés corrélatives
        txtPostItContent.SetFocus
        With cmbUsers
            .RowSource = vbNullString
            .Locked = True
            .Enabled = False
        End With
        Me!cmbUsers = vbNullString
    End If
End Sub

Private Sub clsMouseWheel_MouseWheel(Cancel As Integer)
'---------------------------------------------------------------------------
' Procedure     : chkAnotherUser_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseWheel de la classe clsMouseWheel :
'                 Désactive la molette (Version Access 2000)
'...........................................................................
' Parameters    : Cancel => True = Désactivé
' Return Codes  : Aucun
'---------------------------------------------------------------------------
  Cancel = True
End Sub

Private Sub cmdCancel_Click()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement clic du bouton Annuler :
'                 Annule le message et ferme le formulaire
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    If MsgBox("Souhaitez-vous annuler la création du Post-It ?", _
    vbExclamation + vbYesNo, "Annuler") = vbYes Then
      On Error Resume Next
      DoCmd.RunCommand acCmdUndo
      If err <> 0 Then err.Clear
      DoCmd.Close acForm, Me.Name
      DoCmd.OpenForm "frmMainMenu", acNormal, , , , acDialog
    End If
End Sub

Private Sub cmdSave_Click()
Dim strFrom As String
Dim strDate As String
Dim SQLSelect As String

Dim lngIDUser As Long
Dim strPreviousMessage As String
Dim strPostItContent As String
Dim strNewMessage As String
Dim blnShown As Boolean

Dim blnAlreadyGotMessage As Boolean
Dim blnForMeOnly As Boolean

Dim oRS As DAO.Recordset
  ''' On vérifie que le message n'est pas vide avant d'enregistrer
  If IsNull(strPostItContent) Or Len(strPostItContent) < 3 Then
    MsgBox "Un message doit être inscrit avant d'enregistrer !", _
    vbExclamation, "Message requis"
    Exit Sub
  End If
  ''' On définit alors le nom de l'émetteur du message à l'aide de l'API GetUserName()
  ''' et de la table des utilisateurs
  strFrom = GetCurrentUserName(True)
  ''' on définit la date du jour de rédaction du message
  strDate = "Le " & Format(Now, "d mmmm yyyy") & " à " & _
  Left(Format(Now, "hh:mm"), 2) & "h" & Right(Format(Now, "hh:mm"), 2) & ", "
  ''' On définit le destinataire du message : vous-même ou un autre utilisateur
  If IsNull(Me!chkAnotherUser) Then
    lngIDUser = GetCurrentIDUser()
    blnForMeOnly = True
  Else
    If Me!chkAnotherUser Then
      lngIDUser = Me!cmbUsers
      blnForMeOnly = False
    Else
      lngIDUser = GetCurrentIDUser()
      blnForMeOnly = True
    End If
  End If
  ''' On vérifie si le destinataire du message possède déjà un autre message
  strPreviousMessage = GetStringFieldValueFromTable( _
  "TBLPostIt", "IDUser", "PostItContent", lngIDUser)
  blnAlreadyGotMessage = (Len(strPreviousMessage) > 0)
  ''' Construction de la clause SQL
  SQLSelect = "SELECT IDUser, PostItContent, TypeOfMessage, Shown, FormName, IDKeyCriteria"
  SQLSelect = SQLSelect & vbCrLf & "FROM TBLPostIt"
  ''' Rédaction du message en fonction du destinataire
  If blnForMeOnly Then
    If blnAlreadyGotMessage Then
      strPostItContent = vbCrLf & vbCrLf & strDate & _
      "je me suis de nouveau écrit ce message :" & vbCrLf & Me!txtPostItContent
      SQLSelect = SQLSelect & vbCrLf & "WHERE IDUser = " & lngIDUser
    Else
      strPostItContent = strDate & "je me suis écrit ce message :" & vbCrLf & Me!txtPostItContent
    End If
  Else
    If blnAlreadyGotMessage Then
      strPostItContent = vbCrLf & vbCrLf & strDate & strFrom & _
      " vous a écrit :" & vbCrLf & Me!txtPostItContent
      SQLSelect = SQLSelect & vbCrLf & "WHERE IDUser = " & lngIDUser
    Else
      strPostItContent = strDate & strFrom & " vous a écrit :" & vbCrLf & Me!txtPostItContent
    End If
  End If
  ''' Affectation à la variable du message et de son contenu
  strNewMessage = strPreviousMessage & strPostItContent
  ''' On réinitialise certains contrôles
  blnShown = False
  strFormName = vbNullString
  lngIDKeyCriteria = 0
  ''' Selon le cas, on met à jour ou on ajoute un enregistrement dans la table
  On Error GoTo L_ErrCannotAddData
  Set oRS = CurrentDb.OpenRecordset(SQLSelect, 2)
  With oRS
    If blnAlreadyGotMessage Then
      .Edit     ' Met à jour
    Else
      .AddNew   ' Ajoute l'enregistrement
    End If
    .Fields("IDUser") = lngIDUser
    .Fields("PostItContent") = strNewMessage
    .Fields("Shown") = blnShown
    .update
  End With
  Set oRS = Nothing
  ''' Affectation des contrôles
  cmdCancel.Caption = CMD_CLOSE
  cmdCancel.SetFocus
  chkAnotherUser.Enabled = False
  txtPostItContent.Locked = True
  cmdSave.Enabled = False
L_ExCannotAddData:
  ''' Libération des objets instanciés
  Set oRS = Nothing
  Exit Sub
L_ErrCannotAddData:
  MsgBox Err.Description, vbCritical, Err
  Resume L_ExCannotAddData
End Sub

Private Sub Form_Close()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement Close du formulaire
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
  On Error Resume Next
  clsMouseWheel.SubClassUnHookForm
  Set clsMouseWheel.Form = Nothing
  Set clsMouseWheel = Nothing
End Sub

Private Sub Form_Load()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement Load du formulaire : initialise la classe MouseWheel
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
  Set clsMouseWheel = New MouseWheel.CMouseWheel
  Set clsMouseWheel.Form = Me
  clsMouseWheel.SubClassHookForm
End Sub

Private Sub imgInfo_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'image représentant l'icône
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub

Private Sub imgPostIt_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'image représentant la feuille
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub

Private Sub lblTitle_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'étiquette du titre du message
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub
Private Sub txtPostItContent_Change()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement Change de la zone de texte
'                 Libère l'état du bouton Enregistrer
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
  cmdSave.Enabled = (Len(Me!txtPostItContent.Text) > 0)
End Sub
Private Sub MoveForm(F As Form)
'---------------------------------------------------------------------------
' Procedure     : MoveForm
' DateTime      : 17/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déplacer un formulaire dépourvu de barre de titre
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    ReleaseCapture
    SendMessageCapture F.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
End Sub

VI-A-1. La fonction GetCurrentIDUser()

Cette fonction « maison » renvoie un IDUtilisateur présent dans la table des utilisateurs en fonction d'un critère soumis à une condition Where
Cette table contient tous les champs relatifs aux informations concernant directement les utilisateurs de votre application.
Parmi ces champs figure le Login (nom d'utilisateur de la session Windows).

Pour obtenir l'ID, j'ai donc posé cette fonction qui, à l'aide de l'APIGetUserName(), me permet d'interroger la table via un objet DAO.Recordset dans lequel je passe une chaîne SQL contenant le critère Login = GetUserName()

La valeur retournée par ma fonction est donc le champ que je souhaite, à savoir, le champ IDUtilisateur, clé primaire de la table…

Vous ne devriez donc avoir aucune difficulté pour concevoir cette fonction…

 

VI-B. Code du module de classe du formulaire d'affichage des messages

Ce formulaire possède quatre événements :

  • un événement de Chargement du formulaire ;
  • un événement d'Activation du formulaire ;
  • un événement de Fermeture du formulaire ;
  • un événement de gestion des séquences de Touche appuyée du clavier.

Les autres événements sont régis par les différents contrôles du formulaire…
J'ai également posé des procédures privées qui sont elles aussi appelées par certains de ces événements.

 
Sélectionnez
''' ************************************************************************************
''' Project name        :   Gestionnaire de Post-It pour applications Access
''' Purpose             :   Module dédié aux calculs nécessaires à l'ajustement du contrôle
'''                         du formulaire en fonction du texte qu'il contient
'''-------------------------------------------------------------------------------------
''' Module              :   frmPostIt - Classe
''' Created on          :   28/07/2008
''' Author              :   Jean-Philippe AMBROSINO
'''-------------------------------------------------------------------------------------
''' Contact WEB         :   http://argyronet.developpez.com
''' ************************************************************************************

Option Compare Database
Option Explicit

''' Classe de la gestion de la molette de la souris
Private WithEvents clsMouseWheel        As MouseWheel.CMouseWheel
Private Sub clsMouseWheel_MouseWheel(Cancel As Integer)
'---------------------------------------------------------------------------
' Procedure     : chkAnotherUser_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseWheel de la classe clsMouseWheel :
'                 Désactive la molette (Version Access 2000)
'...........................................................................
' Parameters    : Cancel => True = Désactivé
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    Cancel = True
End Sub

Private Sub Form_Close()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement Close du formulaire
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    On Error Resume Next
    clsMouseWheel.SubClassUnHookForm
    Set clsMouseWheel.Form = Nothing
    Set clsMouseWheel = Nothing
End Sub

Private Sub Form_Current()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement Current du formulaire
'                 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.txtPostItContent.Height = GetTextLength(Me!txtPostItContent)
    Me.Section("Detail").Height = Me.txtPostItContent.Top + _
        Me.txtPostItContent.Height + MARGIN_HEIGHT
    Me.InsideHeight = Me.Section("Detail").Height + MARGIN_HEIGHT
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement KeyDown du formulaire
'
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
Dim intAnswer                           As Integer
    If KeyCode = vbKeyEscape Then
        intAnswer = MsgBox("Voulez-vous supprimer ce message avant de fermer ?", _
            vbQuestion + vbDefaultButton3 + vbYesNoCancel, "Supprimer")
        Select Case intAnswer
            Case vbCance ' On sort
                Exit Sub
            Case vbNo   ' On affecte True à la case à cocher
                Me!chkShown = True
            Case vbYes  ' On supprime le message via la procédure DeleteMessage()
                DeleteMessage Me!txtIDUser
        End Select
        DoCmd.Close acForm, Me.Name
    End If
End Sub

Private Sub Form_Load()
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement Load du formulaire : initialise la classe MouseWheel
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    Set clsMouseWheel = New MouseWheel.CMouseWheel
    Set clsMouseWheel.Form = Me
    clsMouseWheel.SubClassHookForm
End Sub

Private Sub imgInfo_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'image représentant l'icône
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub

Private Sub imgPostIt_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'image représentant la feuille
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub

Private Sub lblTitle_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'étiquette du titre du message
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub

Private Sub txtPostItContent_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---------------------------------------------------------------------------
' Procedure     : cmdCancel_Click
' DateTime      : 28/07/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Evénement MouseMove de l'étiquette du titre du message
'                 Permet de déplacer la fenêtre
'...........................................................................
' Parameters    : Button, Shift, X, Y (Voir Aide - F1)
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    MoveForm Me
End Sub

Private Sub DeleteMessage(ByVal IDUser As Long)
'---------------------------------------------------------------------------
' Procedure     : DeleteMessage
' DateTime      : 17/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Supprime tous les messages de l'utilisateur sélectionné
'...........................................................................
' Parameters    : IDUser = identifiant de l'utilisateur
' Return Codes  :
'---------------------------------------------------------------------------
Dim oRS                                 As DAO.Recordset
    Set oRS = CurrentDb.OpenRecordset( _
    "SELECT * FROM TBLPostIt WHERE IDUser = " & txtIDUser, dbOpenDynaset)
    With oRS
        If Not .EOF Then
            Do While Not .EOF
                .Delete
                .MoveNext
            Loop
        End If
        .Close
    End With
    Set oRS = Nothing
End Sub
Private Sub MoveForm(F As Form)
'---------------------------------------------------------------------------
' Procedure     : MoveForm
' DateTime      : 17/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déplacer un formulaire dépourvu de barre de titre
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Aucun
'---------------------------------------------------------------------------
    ReleaseCapture
    SendMessageCapture F.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
End Sub

VI-C. Code du module de classe du formulaire parent

C'est ce formulaire qui vous permettra à la fois de générer de nouveaux messages et de les voir apparaître au moment du chargement grâce à la minuterie. Vous exploiterez alors un seul événement pour l'affichage des messages :

  • l'événement Timer du formulaire.

Il existe également dans ce même formulaire, un bouton permettant de générer de nouveaux messages.

  • Ce bouton déclenche alors l'événement Click
 
Sélectionnez
''' ************************************************************************************
''' Project name        :   Gestionnaire de Post-It pour applications Access
''' Purpose             :   Module dédié aux calculs nécessaires à l'ajustement du contrôle
'''                         du formulaire en fonction du texte qu'il contient
'''-------------------------------------------------------------------------------------
''' Module              :   frmMainMenu - Classe
''' Created on          :   28/07/2008
''' Author              :   Jean-Philippe AMBROSINO
'''-------------------------------------------------------------------------------------
''' Contact WEB         :   http://argyronet.developpez.com
''' ************************************************************************************

Option Compare Database
Option Explicit

''' [....]
''' [....]
''' [Blocs des autres événements]
''' [....]

Private Sub cmdNewPostIt_Click()
'---------------------------------------------------------------------------
' Procedure     : cmdNewPostIt_Click
' DateTime      : 17/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de générer un nouveau message
'...........................................................................
' Parameters    : Aucun
' Return Codes  :
'---------------------------------------------------------------------------
  DoCmd.OpenForm "frmPopupPostIt_New", , , , acFormAdd, acDialog
End Sub

''' [....]
''' [....]
''' [Blocs des autres événements]
''' [....]
Private Sub Form_Timer()
'---------------------------------------------------------------------------
' Procedure     : Form_Timer
' DateTime      : 17/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Permet de déterminer s'il faut afficher un message
'                 On obtient l'ID utilisateur et on compte ses messages
'...........................................................................
' Parameters    : Aucun
' Return Codes  :
'---------------------------------------------------------------------------
Dim intNBMessages                       As Integer
Dim lngCurrentUser                      As Long
Dim strSQL                              As String
Dim oRS                                 As DAO.Recordset
    '''On désactive le Timer
    Me.TimerInterval = 0
    ''' On compte le nombre de messages
    strSQL "SELECT COUNT(*) FROM TBLPostIt WHERE IDUser = " & GetCurrentIDUser()
    Set oRS = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
    With oRS
        If Not .EOF Then
            ''' On ouvre le formulaire
            DoCmd.OpenForm "frmPopupPostIt", , , "[IDUser]=" & lngCurrentUser, acFormEdit, acDialog
        End If
        .Close
    End With
    Set oRS = Nothing
End Sub
''' [....]
''' [....]
''' [Blocs des autres événements]
''' [....]

VI-D. Module basPostIt : Définition dynamique de la hauteur du contrôle Textbox

Il s'avère que la propriété Auto extensible ne répond pas correctement au véritable contenu du texte et ainsi, tronque une partie du texte.
Il a donc été nécessaire de mettre en place une routine qui le permet.
Pour définir dynamiquement la hauteur du contrôle Textbox contenant le message du Post-It, le formulaire exploite la fonction GetTextLength() qui calcule la hauteur nécessaire. Elle est écrite dans le module suivant :

Module basPostIt
Sélectionnez
''' ************************************************************************************
''' Project name        :   Gestionnaire de Post-It pour applications Access :
''' Purpose             :   Module dédié aux calculs nécessaires à l'ajustement du contrôle
'''                         Textbox du formulaire en fonction du texte qu'il contient
'''-------------------------------------------------------------------------------------
''' Module              :   basPostIt - Module
''' Created on          :   28/07/2008
''' Author              :   Jean-Philippe AMBROSINO
'''-------------------------------------------------------------------------------------
''' Contact WEB         :   http://argyronet.developpez.com
''' ************************************************************************************

Option Compare Database
Option Explicit

''' API et constante de déplacement de la fenêtre
Public Declare Function ReleaseCapture Lib "user32" () As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const WM_NCLBUTTONDOWN = &HA1
Public Const HTCAPTION = 2

' API dédiée à obtenir les caractéristiques d'un périphérique
Private Declare Function GetDeviceCaps Lib "gdi32" ( _
ByVal lngDC As Long, ByVal nIndex As Long) As Long

' API permettant de définir les informations du contexte d'un périphérique donné
Private Declare Function CreateIC Lib "gdi32" Alias "CreateICA" ( _
ByVal lpDriverName As String, ByVal lpDeviceName As String, _
ByVal lpOutput As String, lpInitData As Any) As Long

' API permettant de supprimer le contexte spécifié (DC)
Private Declare Function DeleteDC Lib "gdi32" ( _
ByVal lngDC As Long) As Long

' API permettant de sélectionner un objet dans un contexte
Private Declare Function SelectObject Lib "gdi32" ( _
ByVal lngDC As Long, ByVal hObject As Long) As Long

' API permettant de supprimer un objet dans un contexte
Private Declare Function DeleteObject Lib "gdi32" ( _
ByVal hObject As Long) As Long

' API permettant de "dessiner" du texte formaté dans un rectangle selon des spécifications
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" ( _
ByVal lngDC As Long, ByVal lpStr As String, ByVal nCount As Long, _
lpRect As RECT, ByVal wFormat As Long) As Long

' API dédiée à la création d'une police logique avec caractéristiques identiques à l'originale
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" ( _
lpLogFont As LOGFONT) As Long

' API Retourne le Handle d'un contexte
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

' API dédiée à libérer la mémoire pour un contexte donné
Private Declare Function ReleaseDC Lib "user32" ( _
ByVal hwnd As Long, ByVal lngDC As Long) As Long

Private Type RECT
    Gauche                              As Long
    Haut                                As Long
    Bottom                              As Long
    Right                               As Long
End Type

Private Type LOGFONT
    lfHeight                            As Long
    lfWidth                             As Long
    lfEscapement                        As Long
    lfOrientation                       As Long
    lfWeight                            As Long
    lfItalic                            As Byte
    lfUnderline                         As Byte
    lfStrikeOut                         As Byte
    lfCharSet                           As Byte
    lfOutPrecision                      As Byte
    lfClipPrecision                     As Byte
    lfQuality                           As Byte
    lfPitchAndFamily                    As Byte
    lfFaceName                          As String * 32
End Type

Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90

Private Const CLIP_LH_ANGLES As Long = 16
Private Const OUT_TT_ONLY_PRECIS As Long = 7

Private Const DT_Haut As Long = &H0
Private Const DT_Gauche As Long = &H0
Private Const DT_WORDBREAK As Long = &H10
Private Const DT_CALCRECT As Long = &H400

'---------------------------------------------------------------------------
' Procedure     : GetTextLength
' DateTime      : 02/08/2008
' Author        : Jean-Philippe AMBROSINO
' Context       : Code inspiré du tutoriel de cafeine
' Purpose       : Retourne la hauteur nécessaire d'un Textbox pour afficher
'                 son contenu dans son intégralité
'...........................................................................
' Parameters    : FormControl = Control de type Textbox contenant le texte
'                 [TextToCheck] = Chaîne représentant le texte affiché
' Return Codes  : Long
'---------------------------------------------------------------------------
Public Function GetTextLength(ByVal FormControl As Control, Optional ByVal TextToCheck As String = "") As Long
Dim tyFONT                              As LOGFONT
Dim tyRECT                              As RECT
Dim lngDC                               As Long
Dim lngNewFont                          As Long
Dim lngOldFont                          As Long
Dim lngRet                              As Long
Dim strText                             As String
    
    ' Vérification du texte
    If Len(TextToCheck) = 0 Then
        strText = FormControl.Value & Chr(0)
    Else
        strText = TextToCheck & Chr(0)
    End If

    lngDC = GetDC(0&)

    ' Obtention du rectangle représenté par le contrôle
    tyRECT.Bottom = CountPixelsX(FormControl.Width)
    ' Obtention du contexte et création du texte avec les caractéristiques de la  police
    With FormControl
        tyFONT.lfClipPrecision = CLIP_LH_ANGLES
        tyFONT.lfOutPrecision = OUT_TT_ONLY_PRECIS
        tyFONT.lfEscapement = 0
        tyFONT.lfFaceName = .FontName & Chr$(0)
        tyFONT.lfWeight = .FontWeight
        tyFONT.lfItalic = .FontItalic
        tyFONT.lfUnderline = .FontUnderline
        tyFONT.lfHeight = (.FontSize / 72) * -GetDeviceCaps(lngDC, 90)
        lngNewFont = CreateFontIndirect(tyFONT)
    End With

    ' Selectionne un objet Font
    lngOldFont = SelectObject(lngDC, lngNewFont)
    lngRet = DrawText(lngDC, strText, -1&, tyRECT, DT_CALCRECT Or DT_Haut Or DT_Gauche Or DT_WORDBREAK)
    ' Restaure la police originale
    SelectObject lngDC, lngOldFont
    ' Supprime la police précédemment créée dans le contexte
    DeleteObject lngNewFont
    ' Si l'API DrawText réussit, alors la hauteur du contrôle est calculée en Twips
    GetTextLength = CountTwipsX(tyRECT.Right) + 10
    'On libère alors l'objet du contexte
    ReleaseDC 0&, lngDC
End Function

'---------------------------------------------------------------------------
' Procedure     : GetTwipsPerPixelsX
' DateTime      : 02/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Calcul le nombre de Twips par Pixel X
'...........................................................................
' Parameters    : Aucun
' Return Codes  : Long
'---------------------------------------------------------------------------
Private Function GetTwipsPerPixelsX() As Long
Dim lngDC                      As Long

    lngDC = CreateIC("DISPLAY", vbNullString, vbNullString, vbNullString)
    If lngDC <> 0 Then
        GetTwipsPerPixelsX = 1440 / GetDeviceCaps(lngDC, LOGPIXELSX)
        DeleteDC lngDC
    End If
End Function
Private Function CountPixelsX(ByRef NbTwips As Long) As Long
'---------------------------------------------------------------------------
' Procedure     : CountPixelsX
' DateTime      : 02/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Retourne le nombre de Twips selon le nombre de Pixels
'...........................................................................
' Parameters    : NbPixels = Nombre de pixels
' Return Codes  : Long
'---------------------------------------------------------------------------
    CountPixelsX = NbTwips / GetTwipsPerPixelsX
End Function
Private Function CountTwipsX(ByRef NbPixels As Long) As Long
'---------------------------------------------------------------------------
' Procedure     : CountTwipsX
' DateTime      : 02/08/2008
' Author        : Jean-Philippe AMBROSINO
' Purpose       : Retourne le nombre de Twips selon le nombre de Pixels
'...........................................................................
' Parameters    : NbPixels = Nombre de pixels
' Return Codes  : Long
'---------------------------------------------------------------------------
    CountTwipsX = NbPixels * GetTwipsPerPixelsX
End Function

Vous ajoutez donc un module standard à votre projet que vous nommez basPostIt (par exemple) et y recopierez l'intégralité du bloc de code ci-dessus.

VII. Conclusion

Ce tutoriel peut s'avérer utile pour les développeurs qui souhaitent enrichir leurs applications avec des petits plus pratiques…
Il apprend à concevoir des formulaires selon un jeu de conditions bien spécifiques avec une idée originale.
Je vous laisse vous entraîner avec cette pratique. Si vous rencontrez des difficultés ou si j'ai omis de préciser quelque chose qui reste obscur, n'hésitez pas à m'en faire part.

VIII. Remerciements

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

- Cafeine, pour son tutoriel sur les formulaires autoextensibles pour Access.
- Jeannot45
- Starec
- Pierre Fauconnier

IX. Définitions

 Twip (Définition de l'aide Visual Basic)
Unité indépendante de l'écran, utilisée pour garantir que l'emplacement et la proportion des éléments d'écran de votre application seront les mêmes, quel que soit le système d'affichage. Le twip est une unité de mesure d'écran égale à 1/20 point d'une imprimante.
On compte environ 1 440 twips dans un pouce logique ou 567 twips dans un centimètre logique (la longueur d'un élément d'écran étant égale à un pouce ou à un centimètre lorsqu'il est imprimé).

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

Copyright © 2019 Jean-Philippe AMBROSINO. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.