Dans une application, il n’est pas toujours évident de localiser rapidement la champ qui est en cours de saisie. La technique suivante le réalise en modifiant la couleur du champ.
Ici j’ai choisi de modifier la couleur du texte et la couleur de fond, mais la mise en évidence pourrait par exemple porter sur la police.
Un écran de l’exemple CRM modifié pour inclure la mise en évidence (temps de mise en place environ 30 secondes sans rire ! ).
Ces variables mémorisent les caractéristiques du champ qui vont être modifiées, et aussi le nom du champ.
gNomChampEnEvidence est une chaîne
gCouleurChampEnEvidence est un entier
gCouleurFondChampEnEvidence est un entier
Chaque fois qu’un champ rentre en saisie, il recoit préalablement l‘événement “prise de focus“ soit WM_SETFOCUS .
La ligne de commande suivante permet d’intercepter cet événement sur tous les champs de la fenêtre et d’appeler la procédure locale MiseEnEvidence .
notez que le nom du champ sera récupéré dans la variable EVE.nom
Evénement(MiseEnEvidence,".*", 7) // WM_SETFOCUS
Cette procédure sera appelée chaque fois qu’un champ de la fenêtre entrera en saisie.
Son premier travail sera de restaurer l’aspect du champ préalablement mis en évidence, quand il y en a un.
Ensuite elle mémorise, en utilisant les variables décrites plus haut, les caractéristiques du champ qui vont être modifiées.
Pour finir, elle modifie le champ pour le mettre en évidence.
PROCEDURE MiseEnEvidence()
sNomChamp est une chaîne = _EVE.nom
// restaurer l'aspect du précédent
SI gNomChampEnEvidence <> "" ALORS
// Annule la mise en évidence
{gNomChampEnEvidence}..CouleurFond = gCouleurFondChampEnEvidence
{gNomChampEnEvidence}..Couleur = gCouleurChampEnEvidence
FIN
// trace({sNomChamp}..Type, typSaisieTexte, typSaisieNum)
SI {sNomChamp, indChamp}..Type = typTexte OU {sNomChamp, indChamp}..Type = typNum ALORS
// mémorise la couleur de fond
gCouleurFondChampEnEvidence = {sNomChamp, indChamp}..CouleurFond
gCouleurChampEnEvidence = {sNomChamp, indChamp}..Couleur
// mémorise le nom du champ
gNomChampEnEvidence = sNomChamp
// mise en évidence
{sNomChamp, indChamp}..CouleurFond = iRougeClair
{sNomChamp, indChamp}..Couleur = iBlanc
FIN
Il est facile de gérer le survol de souris car c’est un événement windows (WM_MOUSEMOVE pour les experts).
Il n’existe malheureusement pas d‘événement “sortie de survol” au niveau de windows.
Heureusement cet événement existe dans WinDev. L’exemple suivant permet d’intervenir lorsque la souris quitte chaque champ d’une fenêtre :
WM_USER est un entier = 1024
Evénement("FinSurvol", ".*", WM_USER+711)
...
PROCEDURE FinSurvol()
//Procédure callback appellée par Evénement()
Trace("Fin du survol du champ "+_EVE.nom)
Picasa, mon programme préféré, dévoile enfin ces APIs. Il devient notamment facile d’obtenir la liste des albums, la liste des photos d’un album, ou de récupérer pour l’afficher une des photos.
Nous allons afficher la liste des albums de PatBiker. La documentation Picasa (http://code.google.com/apis/picasaweb/gdata.htm ) donne l’ exemple suivant, qui récupère les albums publics de l’utilisateur LIZ.
GET http://picasaweb.google.com/data/feed/api/user/liz?kind=album
Codons ce traitement en WLangage.
SourceXML est une chaîne
// PatBiker est le nom du compte Picassa
RequêteHTTP est une chaîne = ChaîneConstruit("http://picasaweb.google.com/data/feed/api/user/%1?kind=album", "PatBiker")
bc. SI HTTPRequête(RequêteHTTP)ALORS
SourceXML = HTTPDonneRésultat(HTTPRésultat)
// document XML à exploiter
XMLDocument("DocXML", SourceXML)
SINON
Erreur(ErreurInfo(errComplet))
FIN
Le résultat est un document XML. L’information concernant un album apparait dans une balise <entry></entry>
. On y trouvera notamment le titre de l’album (balise <title>
), mais surtout le <gphoto:name>
dont la valeur permet de retrouver les photos de l’album. Les valeurs de “titre” et “name” sont très proches, quelquefois identiques. En fait le “name” concatène tous les mots contenus dans le titre en éliminant tous les caractères autres que a..z (pas de lettres accentuées, cédille et autres irrégularités) et l’initiale de chaque mot est transformée en majuscules.
Nous allons récupérer ces deux informations dans une boucle qui fait appel à la formidable commande XMLExécuteXPath.
RequêteXPATH est une chaîne = "//entry/title | //entry/gphoto:name"
SI XMLExécuteXPath("DocXML", RequêteXPATH) ALORS
TANTQUE XMLTrouve("DocXML")
Trace(XMLDonnée("DocXML"))
XMLSuivant("DocXML")
FIN
FIN
Cette boucle pourrait s‘écrire d’une autre manière en regroupant deux lectures. Cela ne change rien au résultat final. Dans cette version chaque tour de boucle correspond à un album.
TANTQUE XMLTrouve("DocXML")
Trace(XMLDonnée("DocXML"))
XMLSuivant("DocXML")
Trace(XMLDonnée("DocXML"))
XMLSuivant("DocXML")
FIN
Cette manière d‘écrire sera utile si c’est un attribut qu’il faut afficher. Vérifions le en modifiant notre requête XPath pour afficher l’URL de l’image symbolisant l’album.
RequêteXPATH est une chaîne = "//entry/title | //entry/gphoto:name | //entry/media:group/media:content"
SI XMLExécuteXPath("DocXML", RequêteXPATH) ALORS
TANTQUE XMLTrouve("DocXML")
Trace(XMLDonnée("DocXML"))
XMLSuivant("DocXML")
Trace(XMLDonnée("DocXML"))
XMLSuivant("DocXML")
Trace(XMLDonnée("DocXML", "url")) // lecture d'un attribut
XMLSuivant("DocXML")
FIN
FIN
Pour afficher la liste des images d’un album, il faut connaître le “name” de l’album. Le traitement est quasiment identique à celui qui permet d’obtenir la liste des albums. La documentation Google donne l’exemple suivant :
GET http://picasaweb.google.com/data/feed/api/user/liz/album/NetherfieldPark?kind=photo
Nous allons afficher la liste de photos composant l’album “Grain” de Patbiker avec le code suivant. Ici sont affichés le titre de la photo (balise <title>
) et la source de la photo (attribut “src” de la balise <content>
).
SourceXML est une chaîne
RequêteHTTP est une chaîne = ChaîneConstruit("http://picasaweb.google.com/data/feed/api/user/%1/album/%2?kind=photo", "PatBiker", "Grain")
RequêteXPATH est une chaîne = "//entry/title | //entry/content"
bc. Sablier(Vrai)
SI HTTPRequête(RequêteHTTP)ALORS
Sablier(Faux)
SourceXML = HTTPDonneRésultat(HTTPRésultat)
XMLDocument("DocXML", SourceXML)
bc. SI XMLExécuteXPath("DocXML", RequêteXPATH) ALORS
TANTQUE XMLTrouve("DocXML")
Trace(XMLDonnée("DocXML"))
XMLSuivant("DocXML")
Trace(XMLDonnée("DocXML", "src"))
XMLSuivant("DocXML")
FIN
FIN
XMLTermine("DocXML")
SINON
Erreur(ErreurInfo(errComplet))
FIN