25 octobre 2006

Comment suis-je devenu définitivement accro des outils PC SOFT (partie 1) ?

J'ai découvert le savoir faire PC SOFT en 1994 avec le trio Hyper Screen, Hyper File et Hyper Screen. Travaillant sur la réalisation d'un tableau de bord(1) pour une chaîne de grande distribution, fraîchement diplômé de l'université de Grenoble, je n'avais jamais fait autre chose que des programmes noirs, avec des interfaces en mode texte. Et là, je faisais des programmes en couleurs, gérant la souris, le défilement de données avec des ascenseurs, l'ouverture de fenêtres les unes par-dessus les autres ... le tout depuis un QBasic sous DOS 6.2 et sa compilation en ligne de commande. Le principe(2) était des plus simple, les 3 produits PC SOFT ajoutaient en quelque sorte des commandes au QBasic, commandes pour gérer l'interface, les données et les éditions. Le résultat était sidérant, avec très peu de commandes le programme était d'une efficacité redoutable, aussi conviviale qu'une application sous Windows 3.1 de l'époque, les problèmes de pilotes en moins !

Sorti de la tristesse des interfaces texte du DOS grâce à Hyper Screen, je me suis tout naturellement mis à la programmation sous Windows. J'ai compulsé de nombreuses heures le Petzold, et, je ne pouvais pas choisir mes outils à cette époque, j'ai fait mes premières fenêtres sous Visual C++ 1.5. Avec la première mouture des MFC (Microsof Foundation Classes), je pensais que la gestion de l'interface et des données serait aussi simple qu'avec Hyper Screen et Hyper File sous DOS. C'était une erreur, je me suis retrouvé avec des compilations infernales et interminables, des classes dans tous les sens, loin très loin de la simplicité de mes précédents développements. Heureusement, mon employeur a changé son fusil d'épaule avec l'arrivée de WINDEV 1.5, et depuis, avec des contextes professionnels différents, je travaille avec les outils PC SOFT. Ca fait donc plus de 12 ans !

Avec WINDEV 1.5 j'ai pu faire mes premières applications Windows en quelques clics, comme on peut le faire aujourd'hui. Le principe est en effet resté le même, on dessine la fenêtre en y plaçant les champs et boutons. On clic sur Go pour tester, sur l'engrenage pour créer l'exécutable à diffuser. J'ai ainsi enchaîné mes créations avec la version 1.5, puis les versions 2, 4 et enfin 5.5 qui a permis le passage en 32 bits. Passage douloureux pour bon nombre de mes collègues qui devaient se soucier de la portée de leurs pointeurs, de la taille de leurs variables entières (...), aisé pour moi qui devait uniquement cocher un sélecteur à la création de l'exécutable (juste les appels des API à adapter). PC SOFT avait tout prévu, comme sous Hyper Screen, et Hyper File qui restait le même avec déjà son système de modification automatique des fichiers de données.

La suite au prochain épisode ...


(1) Tableau de bord : vous comprenez mon billet relatif au tableau de bord des versions 11, j'ai fréquemment travaillé de tout temps sur la présentation des données, et l'aperçu du tableau de bord de suivi des projets est de très bonne augure pour WINDEV 11 !

(2) Cette technique de programmation reste disponible en version 10, elle est illustrée pas des exemples du dossier \Langages Externes\. En C, C#, Basic, Cobol, Fortran on ajoute des "includes" qui donnent accès à Hyper File, Wlangage et aux éléments d'une bibliothèque (.WDL).

20 octobre 2006

Section critique à la bonne place, avec le bon nom...

Dans un programme utilisant plusieurs thread (messagerie instantanée avec Socket, traitements batch...), il peut arriver après un certain temps d'utilisation un blocage (pas de réponse...), ou une disparition pure et simple de la liste des processus, ou un message du mécanisme de sécurité WLangage :

Une erreur système inattendue est survenue.
Module : WD100VM.DLL
Erreur système : Access violation (GPF)
EIP = 12345678


