Bandeau Xylak
Bandeau LOCUS SOLUTUS
Bandeau arc-en-ciel
    Brimborions
     xylakaviens
fbNauvatag
xyljack.net


Oyiwen ed tanemert_______ Page mise à jour le 23 février 2022 vers 19h30 TUC

Le mode Sombre-plat 

Ironie de l'Histoire : aux débuts de VisualBasic, le (pseudo-)relief de VB et le texte noir sur fond blanc de Windows se voulaient le comble de la modernité face au flat design  de QuickBasic (avec, par exemple, des boutons au contour formé d'un simple trait) couplé au dark theme  (texte clair sur fond noir) de la console MS-DOS. Deux décennies plus tard, la girouette a tourné… et il n'est pas simple de donner aux programmes écrits en VB6 (à son tour présenté comme obsolète) l'aspect sombre-plat  aujourd'hui à la mode. Le code ci-dessous essaie de répondre à cet éventuel besoin.


Sommaire


I- Les problèmes

Ⓐ  À première vue, il ne devrait pas y en avoir puisque les contrôles de VB6 disposent des propriétés adéquates :
__on peut aussi jouer sur BorderStyle = 1 (bordure) ou 0 (pas de bordure).
Le système produit l'effet attendu pour les listes (ListBox )___aaa

ou les étiquettes (Label )___aaa
   Bordures

Changer les valeurs de ces propriétés devrait donc permettre de passer de  q   à w   ou e  ___aaa

Ⓑ  Hélas ! d'autres contrôles se montrent beaucoup moins coopératifs, notamment les cadres (Frame ) et les boutons (CommandButton ), qui constituent une part importante de l'interface dans la plupart des programmes.

D'abord, dans ces contrôles, mettre Appearance à 0 ne change rien, la bordure restant de type 3D .

Modes Clair-relief et Sombre-plat

Pis encore, les CommandButtons  sont dépourvus

Les cases à cocher (CheckBox ) et les boutons d'option (OptionButton ) permettent bien de retrouver un texte en blanc (grâce à la présence d'une propriété ForeColor) mais

La seule solution est alors de remplacer les boutons, cases à cocher et boutons d'option par un autre type de contrôle.

La zone d'image (PictureBox ) offre une gestion satisfaisante de la bordure mais le texte ne peut être placé que comme image, rendant le procédé aussi complexe qu'avec la propriété Picture d'un bouton ; l'emploi semble donc limité aux boutons affichant seulement une image.

La solution habituellement conseillée est l'étiquette (Label ), d'un emploi plus souple ; c'est celle qui a été retenue ici dans la plupart des cas, bien qu'elle présente quelques inconvénients :

  1. la commande Bouton [(Index )].Value = VRAI (qui permet de cliquer virtuellement sur un bouton) n'est plus disponible ; seul est possible Bouton _Click [(Index )]  ;
  2. les étiquettes n'ont pas de hWnd donc pas de SetFocus/GotFocus/LostFocus  et ne peuvent pas servir de conteneur pour une image ;
  3. pour la même raison, il n'est pas possible de faire apparaître une étiquette par dessus un autre contrôle (liste, bouton, zone de texte ou d'image, cadre) en jouant sur la propriété ZOrder ;
    NB- cette particularité se révèle d'ailleurs particulièrement gênante lors de la création dans l'interface graphique ;
  4. alors que, dans un bouton, VB centre automatiquement le texte aussi bien horizontalement que verticalement, il faut mettre la propriété Alignment de l'étiquette à 2_Center pour le centrer horizontalement, et rien n'est prévu pour le centrage vertical ; on peut envisager un système à double étiquette, l'une pour la bordure et la couleur de fond, l'autre pour le texte, mais le code s'en trouve fortement alourdi ; il reste donc à jouer avec les polices, certaines plaçant le texte plus bas que d'autres (voir II-Ⓒ-NB3 ci-dessous).
Ⓒ  Le remplacement des boutons par des étiquettes a été l'occasion de combler ce qui me semble une lacune de VB6 : quand un contrôle est désactivé, sa bulle d'aide ne s'affiche pas. Ici, la propriété Enabled a donc laissé la place à une fonction Actif et des procédures Active, ActiveSi et Désactive. Le principal inconvénient est de devoir placer une ligne
If Actif(…) = FAUX Then Exit Sub
à l'entrée de chaque procédure d'un contrôle susceptible d'être désactivé.
Ⓓ  Dernier problème à résoudre : les procédures MsgBox. Comme on pouvait s'y attendre, rien ne permet de modifier l'apparence gris clair + relief  des fenêtres utilisées pour ce type de message. Il a donc fallu créer Dial avec la même multiplicité d'options (procédure / fonction ; icône, nombre et libellé des boutons variables ; toutefois, des propriétés comme vbDefaultButton… ou vbMsgBox… n'ont pas été incluses).

II- Mode d'emploi

Ⓐ  Pour mettre à jour un projet, il faut y inclure la feuille PlatD (fichiers @_PlatD.frm et @_PlatD.frx) ainsi que le module PlatM (fichier @_PlatM.bas).
Ⓑ  Comme on peut le voir dans les captures d'écran ci-dessus, on a le choix entre deux apparences :

Dans les deux cas, le fond du bouton est


noir par défautbrique lorsqu'il est actif et survolé par la sourisgris quand il est désactivé
Fond du bouton par défautFond du bouton survoléFond du bouton désactivé

Le choix entre les deux apparences se fait par la variable booléenne globale Bord, dont la valeur FAUX entraîne l'apparence -sans bordure (valeur par défaut) et VRAI, l'apparence -trait simple ; pour obtenir ce dernier aspect, il faut placer une instruction Bord = VRAI dans la procédure Form_Load de la feuille.

