I. Avant-propos▲
Ce document a pour but de vous montrer comment il est possible de positionner un formulaire à l'extrême droite de l'écran.
En effet, lorsque vous ouvrez un formulaire Access, celui-ci se positionne là où il à été positionné lors de la dernière utilisation, cette dernière étant enregistrée dans les propriétés de celui-ci.
Grâce à ce tutoriel, vous serez à même de mettre en œuvre une routine idoine.
I-A. Remerciements▲
Je tiens à remercier tout particulièrement toutes celles et tous ceux qui ont participé à la relecture de ce document en y incluant leurs remarques.
I-B. Contact▲
Pour tous renseignements complémentaires, veuillez me contacter directement (Argyronet) par MP.
II. Présentation du formulaire exemple▲
J'ai utilisé la base de données « Les Comptoirs » pour vous servir d'exemple.
Pour ce faire, vous devez dupliquer le formulaire nommé « Démarrage » et vous le renommerez pour la circonstance frmStartup.
Vous aurez pris soin de supprimer les éléments non utilisés dans ce dernier comme le montre l'illustration ci-dessous.
II-A. Le formulaire dupliqué et son bouton▲
Vous noterez qu'il n'y a aucune procédure Visual Basic dans le code de ce formulaire.
Seul le bouton OK exploite une macro =FermeFormulaire()
Son rôle ne présente aucun intérêt pour ce tutoriel puisque vous pouvez fermer un formulaire Access aussi bien avec du code qu'avec une macro, ma préférence étant bien entendu axée sur une procédure Visual Basic.
Le formulaire en mode création
Le formulaire en mode formulaire
II-B. Les propriétés à redéfinir▲
Pour vérifier que votre formulaire est opérationnel, il vous faut supprimer un certain nombre de propriétés prédéfinies sur celui-ci.
Vous ouvrirez donc les propriétés du formulaire et les définirez comme suit :
- Auto centrer : ……………………….….. Non
- Fenêtre indépendante : ……………. Oui
- Fenêtre modale : ………………………. Oui
Les propriétés du formulaire à ouvrir
C'est terminé pour ce formulaire, vous pouvez l'enregistrer et le fermer.
III. Conception du formulaire principal▲
Il s'agit du formulaire que vous avez certainement déjà conçu dans votre application.
Du fait que je ne sais pas substituer votre formulaire à celui que nous avons à concevoir, je vais vous proposer de créer celui-ci.
Il vous suffira par la suite d'adapter selon vos besoins en respectant les appels de code.
III-A. Conception du formulaire principal▲
Pour concevoir le formulaire manuellement, depuis la fenêtre Base de données, choisissez Nouveau
L'image ci-après apparaît et vous sélectionnez alors Mode création
Vous n'avez pas de table ni de requête à affecter comme source du formulaire pour cet exemple.
Cliquez sur OK
Étape 1
Le formulaire se présente vide avec seulement la section Détail visible.
Étape 2
Vous devez poser sur ce formulaire les contrôles nécessaires comme suit.
Un groupe d'option
Vous poserez d'abord un groupe d'options comme illustré ci-après (que vous pouvez concevoir avec l'Assistant Contrôle )
Les options, leurs étiquettes et leurs valeurs respectives du groupe d'options sont les suivantes
- En &haut à droite …………………………… 1
- Au &milieu à droite ………………………… 2
- En &bas à droite ……………………………. 3
Ne mettez pas de valeur par défaut sur ce groupe d'options.
Vous lui appliquerez un look circonstanciel et le nommerez fraTopPosition.
Une case à cocher
Vous poserez ensuite une case à cocher comme illustré ci-après que vous nommerez chkSetFocusToForm et dont l'étiquette s'intitulera « Donner le &focus au formulaire ».
Un bouton d'ouverture
Vous poserez enfin un bouton de commande comme illustré ci-après que vous nommerez cmdOpenForm et dont l'étiquette s'intitulera « &Ouvrir Le formulaire ».
Notez le symbole & précédant chaque intitulé d'étiquette et servant à définir le raccourci clavier.
Le formulaire principal en mode création
III-A-1. Propriétés des contrôles du formulaire principal▲
Les contrôles que vous avez posés ne nécessitent pas de grosses modifications en ce qui concerne les propriétés.
Vous avez déjà défini celles du groupe d'options et il vous reste à définir la propriété Enabled (Activé) du bouton de commande à False (Non)
Il sera toutefois nécessaire de définir les propriétés d'événement dans le code, chose vue ci-après.
Elles se traduisent simplement de la façon suivante :
- - par l'événement Click (Sur clic) pour le bouton ;
- - par l'événement AfterUpdate (Après MAJ) pour le groupe d'options ;
- - par l'événement Load (Sur chargement) pour le formulaire lui-même.
III-A-2. Code des contrôles du formulaire principal▲
En ce qui concerne le code Visual Basic de ce formulaire, il se traduit par ces quelques lignes :
Option
Compare Database
Option
Explicit
' Affichage du formulaire
Private
Sub
cmdOpenForm_Click
(
)
DoCmd.OpenForm
"frmStartup"
, acNormal, , , , acHidden
subMoveFormToRight "frmStartup"
, Me!fraTopPosition, Me!chkSetFocusToForm
fraTopPosition.SetFocus
cmdOpenForm.Enabled
=
False
End
Sub
' Initialisation des contrôles
Private
Sub
Form_Load
(
)
Me!fraTopPosition =
0
Me!chkSetFocusToForm =
False
End
Sub
' Événement du cadre d'options
Private
Sub
fraTopPosition_AfterUpdate
(
)
cmdOpenForm.Enabled
=
True
End
Sub
III-A-2-a. Description du code du formulaire principal▲
Le code du formulaire principal possède trois codes événements
- cmdOpenForm_Click qui a pour rôle de déclencher l'ouverture du formulaire en question (frmStartup). La méthode utilise la fonction DoCmd.OpenForm en spécifiant dans un premier temps que l'on veut ouvrir le formulaire en mode caché…
Pourquoi caché ? Tout simplement parce que l'on ne sait pas déterminer sa position à son ouverture considérant qu'un formulaire est flottant et que sa position est mémorisée dès qu'on le ferme si aucune propriété (AutoCentrer par exemple) ne contre celle-ci.
De ce fait, il ne faut pas que le formulaire soit visible.
Ensuite, la procédure publique subMoveFormToRight (vue ci-après) utilise respectivement trois arguments :
Enfin, la procédure redonne le focus au groupe d'options et désactive le bouton.
- fraTopPosition_AfterUpdate se contente de rendre activé le bouton « cmdOpenForm ».
La valeur de 1 à 3 qu'il renvoie est définie par les différentes valeurs des options et sera passée en paramètre dans la procédure subMoveFormToRight.
- Form_Load est écrit ainsi par prudence pour initialiser le contrôle CheckBox à False pour éviter qu'il soit Null et ainsi générer une erreur. Aussi, pour le cas où vous n'auriez pas prêté attention à la valeur par défaut du groupe d'options, cette valeur est affectée à zéro (aucune option cochée).
C'est terminé pour ce formulaire, il ne vous restera plus qu'à l'enregistrer et le fermer
III-B. Le formulaire principal en mode formulaire▲
Lorsque vous passez en mode formulaire, vous devez obtenir quelque chose comme ceci :
IV. Le module▲
Pour achever la conception de ce tutoriel, il vous faut insérer un module contenant le code principal de ce projet. Ce module que vous nommerez basMoveForm contiendra la routine publique qui sera chargée de placer le formulaire.
IV-A. Code du module▲
Le code du module se compose de Constantes, d'un Enum, de cinq déclarations d'API Windows.
La seule procédure publique subMoveFormToRight de ce module exploite tous ces éléments.
Option
Compare Database
Option
Explicit
' Énumération des positions souhaitées
Public
Enum eRightPosition
SetToTop =
1
SetToCenter =
2
SetToBottom =
3
End
Enum
' Constantes de l'Api SetWindowPos()
Private
Const
HWND_TOPMOST =
-
1
Private
Const
HWND_NOTOPMOST =
-
2
Private
Const
SWP_NOSIZE =
&
H1
Private
Const
SWP_NOMOVE =
&
H2
Private
Const
SWP_NOACTIVATE =
&
H10
Private
Const
SWP_SHOWWINDOW =
&
H40
Private
Const
SWP_HIDEWINDOW =
&
H80
Private
Const
SWP_FOCUSWINDOW =
0
' Constantes des API GetSystemMetrics() et GetDeviceCaps()
Private
Const
SM_CXSCREEN =
0
Private
Const
SM_CYSCREEN =
1
Private
Const
HWND_DESKTOP As
Long
=
0
Private
Const
LOGPIXELSX As
Long
=
88
Private
Const
LOGPIXELSY As
Long
=
90
' Constantes des dimensions de marge et barre de titre de la fenêtre
Private
Const
SCREEN_MARGIN =
5
Private
Const
SCREEN_TITLEBAR =
30
'API Windows
Private
Declare
Function
GetSystemMetrics Lib
"user32"
(
ByVal
nIndex As
Long
) _
As
Long
Private
Declare
Sub
SetWindowPos Lib
"user32"
(
ByVal
Hwnd As
Long
, ByVal
_
hWndInsertAfter As
Long
, ByVal
X As
Long
, ByVal
Y As
Long
, ByVal
cx As
Long
, _
ByVal
cy As
Long
, ByVal
wFlags As
Long
)
Private
Declare
Function
GetDC Lib
"user32"
(
ByVal
Hwnd As
Long
) As
Long
Private
Declare
Function
ReleaseDC Lib
"user32"
(
ByVal
Hwnd As
Long
, ByVal
hdc _
As
Long
) As
Long
Private
Declare
Function
GetDeviceCaps Lib
"gdi32"
(
ByVal
hdc As
Long
, ByVal
_
nIndex As
Long
) As
Long
'
'*******************************************************************************
' Procédure : subMoveFormToRight
' Rôle: Permet de positionner un formulaire sur la partie droite de l'écran
' Paramètres:
' - FormName : Nom du formulaire
' - RightPosition : Valeur de la position de 1 à 3 fondée sur eRightPosition
' - ActivateWindow : True ou False (True donne le focus à la fenêtre déplacée)
'*******************************************************************************
'
Public
Sub
subMoveFormToRight
(
ByVal
FormName As
String
, Optional
ByVal
_
RightPosition As
eRightPosition, Optional
ByVal
ActivateWindow As
Boolean
=
False
)
Dim
sngScreenWitdh As
Single
Dim
sngScreenHeight As
Single
Dim
TwipsPerPixelX As
Long
Dim
TwipsPerPixelY As
Long
Dim
lngNewX As
Long
Dim
lngNewY As
Long
Dim
lngDC As
Long
Dim
lngHorizontalPosition As
Long
Dim
lngVerticalPosition As
Long
Dim
lngFormHwnd As
Long
Dim
lngFormWidth As
Long
Dim
lngFormHeight As
Long
' Initialisation des coordonnées du formulaire et de son Handle
With
Forms
(
FormName)
lngFormHwnd =
.Hwnd
lngFormWidth =
.InsideWidth
lngFormHeight =
.InsideHeight
End
With
' Calculs relatifs à l'écran
lngDC =
GetDC
(
HWND_DESKTOP)
TwipsPerPixelX =
1440
&
/
GetDeviceCaps
(
lngDC, LOGPIXELSX)
TwipsPerPixelY =
1440
&
/
GetDeviceCaps
(
lngDC, LOGPIXELSY)
ReleaseDC HWND_DESKTOP, lngDC
lngHorizontalPosition =
lngFormWidth \
TwipsPerPixelX
lngVerticalPosition =
lngFormHeight \
TwipsPerPixelY
sngScreenWitdh =
GetSystemMetrics
(
SM_CXSCREEN)
sngScreenHeight =
GetSystemMetrics
(
SM_CYSCREEN)
lngNewX =
(
sngScreenWitdh -
lngHorizontalPosition) -
SCREEN_MARGIN
'Vérification de la position verticale choisie
Select
Case
RightPosition
Case
SetToTop
lngNewY =
0
Case
SetToBottom
lngNewY =
(
sngScreenHeight -
lngVerticalPosition) -
SCREEN_TITLEBAR
Case
Else
lngNewY =
((
sngScreenHeight -
lngVerticalPosition) -
SCREEN_MARGIN) \
2
End
Select
' Positionnement final du formulaire
SetWindowPos lngFormHwnd, HWND_TOPMOST, lngNewX, lngNewY, 0
, 0
, SWP_SHOWWINDOW _
Or
SWP_NOSIZE Or
IIf
(
ActivateWindow, SWP_FOCUSWINDOW, SWP_NOACTIVATE)
End
Sub
IV-A-1. Description du code du module▲
Le code de la procédure subMoveFormToRight
Dans un premier temps, le formulaire à positionner est déjà ouvert et caché. Du fait que son nom est passé en paramètre (ByVal FormName As String) cela permet d'obtenir les informations qui nous intéressent à son sujet à savoir :
- son Handle ;
- sa longueur (InsideWidth) ;
- sa hauteur (InsideHeight) ;
' Initialisation des coordonnées du formulaire et de son Handle
With
Forms
(
FormName)
lngFormHwnd =
.Hwnd
lngFormWidth =
.InsideWidth
lngFormHeight =
.InsideHeight
End
With
À ce stade, le formulaire est toujours invisible.
Ensuite, par le biais de différentes API, on initialise des variables pour connaitre le nombre de twips par pixel. Ceci va servir à effectuer les différents calculs pour déterminer la taille de l'écran et ainsi, pouvoir déterminer les nouvelles valeurs de X et de Y du l'API SetWindowPos.
=> La variable lngNewX qui sert à déterminer de combien de pixels on va déplacer horizontalement le formulaire est maintenant initialisée.
Avec le bloc Select Case/End Select, on est à même de savoir quelle sera la position verticale de la fenêtre selon les trois choix établis par le groupe d'options vu ci-avant ; ces positions sont définies par l'Enum eRightPosition où chacun des éléments prend la valeur de 1 à 3 correspondant justement aux trois options du groupe d'options.
=> La variable lngNewY qui sert à déterminer de combien de pixels on va déplacer verticalement le formulaire est à son tour, initialisée.
On donne le focus à la fenêtre si la variable ActivateWindow est affectée à True.
Enfin, on rappelle l'API SetWindowPos() avec les nouvelles valeurs de X et de Y toujours avec les arguments nécessaires pour placer cette fois, le formulaire sur le bord droit de l'écran et selon le cas, en haut, au milieu ou en bas.
- La constante SCREEN_MARGIN est utilisée pour soustraire la valeur des X à concurrence de la largeur de la bordure d'une fenêtre.
- La constante SCREEN_TITLEBAR est utilisée pour soustraire la valeur des Y à concurrence de la hauteur de la barre de titre d'une fenêtre.
Bien entendu, vous pouvez modifier la valeur de SCREEN_MARGIN si vous souhaitez ne pas faire coller la fenêtre sur la bordure droite, mais un peu en retrait.
Attention
Les Enum ne sont pas exploitables dans la version 97 d'Access et antérieures. Aussi, il vous faudra remplacer ces valeurs par des constantes et adapter le code en conséquence.
C'est terminé
Il ne vous reste plus qu'à exécuter le tout en ouvrant le formulaire principal en mode formulaire.
Je vous recommande de compiler votre projet afin de vous assurer que vous n'avez pas fait d'erreur de syntaxe, synonyme de plantage et de dysfonctionnement.
Pour effectuer une compilation, dans l'éditeur Visual Basic, cliquez sur le Menu Débogage/Compiler Comptoir.
Bien entendu, le menu Compiler… sera suivi du nom de votre application.
IV-B. Mise en œuvre de l'utilisation▲
Le résultat est conséquent au choix que vous avez effectué :
V. Conclusion▲
Ce tutoriel peut s'avérer utile pour les développeurs qui souhaitent manipuler plus facilement l'ouverture des formulaires. J'en ai fait les frais pour certains projets et je partage aujourd'hui avec vous ce petit plus…
Je précise que ce qui a motivé la rédaction de ce tutoriel est une question posée sur le Forum par un utilisateur qui souhaitait justement ouvrir un formulaire à un endroit ciblé sur l'écran.
Ce tutoriel, plus théorique que pratique, permet de répondre à une telle demande à partir du moment où vous déterminez vous-même le niveau de tolérance de la valeur des constantes SCREEN_MARGIN et SCREEN_TITLEBAR… Vous prêterez en revanche attention à ce que les nouvelles valeurs attribuées rentrent dans une plage conforme.
VI. Vocabulaire▲
TWIPS
Abréviation de « twentieth of a point ». Unité de mesure de longueur utilisée dans la conception d'objets graphiques.
1 twip est égal à 1/20e de point, 1/1440e de pouce.
HANDLE
Valeur numérique identifiant un objet informatique (§ une fenêtre ou un fichier) et permettant donc sa « manipulation » ou sa gestion (to handle en anglais). L'abréviation de cette valeur est souvent nommée HWnd.