C'est une difficulté sérieuse, car il n'y a en général aucune reproduction systématique, et le traitement donné dans la pile de l'erreur change d'une exécution à l'autre. La piste de recherche à privilégier dans pareil cas, se nomme "section critique". En effet, dès que plusieurs threads s'exécutent en parallèle, ils vont nécessairement à un moment ou à un autre accéder à des éléments partagés. Typiquement, une variable globale du projet, un membre de classe utilisé dans une méthode exécutée par un thread secondaire, et une autre partie de la classe sollicitée dans le thread principal ... les combinaisons sont infinies.

Il faut donc en tout premier lieu en cas d'instabilité vérifier que tous les éléments (variables, membres...) qui sont utilisés par deux thread distincts sont dans une section critique. Sans cela, l'erreur ou le blocage "aléatoire" est quasiment garanti à un moment ou à un autre dans le déroulement de l'application, et le plus souvent après un important nombre d'heures d'utilisation.

A titre d'exemple, si une variable globale du projet est affectée dans un thread secondaire, le code devra être de la forme suivante :

Et bien sûr, la consultation de cette variable dans le thread principal devra se faire avec la même section critique (attention à ne pas faire une faute de frappe dans le nom de la section) :

Ce billet est motivé par plusieurs instabilités aléatoires résolues en ajoutant les bonnes sections critiques. La dernière en date, hier, provenait d'une faute de frappe avec un nom de section critique erroné lors de l'affectation d'un membre !

17 octobre 2006

Demander de l'aide au Framework DotNet ...

Dans le meilleur des mondes, le développeur aurait dans son environnement de développement toutes les fonctions possibles et imaginables créées depuis l'origine de la micro-informatique. Le temps passé à "réinventer la roue" serait enfin réduit à un minimum acceptable. Bien évidemment, ce meilleur des mondes n'est qu'utopie, et c'est tant mieux car le quotidien du développeur deviendrait bien monotone s'il n'était plus nécessaire de se creuser la tête de temps à autre !

Dans la pratique donc, il n'est donc pas rare d'avoir une fonction manquante, nécessitant dans le pire des cas un recodage. Mais c'est un cas extrême avec WINDEV car deux Framework sont à la disposition du développeur.

On pense immédiatement au Framework PC SOFT inclus avec toutes les applications. Il contient à lui seul des centaines de fonctions, des propriétés, l'accès moteur Hyper File, aux bases de données via OLE DB ...

Mais il ne faut pas omettre le Framework .NET directement accessible également. Il apporte de nombreuses possibilités supplémentaires.

Une illustration, obtenir du système un identifiant unique, plus communément appelé GUID (cf. ci-contre). La fonction "iDonneIdentifiant" du WLangage ne convient pas si l'on désire un identifiant unique au niveau du poste, elle ne convient que pour une instance de l'application.

La classe GUID de MSCORLIB inclus en standard dans .NET donne l'information. Il devient alors très facile d'avoir l'information en quelques clics. Le menu "Atelier" donne la possibilité d'ajouter dans le projet les classes de MSCORLIB. Il suffit ensuite de déclarer un objet "GUID" pour obtenir l'information attendue.

L'éditeur de code propose une complétion automatique pour les classes .NET intégrées, cela facile leur utilisation.

Notez qu'en utilisant le Framework .NET dans votre application sa présence sur l'installation cliente sera indispensable. Il faut donc vérifier avant tout le déploiement du Framework .NET sur les postes cibles. Normalement il est fait du moment que Windows update est actif.

13 octobre 2006

Synthèse de l'information, par Google et WINDEV 11 !

C'est chose faite, la version 11 de WINDEV est annoncée. En même temps Google propose une nouvelle version de Blogger. Moi qui adore les découvertes, je suis comblé !

Je suis régulièrement amené ces derniers temps à travailler sur la présentation des données dans des applications existantes. Les tableaux statistiques d'époque ou autre ne conviennent plus à l'utilisateur final, qui veut en un clin d'oeil avoir accès à toute l'information. C'est par exemple une des clés du succès des portails Web qui savent proposer un accueil regroupant les éléments dont a besoin l'Internaute.