Les cases d'option (OptionButton ) et cases à cocher (CheckBox ) sont aussi affectées par ce choix, comme il est précisé dans les sections Ⓓ  et .

Le fonctionnement de l'ensemble est assuré par les procédures

 é#Nom _MouseMove
Form|icNom _MouseMove
couleur de fond lors du survol, appelant
couleur de fond par défaut, appelant
FixeFond|FixeFond2
ReNoir
fond brique
fond noir
 Active|Désactive
ActiveSi
Actif
remplace Nom .Enabled = Vrai|Faux
remplace If … Then Nom .Enabled = Vrai
remplace = Nom .Enabled
<!> Ci-dessous, seules sont mentionnées les propriétés dont la valeur par défaut doit être modifiée.
Ⓒ  Les boutons de commande (CommandButton ) sont remplacés par Ⓓ  Les cases d'option (OptionButton ) sont remplacées par des étiquettes en groupe de contrôles:

Même comportement et mêmes procédures que pour les boutons avec en plus
_________Pointe (pour « enfoncer » le bouton cliqué) et Pointé (pour renvoyer son état).

L'état est figuré

NB1- Si besoin est, l'index de la case enfoncée peut être enregistrée dans la propriété Tag d'un contrôle.
NB2- Dans VB6, c'est le conteneur qui crée la famille de boutons d'option ; par exemple, si l'on a dans un cadre deux cases d'option coAAA(0) et coBBB et, à l'extérieur de ce cadre, une case d'option coAAA(1), la selection de coAAA(0) entraîne automatiquement la remise à zéro de coBBB mais on peut sélectionner simultanément coAAA(0) et coAAA(1). Dans Plat, c'est le groupe de contrôles (donc le nom) qui crée la famille, sans tenir compte du conteneur.
Ⓔ  Les cases à cocher (CheckBox ) sont remplacées par une étiquette bouton inverseur éiNom .

Comme pour les cases d'option, l'état relâché|enfoncé est figuré par les propriétés Appearance et BorderStyle.

Procédures particulières : Inverse, Coche, Décoche et fonction Coché.
Ⓕ  S'agissant des cadres (Frame ), ceux qui servent simplement de conteneur, sans bordure, peuvent être conservés en fixant la propriété BackColor à 0 (noir) ; ceux qui ont un rôle visuel et une bordure sont à remplacer par une zone d'image (PictureBox ) :
Ⓖ  Pour permettre d'afficher les bulles d'aide même quand le contrôle est désactivé, la propriété Enabled est remplacée par la couleur de fond du bouton :

BackColor   NOIR
BRIQUE   
GRIS
activé non survolé
activé + survolé
désactivé

Le fonctionnement est assuré par la fonction Actif et les procédures Active, ActiveSi et Désactive .

Notes complémentaires :
  1. L'instruction IniPlat Me doit être ajoutée dans la procédure Form_Load de la feuille.
  2. Cette commande doit être suivie de la liste des contrôles à désactiver par défaut.
  3. Dans les procédures _Click des contrôles susceptibles d'être désactivés, if faut placer comme première ligne
    ____If Not Actif(NomDuContrôle ) Then Exit Sub
  4. La liste de ces boutons peut être placée dans le presse-papiers par l'instruction PropCtrl Me, "d" appelée à partir de la feuille ( voir la section Ⓙ   plus bas)
  5. Active et Désactive peuvent traiter une liste de contrôles passée en paramètres mais pas un groupe de contrôles.
  6. lors du survol, si Actif = VRAI, le curseur de la souris (MousePointer ) prend la forme 15-Size All  alors qu'il reste à 0-Default  sur un contrôle inactif.
Ⓗ  La fonction MsgBox est remplacée par  Dial(Texte, Btn[, Ico, Ttr])  
Btn est une chaîne de 1 à 3 caractères parmi   V
vu   
O
oui   
N
non   
A
annuler   
R
réessayer   
I
ignorer   
Ico (facultatif), un caractère parmi      I
information   
[par défaut]
E
exclamation   
Q
question   
C
critique

La fonction Dial renvoie la lettre du bouton sélectionné.

Ⓘ  Constantes couleurs système :
fond courantfond séléctionnéfond désactivétexte courant
Const PNOIR = &h0&,PCHOIX = &h3060&,PGRIS = &h808080,PBLANC = &hFFFFFF
NB- le P initial sert à distinguer ces constantes de celles qui pourraient être utilisées ailleurs dans le programme.
Ⓙ  PropCtrl : procédure à appeler d'une feuille sous la forme PropCtrl Me, "[Q|q][C][D]" pour placer dans le presse-papiers diverses informations sur les contrôles de cette page, suivant le contenu du dernier paramètre :
QContainer  de chaque contrôle
qidem en omettant les contrôles placés directement dans la feuille
Ccouleur de fond de chaque contrôle (en hexadécimal)
NB- les étiquettes transparentes (Label  avec BackStyle = 0) sont signalées par un signe =
Dcontrôles susceptibles d'être désactivés
NB- l'information est à corriger quand une instruction Désactive se trouve
  • placée en commentaire (faux positif),
  • dans un module .bas (mention absente).

III- Le code

Les trois fichiers @_PlatD.frm, @_PlatD.frx et @_PlatM.bas sont rassemblés dans une archive Plat.zip que l'on peut télécharger en cliquant sur ce lien.

La version la plus récente est v1.0 du 24/02/2022.


Plan du site & Mentions légales_._Site éclos sur Skyrock, développé avec Axiatel et mûri sur Strato.com_._© 2015-2024 - XylonAkau