Cette "tendance" ressort des nouveautés, puisque Google, et WINDEV 11 propose une notion de "tableau de bord" (dashboard en anglais dans le texte). L'interface du futur Windows Vista est également orientée vers une présentation réellement pensée pour l'utilisateur, et non plus pour le "bidouilleur", ou le connaisseur.

Gageons qu'avec de telles sources d'inspiration, les applications vont prendre un sacré "coup de jeune" en terme d'interface, et d'ergonomie. Alors synthèse de l'information dans nous outils de travail, mais également dans nos productions pour rendre l'outil informatique plus accessible en pensant toujours à ce dont à réellement besoin l'utilisateur final !

12 octobre 2006

On en apprend tous les jours ...

Le développement est un domaine si vaste, qu'il ne se passe pas une journée sans faire de découverte. Ma nouveauté du jour, est la fonction "ChaineRécupère" ! J'ai de tout temps utilisé la fonction "Transfert" qui n'est plus nécessaire maintenant. J'étais passé à côté de cette fonction, je ne sais pas dire dans quelle version de WINDEV elle est apparue.

Un fil du forum décrit l'aspect technique de cette commande.

Moralité, n'oubliez pas de relire régulièrement les documentations diverses, on ne sait jamais tout. Et puis il vient un stade ou l'on en apprend tous les jours, mais on en oublie également.

11 octobre 2006

Poser la bonne question !

Le dialogue instauré entre une application et ses utilisateurs est primordiale. Même avec des modes opératoires parfaitement définis, si l'application propose un choix ambigu l'utilisateur risque une fausse manipulation. Il aura de plus un ressenti négatif envers l'application, la trouvant difficile à utiliser.

Il paraît donc évident que toutes les applications devraient avoir des dialogues peaufinés. Cependant la réalité est différente, car historiquement le développeur disposait pour solliciter l'utilisateur de la fameuse "MessageBox" Windows, accessible en Wlangage au travers des fonctions "OuiNon", "Confirmez" avec les traditionnels boutons Oui, Non, Annuler. Difficile de proposer un dialogue efficace à partir de ce jeu d'instructions, sans passer un temps important dans la création de fenêtres spécifiques.

Pour trouver un juste équilibre entre des messages conviviaux à la réponse facile, sans rallonge de planning, le Wlangage propose une fonction "Dialogue", dotée d'un assistant de mise en œuvre, que je recommande de rendre obligatoire dans toutes vos règles ou chartes de programmation !

En effet, cette fonction permet de trouver le juste équilibre pour que le développeur en un minimum de temps puisse créer une interface de dialogue agréable, et surtout complète.

Voici une illustration, avec une action courante, l'envoi d'un email. Dans le cas ou l'utilisateur final ne renseigne pas le sujet de son message, on va l'en informer. La méthode originale "OuiNon" pouvait donner le type de message ci-contre. Oui, il est un peu caricatural, mais je vous assure l'avoir trouvé dans des applications.

L'utilisation de la fonction "Dialogue" permet d'éviter pareil "désagrément", car elle va permettre au développeur de bien poser la question, tout en proposant des boutons de réponses en texte clair. Notez que l'internationalisation est prise en charge par la fonction "Dialogue". Cette vue de l'assistant se passe quasiment de commentaire. Au centre le message, à droite on gère la présence des boutons, en bas leurs caractéristiques, à gauche l'icone système à afficher...



L'assistant va plus loin, le code de traitement du choix de l'utilisateur est immédiatement généré. Il ne reste plus qu'à insérer l'appel de vos procédures.

Un principe similaire pour un dialogue de saisie est proposé grâce à la fonction "Saisie". Ci-dessous, son illustration extraite de l'aide de WINDEV.



Astuce, n'oubliez pas les minuteries. Il est rare de bloquer une application sur un dialogue, il peut être utile de forcer sa validation sans réponse de l'utilisateur après un certain laps de temps. C'est la fonction "DélaiAvantFermeture" qui appelée avant "Dialogue" vous permet d'ajouter une minuterie sur le bouton qui valide le dialogue.

10 octobre 2006

Piloter la sauvegarde d'une base de données Hyper File Client/Serveur

Voici un code prêt à l'emploi qui m'a donné du fil à retordre, car l'aide en ligne de la commande était erronée ! En effet, il y avait une coquille sur le paramètre permettant de donner le mot de passe. Le bon paramètre est /MDP_DB et non pas /MDP_BD.

Vous pouvez copier directement le code sur le fil correspondant dans le forum

09 octobre 2006

Hyper File, Hyper File Client/Serveur, MYSQL, Oracle, SQL SERVER...

Une demande très courante des développeurs, et de pouvoir changer ou alterner la base de données utilisée par l'application. Utiliser une base Hyper File en mode partage (dit "classique"), ou en mode Client/Serveur suivant le site, ou une base MYSQL...

La solution est très simple, mais de part notre naturel à toujours chercher compliqué, les méthodes employées sont souvent les moins efficaces. Pourtant, avec seulement deux commandes, le W-Langage permet de facilement jongler d'une base de données à l'autre, sans intervenir sur la description des tables dans l'analyse. En effet, le type de base de données indiqué dans l'analyse est indicatif, il est utilisé uniquement par défaut sans mention contraire dans vos traitements. Ainsi dans votre code vous pouvez à tout moment appeler :
- "HOuvreConnexion" : elle permet d'ouvrir une connexion vers une base quelconque, du moment que vous avez une accès natif, ou un provider OLE DB.
- "HChangeConnexion" : elle permet d'associer une ou plusieurs tables de l'analyse, à une connexion qui vient d'être ouverte.
Ainsi une application simplement en redéfinissant la connexion peut changer la base utilisée. Un extrait de code est proposé dans une FAQ PC SOFT.

Attention, il s'agit là du principe de connexion. Bien entendu, le simple faire de changer de base peut ne pas suffire, car chaque base a ses propres spécificités d'utilisation. Si la base Hyper File est en mode Client/Serveur, il faudra privilégier les requêtes pour en tirer les meilleures performances. Mais cela dans un but d'optimisation. Dans tous les cas ou le volume de données traité reste raisonnable, il n'est pas indispensable d'avoir un travail d'optimisation intensif, il est ainsi possible de jongler facilement d'une base à une autre juste avec les commandes "HOuvreConnexion"et "HChangeConnexion".

Ce principe de connexion peut également être utilisé pour effectuer un transfert de données lorqu'il s'agit de bases de données différentes. La notion d'alias vient en renfort, et va permettre d'avoir un unique fichier de l'analyse, accessible en deux exemplaires dans deux connexions différentes. Le traitement peut alors être de la forme suivante :
- "HOuvreConnexion" pour vous connecter à une base quelconque,
- "HAlias" pour avoir une copie du fichier,
- "HChangeConnexion" pour que l'alias travail sur la base sur laquelle la
connexion a été ouverte,
- "POUR TOUT" pour parcourir les enregistrements du fichier source,
- "HCopieEnreg" et "HAjoute" pour copier les enregistrements.
Il est même envisageable de traiter une analyse complète, et plaçant le tout
dans parcours de la liste des fichiers (fonction "HListeFichier").
Il existe également des outils permettant d'effectuer des transferts de données.

06 octobre 2006

Echanger des sources et techniques avec Google ?

L'actualité Google est toujours chargée ces dernières années, elle concerne aujourd'hui tous les développeurs adeptes du partage de sources, et qui ne souhaitent plus réinventer en permanence la roue !

Un nouveau portail "codesearch" a donc vu le jour, et permet d'effectuer des recherches dans les codes sources recensés par Google. Et en matière de recensement, Google sait y faire !

05 octobre 2006

Limiter les ressources sollicitées par les impressions.

Je l'ai évoqué dans un précédent billet, s'il y a bien un domaine dans lequel il faut s'appliquer à ne pas trop solliciter le système, c'est bien celui de l'impression. En effet, si pour l'utilisateur le fait d'imprimer une action anodine, pour le système ce n'est pas rien, il va abondamment solliciter les pilotes de périphériques, les ressources graphiques...

Voici quelques astuces qui vous permettront je l'espère d'augmenter la réussite de vos impressions, essentiellement sur les configurations les plus faiblement dotées (hard et soft).

1. réinitialiser le mécanisme d'impression avant chaque nouvelle impression, avec un appel de la fonction "iRAZ".

2. éviter les images volumineuses en fond de page par exemple en utilisant une image enregistrée pour le Web.

3. sélectionner dans la confi- guration des états, l'option d'impres- sion à chaque page.


4. ralentir l'impression avec la fonction "Multitache" dans le code après impression du bas de page. L'attente doit varier en fonction de la configuration, elle peut être mémorisée dans la base de registres. Un menu "Configuration" de l'application pourra permettre son réglage d'un poste à un autre.

03 octobre 2006

Créer une fenêtre, à partir d'une application existante

Il peut arriver de trouver une fenêtre dans une application existante, avec une interface novatrice ou non, mais en tout cas interessante. Pour réaliser la même dans votre application, une première alternative consiste à recréer champs par champs les éléments de la fenêtre qui aide votre inspiration (notez que je ne parle jamais de copie...).

Mais il y a bien mieux, dans l'assistant de création d'une nouvelle fenêtre. Le volet "Import" vous liste les applications lancées, et vous permet d'en choisir une. A la validation, vous obtiendrez sous WINDEV une fenêtre dont vous pourrez coder les traitements, reprenant tout ou partie de l'interface de l'application existante.

Mise en forme RTF programmée

Voici une méthode que j'utilise couramment pour mettre en forme un texte RTF. Elle permet de créer un "modèle" en RTF, puis de l'utiliser dans un traitement pour une mise en base, ou un affichage.

Première étape, sous Wordpad, préparer le texte avec la mise en forme. Dans le texte, placer des %1, %2 en lieu et place des données effectives, en effectuant toute la mise en forme désirée.

Seconde étape, récupérer à l'aide du bloc note le code RTF avec sa mise en forme, afin de le placer dans une constante du projet. Dans le cas ou la mise en forme doit évoluer régulièrement, il peut être avantageux de récupérer la mise en forme au lancement de l'application, avec la fonction "fChargeTexte".

La technique est en place, pour obtenir l'information avec sa mise en forme dans l'application, il suffira d'affecter un champ RTF, un libellé RTF, ou une rubrique de fichier avec la fonction "ChaineConstruit". Exemple :
LIB_RTF = ChaineConstruit(RTF_RAPPORT, RéseauUtilisateur(), DateVersChaine(DateSys()), sRapport)

Ce texte mise en forme peut également compléter un texte existant, en utilisant la fonction "RTFInsére".

02 octobre 2006

Les possibilités d'un service Web ... sans Web service

L'utilisation d'un Web service peut être commode dans bien des situations pour interroger depuis une application un système distant qui va vous retourner une information : une clé pour l'installation de l'application, l'état d'un processus distant ...

Vous pouvez avec WINDEV créer un Web service, qui sera configuré sur le serveur Web avec l'extension standard SOAP. Cela reviendra à accéder à une bibliothèque (.WDL) regroupant vos traitements, en "traversant" le serveur Web. Vous pouvez obtenir le détail de ce principe, et de sa configuration, dans l'aide de WINDEV, le schéma de principe ci-contre en est issu. Le site "Soapuser.com" montre les principes de communication qui régissent les services Web. Vous pourrez constater que cela n'est pas simple, pour finalement peu de chose : récupérer le résultat d'un traitement exécuté sur un serveur Web.

Le but de ce billet, est de présenter une alternative à la mise en place d'un Web Service, donnant le même résultat, mais évitant la configuration de l'extension SOAP du serveur Web, et le déploiement des modules WINDEV spécifiques (WD100SIIS.DLL, WD100SAPA.DLL ou WD100SAPA2.DLL). Cette alternative peut être mise en œuvre, à partir du moment ou vous disposez d'une application WEBDEV déployée. Cette application, en un minimum de programmation peut devenir un "Web service". Le principe est le suivant :

Côté site WEBDEV, le code du projet sera piloté via sa ligne de commande. Exemple :

ValeurReçueEnParamètre est une chaine
ValeurReçueEnParamètre = PageParamètre("AFAIRE")

SELON ValeurReçueEnParamètre
CAS : "XYZ"
// On a reçu la tâche XYZ à faire
// comme retourner une clé d'installation
// On appelle une procédure qui retourne le résultat
ChaineAffiche(FonctionXYZ())
// On termine le site la session est terminée
FinProgramme()

AUTRES CAS :
// Aucune action spécifique à faire
// lancement normal du site sur sa page
PageAffiche(<1ière>)
FIN

Côté WINDEV, le code n'est pas plus complexe pour interroger le "Web service" grâce à la fonction "HTTPRequete". Voici un exemple :

HTTPRequete("http://serveur/WD100AWP/WD100AWP.EXE/CONNECT/MONSITE?AFAIRE=XYZ")
Info(HTTPDonneRésultat())

La fonction "HTTPDonneRésultat" va retourner l'information renvoyée par la fonction "FonctionXYZ" du site WEBDEV, par l'intermédiaire de la fonction WLangage "ChaineAffiche". En utilisant différentes valeurs pour le paramètre "AFAIRE" il est possible d'utiliser un même site WEBDEV pour effectuer toutes sortes d'actions, en quelque sorte donc de sous-traiter des traitements. Mais appelé sans paramètre, le site WEBDEV garde sa vocation première.

Voilà comment en 5 fonctions WLangage ajouter des fonctionnalité délocalisées à une application WINDEV, en limitant les étapes de configuration. Il est toujours préférable d'utiliser ce que l'on a déjà, plutôt que d'ajouter une couche de technologie supplémentaire.

Configurations de projet

Une possibilité de WINDEV peu connue des développeurs, les "configurations de projet". Il s'agit pourtant de la possibilité de préparer à partir d'un unique projet, plusieurs exécutables avec des contenus différenciés. Les configurations de projet permettent également la création de composants (.WDK), de bibliothèques (.WDL), de Web Service ou d'assemblage .NET.

La mise en pratique des configurations de projet est capitale, dès qu'un projet va être diffusé à plusieurs sites ayant des spécificités. Si une partie du projet est commune à tous les sites, mais que certaines fenêtres et états auront des particularités, ou ne servent que sur un site donné, les configurations de projet évitent de créer les exécutables les uns à la suite des autres.
C'est à la création des configurations que le contenu de chaque exécutable est déterminé en fonction des éléments déjà présents dans le projet. Ensuite le menu "Atelier ... Génération multiple" permet en une seule opération de recréer tous les exécutables. J'ai déjà vu des développeurs crées un exécutable en cochant certains éléments du projet à inclure, puis créer un deuxième exécutable avec d'autres éléments, puis créer un troisième exécutable avec encore de nouveaux éléments pour un autre site ...

Les configurations n'étant pas limitées aux exécutables, elles permettent d'aller bien plus loin en générant par exemple :
- l'exécutable de l'application,
- un composant avec des fenêtres internes qui permettront d'intégrer des parties de l'application dans un autre projet,
- un Web service regroupant des procédures de l'application pour les exploiter via des requêtes http...

Une fois les configurations décrites avec tous leurs éléments, elles sont transparentes pour la suite du développement. Il faut simplement lors de l'ajout d'un nouvel élément (état, classe, fenêtre...) préciser la configuration dans laquelle il doit être placé.

Si un traitement ne doit être exécuté que dans le cas d'une configuration précise, il est possible d'utiliser la commande "ProjetInfo" avec le paramètre "piConfiguration". Il est dommage sur cet aspect que le "code cible conditionnel" ne propose pas les configurations, et qu'il soit nécessaire d'utiliser un traditionnel SELON ProjetInfo(iConfiguration) ...