Sunteți pe pagina 1din 72

Developpez

Sommaire
Eclipse Android Java MS Office Business Intelligence Qt C/C++/Gtk+ Visual Basic Dveloppement Web Liens Page 2 Page 10 Page 13 Page 18 Page 28 Page 34 Page 45 Page 52 Page 59 Page 71

Le Mag

dition de dcembre - janvier 2011/2012. Numro 37. Magazine en ligne gratuit. Diffusion de copies conformes loriginal autorise. Ralisation : Alexandre P ottiez Rdaction : la rdaction de Developpez Contact : magazine@redaction-developpez.com

Article MS Office

Comment positionner un formulaire un endroit dtermin


Ce texte s'adresse des utilisateurs Access dbutants qui veulent s'initier la programmation.
par Claude Leloup Page 18

Article DotNet ditorial


Pour bien dmarrer cette nouvelle anne, le magazine refait le plein de nos meilleurs articles, critiques de livres, questions/rponses, news. Ils sont dcouvrir ou redcouvrir. Profitez-en bien ! La rdaction

Le dbogage sous Visual Basic 6 & Visual Basic pour Application (1re partie)
Tout ce que vous devez savoir sur le dbogage et la gestion des erreurs sous Visual Basic 6.
par DarkVader Page 52

Eclipse
Les derniers tutoriels et articles
Introduction Tycho : construction automatique d'un product Eclipse Ce tutoriel est une introduction Tycho, un plugin pour Maven permettant de construire des bundles OSGi et des plugins Eclipse. Nous montrons par l'exemple comment construire automatiquement des excutables Eclipse (appels product ) par l'intermdiaire de Tycho.
1. Introduction Historiquement la construction automatique de bundles OSGi ou de plugins Eclipse passait par l'utilisation d'un ensemble de tches ANT fournies par la plateforme Eclipse. Malheureusement la manipulation de ces tches ANT n'tait pas simple et l'utilisation dans un outil d'intgration continue (Jenkins, Cruise Control par exemple) tait rendue difficile. ct de cela, Maven l'outil de construction de binaires a dmontr qu'il tait ais de compiler, de jouer des tests et de grer les dpendances dans l'univers Java. Toutefois l'utilisation de Maven dans la plateforme Eclipse tait impossible du fait qu'Eclipse se base sur une architecture OSGi. Avec l'arrive de Tycho, qui est un plugin Maven, il est dsormais possible d'utiliser toute la puissance de Maven pour construire des bundles OSGi et des plugins Eclipse. 2.1. Eclipse RCP / Plugin L'environnement de dveloppement Eclipse est naturellement utilis puisqu'il intgre la plateforme de dveloppement de plugins. Par ailleurs, nous utiliserons la version Indigo qui est la version courante au moment de l'criture de ce tutoriel. Le tlchargement de l'environnement de dveloppement est obtenu sur le site de la fondation Eclipse : Lien 02. Pour l'installation, dcompresser l'archive dans le rpertoire o vous installez gnralement vos applications (par exemple : c:\program files). 2.2. Maven 3 Introduction Tycho : construction automatique d'un product Eclipse

Maven est un outil de construction de binaires pour la plateforme de dveloppement Java. Il se distingue des Dans ce tutoriel, je vous propose l'utilisation du plugin autres outils dans le sens o il utilise une approche Tycho dans le cas de la construction d'excutables Eclipse dclarative. En effet, le contenu et la structure d'un projet RCP galement appels product. Nous montrons par Java sont dcrits. l'exemple toutes les tapes ncessaires en insistant sur la structuration du projet en diffrents plugins et comment Pour utiliser Tycho, vous devez obligatoirement installer la gnrer des binaires selon une version spcifique de la version de Maven 3 disponible en tlchargement sur le plateforme Eclipse. site de la fondatation Apache : Lien 03. Ce tutoriel suppose que vous disposiez des connaissances Pour l'installation, suivre les tapes lmentaires de base sur les technologies suivantes : suivantes : dcompresser l'archive dans le rpertoire o vous dveloppement de plugins avec la plateforme installez gnralement vos applications (par Eclipse (SWT/JFace, Eclipse RCP...), voir la page exemple : c:\program files) ; des tutoriels Eclipse de Developpez.com pour une crer une variable d'environnement M2_HOME mise niveau : Lien 01 ; qui pointe sur le rpertoire de Maven (par construction de binaires avec Maven. exemple : c:\program files\maven3) ; ajouter le rpertoire binaire de Maven la 2. Installation des outils variable d'environnement PATH. Cette section prsente tous les outils utiliss dans le cadre de ce tutoriel. Nous signalons volontairement pour chaque 2.3. Tycho outil, la version utilise lors de la ralisation de ce tutoriel. Tycho est un plugin pour Maven pour construire des Eclipse RCP / Plugin : l'environnement de binaires de bundles OSGi et de plugins Eclipse. Comme dveloppement Java pour dvelopper des plugins indiqu prcdemment il ne peut fonctionner qu' partir de (version 3.7.0). la version 3 de Maven. Maven 3 : l'outil de construction automatique de binaires. Pour l'installation, il suffit de complter le fichier pom.xml Tycho : le plugin pour Maven pour construire des au niveau de la balise <plugins>. Nous tudierons ce point binaires de bundles OSGi et de plugins Eclipse. plus prcisment dans la suite au niveau de la section 3. M2Eclipse: l'intgration de Maven pour Eclipse. Nous dtaillons pour chacun de ces outils la procdure d'installation et de configuration.
<build> ... <plugins> <plugin>

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 2

<!-- enable tycho build extension --> <groupId>org.sonatype.tycho</groupId> <artifactId>tycho-maven-plugin</artifactId> <version>${tycho-version}</version> <extensions>true</extensions> </plugin> </plugins> </build> </project>

demand de redmarrer Eclipse, ne pas accepter le redmarrage et quitter Eclipse. Avant de relancer Eclipse, modifier le fichier eclipse.ini situ la racine de votre rpertoire d'installation d'Eclipse afin de prciser le rpertoire de votre JDK. Le plugin M2Eclipse utilise ce chemin pour excuter ses commandes.

2.4. M2Eclipse M2Eclipse est une intgration de Maven pour l'environnement de dveloppement Eclipse. Son utilisation permet d'employer des commandes Maven directement dans Eclipse et permet galement de rendre la manipulation du fichier pom.xml plus aise puisqu'une interface graphique sous forme de formulaire remplace la reprsentation XML assez verbeuse. Pour l'installation, nous utiliserons l'outil Marketplace de l'diteur Eclipse. Voici les tapes. Ouvrir l'outil Marketplace via le menu Help -> Eclipse Marketplace... Depuis la zone de texte Find, saisir la valeur M2Eclipse, puis cliquer sur "rechercher". Vous devriez obtenir le rsultat prsent sur la capture d'cran ci-dessous :

-vm C:/Program Files (x86)/Java/jdk1.6.0_18/bin/javaw.exe

Redmarrer Eclipse, ouvrir le menu des prfrences (Window -> Preferences) et slectionner les options lies Maven. Depuis les options Maven, afficher les lments lis User Settings et prciser dans la zone User Settings votre fichier settings.xml (li au rpertoire d'installation de Maven 3) et cliquer sur Update Settings.

3. Construction des plugins Dans la suite, nous prsentons l'utilisation de Tycho au travers d'une application RCP contenant une vue affichant un arbre. L'objectif final est de gnrer automatiquement une archive contenant notre product Eclipse. Nous insistons dans un premier temps sur la dcomposition de l'application en plusieurs projets, chacun contenant un fichier de description pom.xml. Cette Cliquer sur Install depuis le plugin Maven dcomposition est prsente ci-dessous : Integration for Eclipse. Aprs un certain temps de recherche, vous keulkeul.tychorcpdemo.aggregator : regroupe devriez obtenir le rsultat suivant, cliquer sur tous les autres projets ; Next. keulkeul.tychorcpdemo.rcp : contient le plugin RCP ; keulkeul.tychorcpdemo.parent : le projet Parent au niveau Maven ; keulkeul.tychorcpdemo.feature : dcrit un projet feature ; keulkeul.tychorcpdemo.repository : contient la description d'un product et l'update site. Dans un second temps, nous dtaillons le contenu de chaque fichier de description pom.xml afin d'indiquer les paramtrages pour Tycho. Accepter la licence d'autorisation, puis cliquer sur Finish. Le plugin va tre install et il vous sera

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 3

3.1. Cration d'un projet Agrgateur (keulkeul.tychorcpdemo.aggregator) Ce projet Agrgateur aura comme seul but de contenir tous les sous-projets (plugins, feature, tests, repository p2...). Du point de vue Maven il s'agira de dcrire dans le fichier pom.xml tous les sous-modules . Veuillez suivre la dmarche ci-dessous. Ouvrir l'assistant de cration de projet File -> New -> Other... Choisir l'lment Maven Project de la catgorie Maven, l'cran ci-dessous doit apparatre :

Choisir l'lment Plug-in Project depuis la catgorie Plug-in Development, puis cliquer sur Next. L'cran ci-dessous doit apparatre :

Cocher l'option Create a simple project (skip archetype selection), puis cliquer sur Next.

Dans le champ Project Name saisir la valeur keulkeul.tychorcpdemo.rcp. Dcocher l'option Use default location. Crer un rpertoire keulkeul.tychorcpdemo.rcp la racine du rpertoire du projet agrgateur cr prcdemment, puis cliquer sur Next. L'cran suivant doit apparatre :

Dans le champ de texte Group Id saisir la valeur tychorcpdemo. Dans le champ de texte Artifact Id saisir la valeur keulkeul.tychorcpdemo.aggregator. Au niveau de la slection Packaging slectionner la valeur pom puis cliquer sur Finish.

Cocher la case Would you like to create a rich client application ? puis cliquer sur Next. L'cran suivant doit apparatre :

Un nouveau projet Maven sera cr contenant un fichier pom.xml. Nous modifierons ce fichier chaque fois que nous ajouterons un nouveau module. 3.2. Cration du plugin RCP (keulkeul.tychorcpdemo.rcp) Ce plugin est particulier dans le sens o il s'agit d'un RCP (Rich Client Application) ce qui signifie qu'il peut tre utilis seul. Comme l'ide n'est pas d'apprendre crer un plugin RCP nous utiliserons un exemple patron. Ouvrir l'assistant de cration de projet File -> New -> Other...
Numro 37 Dcembre - Janvier 2011/2012 Page 4

Developpez Magazine est une publication de developpez.com

Choisir comme patron RCP application with a view puis cliquer sur Next. L'cran suivant doit apparatre :

Choisir depuis Launch with la valeur plug-ins selected below only. Dcocher tous les plugins prsents depuis le nud racine Target Platform. Slectionner uniquement le plugin keulkeul.tychorcpdemo.rcp depuis le nud racine Workspace. Cliquer sur Add Required Plug-ins pour ajouter uniquement les plugins requis l'excution de ce plugin RCP. Cliquer sur Run. Vous devriez obtenir l'cran suivant :

Dans le champ Application window title saisir la valeur Keulkeul Tycho RCP Demo Application. Slectionner l'option Add branding ce qui permettra d'tre identifi comme un product lors de la cration de la configuration d'excution, puis cliquer sur Finish.

Un nouveau projet keulkeul.tychorcpdemo.rcp vient d'tre cr. Pour s'assurer que ce plugin RCP fonctionne nous allons crer une configuration d'excution. Ouvrir l'cran de cration des configurations. Depuis le menu principal Run -> Run Configurations ... L'cran suivant doit apparatre :

Ajouter un nouveau fichier Maven pom.xml la racine de ce projet (keulkeul.tychorcpdemo.rcp) dont le contenu est le suivant :

<project> <modelversion>4.0.0</modelversion> <parent> <groupid>tychorcpdemo</groupid> <artifactid>keulkeul.tychorcpdemo.parent</artifa ctid> <version>1.0.0-SNAPSHOT</version> <relativepath>../keulkeul.tychorcpdemo.parent/po m.xml</relativepath> </parent> <groupid>tychorcpdemo</groupid> <artifactid>keulkeul.tychorcpdemo.rcp</artifacti d> <version>1.0.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project>

Crer une nouvelle configuration de type Eclipse Application dont le nom sera TychoRCPDemo. Choisir depuis Run a product la valeur keulkeul.tychorcpdemo.rcp.product (uniquement disponible si vous aviez coch l'option Add branding. Slectionner l'onglet Plug-ins et vous devriez obtenir l'cran suivant :

Comme vous pouvez le constater, ce fichier pom.xml fait rfrence un pom.xml parent que nous dfinirons plus tard. Intressons-nous d'abord l'ajout d'un projet keulkeul.tychorcpdemo.rcp comme module au projet keulkeul.tychorcpdemo.aggregator. Par consquent modifier le fichier pom.xml du projet keulkeul.tychorcpdemo.aggregator de cette manire :

<project> <modelVersion>4.0.0</modelVersion> <groupId>tychorcpdemo</groupId> <artifactId>keulkeul.tychorcpdemo.aggregator</ar tifactId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>keulkeul.tychorcpdemo.parent</module> <module>keulkeul.tychorcpdemo.rcp</module>

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 5

</modules> </project>

De mme nous profitons de cette modification pour ajouter un autre module keulkeul.tychorcpdemo.parent.

keulkeul.tychorcpdemo.aggregator \pom.xml keulkeul.tychorcpdemo.parent \pom.xml keulkeul.tychorcpdemo.rcp \src \pom.xml

3.3. Cration d'un projet parent (keulkeul.tychorcpdemo.parent) Le projet parent a pour objectif de contenir toutes les configurations propres Tycho dont tous les plugins auront besoin. Il contiendra galement les liens vers les entrepts p2.

3.4. Dmarrer une construction du projet via Maven

Nous allons volontairement construire le projet en utilisant l'invite de commandes de Windows au lieu d'utiliser le plugin M2Eclipse. En effet, Tycho est surtout utilis pour construire le projet final via un outil d'intgration continue. C'est une faon de s'assurer que cette construction La dmarche de cration de ce projet est identique celle fonctionne en dehors de l'environnement Eclipse. utilise pour crer le projet keulkeul.tychorcpdemo.aggregator la diffrence que ce Ouvrir l'invite de commandes de Windows et se placer la projet doit tre plac la racine du projet agrgateur. Pour racine du rpertoire parent. Saisir la ligne de commande les valeurs donner dans le nouveau fichier pom.xml, ci-dessous : suivre les indications donnes ci-dessous. mvn clean install Dans le champ de texte Group Id saisir la valeur tychorcpdemo. Dans le champ de texte Artifact Id saisir la valeur Normalement si tout se passe bien vous devriez obtenir le message suivant : keulkeul.tychorcpdemo.parent. Au niveau de la slection Packaging slectionnez la valeur pom puis cliquer sur Finish. Complter le fichier pom.xml gnr par les informations lies la configuration de Tycho
<project> <modelVersion>4.0.0</modelVersion> <groupId>tychorcpdemo</groupId> <artifactId>keulkeul.tychorcpdemo.parent</artifa ctId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <properties> <tycho-version>0.11.0</tycho-version> </properties> <repositories> <!-- configure p2 repository to resolve against --> <repository> <id>helios</id> <layout>p2</layout> <url>http://download.eclipse.org/releases/heli os/</url> </repository> </repositories> <build> <plugins> <plugin> <!-- enable tycho build extension --> <groupId>org.sonatype.tycho</groupId> <artifactId>tycho-maven-plugin</artifactId> <version>${tycho-version}</version> <extensions>true</extensions> </plugin> </plugins> </build> </project>

3.5. Cration d'un projet feature (keulkeul.tychorcpdemo.feature) Ce projet de type feature va nous permettre de regrouper dans une feature l'ensemble des plugins de notre application. Il faut admettre que pour l'instant il n'y en a pas normment. L'ide est que si vous souhaitez ajouter de nouveaux plugins, vous n'aurez qu' modifier cette feature. Ouvrir l'assistant de cration de projet File -> New -> Other... Choisir l'lment Feature Project depuis la catgorie Plug-in Development, puis cliquer sur Next. L'cran ci-dessous doit apparatre :

ce niveau vous devriez obtenir la structure de fichiers suivante :

Choisir comme nom keulkeul.tychorcpdemo.feature.

de

projet

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 6

Personnaliser le rpertoire de travail pour tre la racine du projet keulkeul.tychorcpdemo.aggregator. Choisir depuis la liste des plugins disponibles (Initialize from the plug-ins list) le plugin keulkeul.tychorcpdemo.rcp puis cliquer sur Finish.

Ouvrir le fichier site.xml et depuis l'onglet Site Map crer une nouvelle catgorie appele TychoRCPDemo. Depuis cette nouvelle catgorie, ajouter la feature keulkeul.tychorcpdemo.feature cre prcdemment (voir capture d'cran ci-dessous).

Un nouveau projet keulkeul.tychorcpdemo.feature vient d'tre cr. Ajouter un nouveau fichier Maven pom.xml la racine de ce projet dont le contenu est le suivant :
<project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>tychorcpdemo</groupId> <artifactId>keulkeul.tychorcpdemo.parent</artifa ctId> <version>1.0.0-SNAPSHOT</version> <relativePath>../keulkeul.tychorcpdemo.parent/po m.xml</relativePath> </parent> <groupId>tychorcpdemo</groupId> <artifactId>keulkeul.tychorcpdemo.feature</artif actId> <version>1.0.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project>

Ajouter un nouveau fichier Maven pom.xml la racine de ce projet dont le contenu est le suivant :

Ajouter ce nouveau projet comme module en compltant le pom.xml du projet keulkeul.tychorcpdemo.aggregator. Vrifier que l'application se construit correctement via un mvn clean install.

<project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>tychorcpdemo</groupId> <artifactId>keulkeul.tychorcpdemo.parent</artifa ctId> <version>1.0.0-SNAPSHOT</version> <relativePath>../keulkeul.tychorcpdemo.parent/po m.xml</relativePath> </parent> <groupId>tychorcpdemo</groupId> <artifactId>fr.ensma.lisi.tychorcpdemo.repositor y</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>eclipse-repository</packaging> </project>

3.6. Cration d'un projet update site (keulkeul.tychorcpdemo.repository) Ce nouveau projet a pour objectif de crer un update site de notre projet. Cela permettra ainsi d'utiliser l'outil de mise jour pour installer nos nouveaux plugins. Ouvrir l'assistant de cration de projet File -> New -> Other... Choisir l'lment Plug-in Project depuis la catgorie Plug-in Development, puis cliquer sur Next. L'cran ci-dessous doit apparatre :

Ajouter ce nouveau projet comme module en compltant le pom.xml du projet keulkeul.tychorcpdemo.aggregator. Vrifier que l'application se construit correctement via un mvn clean install.

3.7. Cration d'un fichier product (keulkeul.tychorcpdemo.repository) Le fichier product contient toutes les informations relatives la construction d'un excutable Eclipse (plateformes supportes, le splashscreen, le nom de l'application, les images...). Ouvrir l'assistant de cration de projet File -> New -> Other... Choisir l'lment Product Configuration depuis la catgorie Plug-in Development, puis cliquer sur Next. L'cran ci-dessous doit apparatre :

Choisir comme nom de projet keulkeul.tychorcpdemo.repository. Personnaliser le rpertoire de travail pour tre la racine du projet keulkeul.tychorcpdemo.aggregator. Cocher l'option Generate a web page listing all available features within the site puis cliquer sur Finish. Depuis le nouveau projet gnr, renommer le fichier site.xml en category.xml.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 7

Choisir le projet keulkeul.tychorcpdemo.repository. Saisir la valeur tychorcpdemo.product dans le champ File name. Choisir pour l'option Use a launch configuration la valeur TychoRCPDemo puis cliquer sur Finish. diter en mode texte le fichier tychorcpdemo.product (sans l'diteur de configuration de product) et ajouter les instructions suivantes qui permettront de dmarrer les plugins adquats au lancement de l'application RCP

<configurations> <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" /> <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" /> <plugin id="org.eclipse.osgi" autoStart="true" startLevel="-1" /> </configurations>

<build> <plugins> <plugin> <groupId>org.sonatype.tycho</groupId> <artifactId>tycho-p2-directorplugin</artifactId> <version>${tycho-version}</version> <executions> <execution> <id>materialize-products</id> <goals> <goal>materialize-products</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

Finalement depuis le projet feature (keulkeul.tychorcpdemo.feature) il nous reste ajouter le fragment SWT correspondant la plateforme Windows Depuis l'onglet Overview du mode dition du (notre plateforme de tests) de faon construire le product fichier tychorcpdemo.product, saisir la valeur pour cette plateforme. TychoRCPDemo.product. Modifier l'option The Product configuration is noter que pour le support de diffrentes versions de based on par la valeur features. Windows (64 bits par exemple) ou le support de diffrents S'assurer que la valeur systmes d'exploitation (Linux, MAC OS X...), il sera keulkeul.tychorcpdemo.rcp.product est ncessaire de ritrer cette tape. slectionne pour l'option Product et que la valeur Ouvrir le fichier feature.xml et afficher l'onglet keulkeul.tychorcpdemo.rcp.application est Plug-ins. slectionne pour l'option Application. Voir Ajouter la feature capture d'cran ci-dessous : org.eclipse.swt.win32.win32.x86 et dfinir la valeur win32 dans le champ Operating Systems, la valeur win32 dans le champ Window Systems et la valeur x86 dans le champ Architecture. Voir capture d'cran ci-dessous pour visualiser le rsultat attendu :

Depuis l'onglet Dependencies choisir la valeur keulkeul.tychorcpdemo.feature. Voir capture d'cran ci-dessous : Vrifier que l'application se construit correctement via un mvn clean install. Depuis le rpertoire keulkeul.tychorcpdemo.repository/target/products /TychoRCPDemo.product/win32/win32/x86 vous devriez obtenir le rsultat de cette construction. Un product Eclipse construit automatiquement l'aide de Maven/Tycho.

Pour construire un product Eclipse selon un environnement donn (OS/WS/Arch) complter le fichier pom.xml du projet keulkeul.tychorcpdemo.repository comme prsent ci-dessous :

4. Conclusion Ce tutoriel a prsent une introduction l'utilisation du plugin Tycho pour construire automatiquement un product Eclipse. Nous avons insist sur la structuration des diffrents plugins qui composent notre projet et sur le
Numro 37 Dcembre - Janvier 2011/2012 Page 8

Developpez Magazine est une publication de developpez.com

contenu XML placer dans les diffrents fichiers de 5. Liens description spcifiques Maven. Vous trouverez ci-dessous en ensemble de liens qui peuvent complter ce tutoriel : De nombreuses fonctionnalits restent dcouvrir Apprendre construire un plugin : Lien 04. concernant Tycho et notamment la possibilit d'excuter Quelques billets sur Tycho : Lien 05. des tests unitaires, de grer des dpendances de Site de Tycho : Lien 06. bibliothques tierces, de gnrer un product Eclipse selon la version de la plateforme, de dployer les nouveaux plugins dans un update site, et de faire rfrence des 6. Sources plugins depuis un update site donn. Les sources de ce tutoriel sont disponibles ici : FTP (Lien 07) ou HTTP (Lien 08). Retrouvez l'article de Mickael BARON en ligne : Lien 09

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 9

Android
Les dernires news
Globalement, le march des tlphones mobiles enregistre une hausse de 5,6 % par rapport la mme priode de Plus dun smartphone vendu sur deux sous lOS lanne dernire, avec prs de 440,5 millions de dispositifs de Google dans le monde vendus. Les ventes de smartphones, quant elles, ont Le succs dAndroid se confirme en France. Le systme quasiment explos avec une hausse de 42 % par rapport dexploitation de Google est devenu lOS mobile numro 2010. 115 millions de smartphones ont t vendus au 1 sur le territoire franais, selon un rcent rapport publi troisime trimestre. par le cabinet dtude des mdias Mdiamtrie. Ct constructeurs, Samsung devient le premier En six mois, les achats de nouveaux smartphones sous constructeur de smartphones pour cette priode. Nokia Android par les consommateurs ont t deux fois plus demeure nanmoins le premier fabricant de tlphones nombreux quau premier trimestre 2011, permettant ainsi mobiles. lOS de devancer pour la premire fois iOS en France avec 40 % de parts de march. Commentez la news d'Idelways en ligne : Lien 10

Android devient numro 1 en France

L'attrait des terminaux mobiles sous lOS de Google au cours de ces derniers mois se confirme aussi de faon globale travers le monde entier.

Google publie le code source d'Android 4

Le kit de dveloppement natif de l'OS supporte dsormais les API de cette version Les rsultats dune nouvelle tude du cabinet danalyse Gartner, au cours du troisime trimestre de cette anne, Sur la mailing-list d'Android, un ingnieur de Google rvlent quAndroid dtient une part de march de 52,5 %, annonce la publication progressive du code source d'Ice soit le double des ventes de smartphones Android au Cream Sandwish (Lien 11) sur son serveur Git public, d'o troisime trimestre 2010. il peut tre librement tlcharg. Pour Gartner, cette croissance dAndroid se justifie par la diversit des terminaux mobiles sous lOS, un affaiblissement de lenvironnement concurrentiel, le manque de nouveaux produits pour les systmes dexploitation alternatifs comme Windows Phone 7 et BlackBerry OS. Cette ouverture constitue un pas significatif pour Android, car il s'agit de la premire fois qu'une base de code de l'OS, adapte aux tablettes, soit accessible. Android 4 reprsente un environnement unifi pour les smartphones et les tablettes. Pour ces dernires, une version d'Android a t ddie : Honeycomb (Android 3) (Lien 12), mais son code source n'a jamais t publi La seconde place est occupe par Symbian, qui enregistre (Lien 13). Google avait slectionn les partenaires qui ont une chute de prs de 20 points en un an, pour se retrouver eu droit de l'utiliser, l'instar de Motorola pour sa tablette 16,9 % de parts de march au cours de cette priode. Xoom. On constate galement une baisse des ventes de liPhone dApple, dont la part reprsente dsormais 15 % pour le troisime trimestre, contre 16,6 % pour la mme priode de lanne dernire. Cette baisse sexplique selon linstitut Gartner par lattente du nouvel iPhone par les consommateurs. Ces sources dsormais disponibles incluent tout l'historique de l'volution du code. Il est donc possible de remonter aux sources de Honeycomb que Google n'a pas tagu afin de dissuader les dveloppeurs de l'utiliser. L'ingnieur Jean-Baptiste Queru explique dans cette annonce que cette version est quelque peu incomplte. Nous voulons que chacun se concentre sur Ice Cream RIM, le constructeur des tlphones BlackBerry, recule Sandwish , dclare-t-il. aussi de quatre points sur un an avec 11 % de parts de march pour le troisime trimestre. Gartner constate Lors de la sortie des premiers appareils sous Honeycomb, nanmoins que les ventes des tlphones de la firme sont beaucoup d'observateurs avaient fustig le modle open restes stables entre les deux trimestres. source trs contrl. Google publie cette fois le code source avant le lancement commercial du Galaxy Nexus, mais n'amliore pas la gouvernance du projet, toujours sens unique. Paralllement, le Kit de Dveloppement Natif de l'OS vient d'avoir une nouvelle rvision qui expose aux applications C et C++ les nouvelles API introduites par Android 4.0 : Lien 14.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 10

Les dernier tutoriels et articles


Android et les Services Web SOAP

Les instructions pour tlcharger les sources d'Android Tlcharger la nouvelle rvision du NDK : Lien 16 4.0.1 sont consultables sur cette page : Lien 15 Commentez la news d'Idelways en ligne : Lien 17 Android et les Services Web SOAP

Cet article va vous prsenter comment appeler des Services Web SOAP au sein de votre application Android et comment parser le rsultat de l'appel.
1. Prambule web-services/wsdl?WSDL, celle-ci proposant la mthode getMeteo(String ville). Voyons comment appeler ce L'appel de Services Web SOAP peut s'avrer trs utile au service : sein d'une application Android. Ici nous allons voir comment appeler un Service Web permettant de connatre public class AppelService { la mto du jour. Avant cela, une petite mise au point est ncessaire. private static final String NAMESPACE = Tout d'abord, qu'est-ce qu'un Service Web ? Un Service Web est une fonctionnalit excutable distance pouvant tre dveloppe dans divers langages comme Java, .NET... Ces services peuvent tre appels partir d'un langage diffrent de celui du service. Par exemple, il est possible d'appeler un service cod en Java au sein d'un code en PHP. Les fonctionnalits de ces Web_Services peuvent tre des interactions avec une base de donnes, fournir des informations au programme appelant le service. Un Service Web SOAP ncessite une WSDL contrairement des services REST. Qu'est-ce qu'une WSDL? Le WSDL est une description fonde sur le XML qui indique comment utiliser le service. Le WSDL sert dcrire : - le protocole de communication (SOAP RPC ou SOAP orient message) ; - le format de messages requis pour communiquer avec ce service ; - la dfinition des mthodes qu'il est possible d'appeler ; - la localisation du service. Une description WSDL est un document XML qui commence par la balise "definitions" et qui contient les balises suivantes : - "binding" : dfinit le protocole utiliser pour invoquer le service web ; - "port" : spcifie l'emplacement actuel du service ; - "service" : dcrit un ensemble de points finals du rseau. Des outils sont-ils ncessaires? Pour appeler un Service Web SOAP, une bibliothque est ncessaire vu qu'il n'existe pas un tel outil dans le SDK d'Android. Il s'agit de la bibliothque kSoap2 disponible l'adresse suivante : kSoap2 (Lien 18). Elle permettra galement de parser la rponse du service. 2. Appel d'un service Nous allons supposer qu'une WSDL (Web Services Description Language, ou langage de description de services) est disponible l'adresse http://mon-exemple"http://mon-site-web.fr"; private static final String URL = "http://monexemple-web-services/wsdl.WSDL"; private static final String SOAP_ACTION = "getMeteo"; private static final String METHOD_NAME = "getMeteo"; private String getMeteo(String ville) { try { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); request.addProperty("ville", ville); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL); androidHttpTransport.call(SOAP_ACTION, envelope); } catch (Exception e) { Log.e("getMeteo", "", e); } } }

Rien de spcial retenir dans ce code part qu'il utilise intgralement la bibliothque. Afin de pouvoir l'utiliser, il vous faudra juste remplacer les constantes par vos URL et noms de mthodes, adaptes votre WSDL et si ncessaire ajouter des paramtres votre requte. Voil, nous savons donc maintenant comment appeler un Service Web 3. Parser une rponse SOAP Il est fort intressant de savoir appeler un Service Web, encore faut-il savoir comment parser la rponse. Ici, nous voulons donc parser la rponse SOAP se prsentant de la manire suivante :
<meteo> <temps>beau</temps> </meteo>

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 11

Log.e("getMeteo", "", e); public class AppelService { } private static final String NAMESPACE = "http://mon-site-web.fr"; private static final String URL = "http://monexemple-web-services/wsdl.WSDL"; private static final String SOAP_ACTION = "getMeteo"; private static final String METHOD_NAME = "getMeteo"; private String getMeteo(String ville) { String meteo = null; try { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); request.addProperty("ville", ville); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL); androidHttpTransport.call(SOAP_ACTION, envelope); SoapObject objetSOAP = (SoapObject)envelope.getResponse(); meteo = this.parserObjet(objetSOAP); } catch (Exception e) { private String parserObjet(SoapObject objet) { SoapObject meteoObjet = (SoapObject)positionSoap.getProperty("meteo"); String meteo = meteoObjet.getProperty("temps").toString(); return meteo; } } }

Un simple appel la mthode getProperty permet de rcuprer un autre objet SoapObject ou directement la valeur d'une proprit. 4. Conclusion Vous avez pu voir qu'il est trs simple de faire appel des Services Web SOAP et de parser les rsultats. Ici, il s'agit d'un exemple simple mais mme si vous faites face un plus compliqu, vous ne serez pas perdu ! Dans un prochain article, nous verrons comment appeler des Services REST. Retrouvez l'article de Michel Dirix en ligne : Lien 19

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 12

Java
Les derniers tutoriels et articles
Introduction l'cosystme Java Cet article fait un vaste tour d'horizon du monde java et des technologies qui y sont lies afin de permettre aux nouveaux arrivants de se faire une ide d'ensemble.
1. Introduction La trs grande richesse de Java constitue galement l'un de ses dfauts du point de vue de la personne qui dbute et qui ne sait pas trop par o commencer. De fait, les tutoriels pour apprendre les bases sont nombreux (Lien 20), mais lorsqu'il faut aller au-del, chaque cours va tre li un aspect spcifique de Java, et il n'est pas toujours ais de voir les liens entre toutes les facettes, en particulier lorsque l'on dbute. Le but de ce tutoriel est donc de prsenter une approche parmi d'autres de la dcouverte progressive de l'cosystme Java et galement du J2EE. La complexit de ce tutoriel n'est pas linaire, elle augmente mesure que des choses plus compliques sont abordes. Arrtez-vous lorsque vous commencerez ne plus comprendre, et n'hsitez pas cliquer sur les liens qui renvoient vers des tutoriels ayant trait aux sujets abords ;). 2. Ma premire classe Ce paragraphe est davantage destin situer le point de dpart de la progression du tutoriel qu' fournir un point de dpart dans l'apprentissage de Java. De fait, dans l'ensemble de ce tutoriel, on supposera que les bases de la programmation oriente objet (POO) en Java sont connues du lecteur. Pour l'criture de la premire classe Java, point n'est besoin d'utiliser un outillage complexe. partir du moment o vous avez install un JDK et configur les variables d'environnement (Lien 21), de simples diteurs de texte tels que Notepad sous Windows ou Gedit sous Ubuntu suffisent pour crire le premier programme.
public class PremiereClasse { public static void main(String[] args) { System.out.println("Bonjour ceci est mon premier essai avec Java"); } }

Introduction l'cosystme Java

prouverez rapidement le besoin d'utiliser un diteur de texte qui fournisse au minimum la coloration syntaxique afin de rendre la lecture de code plus aise. Gedit sous Linux le fait dj, mais il existe des solutions plus pousses comme Geany (qui est multiplateforme) ou Notepad++ (pour Windows et Mac). 3. Utilisation d'un environnement de dveloppement Si vous progressez en Java, vous allez rapidement vous retrouver confront aux limites de l'approche prcdente et commencer utiliser un environnement de dveloppement. Il s'agit d'un logiciel qui va automatiser tout ce que vous faisiez la main en ligne de commande et vous fournir des outils d'aide au dveloppement qui vont grandement vous faciliter la vie. Le plus connu est Eclipse (Lien 22), mais il existe plusieurs autres possibilits (Lien 23). Dans un environnement de dveloppement (EDI, ou en anglais : IDE), vous allez pouvoir trs facilement compiler et tester vos programmes, utiliser des fichiers diffrents pour chaque classe, structurer les classes en packages et sous-packages , exporter l'ensemble du projet sous forme d'un jar excutable, ajouter des bibliothques tierces, et dans le cas d'un projet J2EE, dployer le projet dans un serveur d'applications, toutes oprations qui taient dj possibles en ligne de commande, mais qui vont se trouver en pratique grandement facilites par l'utilisation d'un EDI. Dans la suite de ce tutoriel nous nous concentrerons sur Eclipse, qui est le plus rpandu (mais pas forcment le plus simple). Vous trouverez ici de nombreux cours pour apprendre dbuter avec Eclipse : Lien 24.

Quelques raccourcis clavier pour vous mettre l'eau la bouche : CTRL+ESPACE = autocompltion. Vous commencez crire un mot et Eclipse le termine pour vous ; ALT+MAJ+J = Javadoc. Permet de gnrer automatiquement le squelette des commentaires Aprs sauvegarde dans un fichier que l'on nomme donc qui ont trait au code survol par le curseur ; "PremiereClasse.java" on peut compiler puis excuter en ligne de commande l'aide de : CTRL+MAJ+O = Import automatique des dpendances requises par votre classe pour peu $ javac PremiereClasse.java qu'elles soient contenues dans des bibliothques $ java PremiereClasse situes dans le CLASSPATH du projet.
Bonjour ceci est mon premier essai avec Java

On peut coder un moment de cette manire. Tant que l'on ne va utiliser que les bibliothques fournies avec le JDK, a ne pose aucun souci. Il suffit de placer toutes ses classes la suite dans le mme fichier (une seule sera publique, celle qui contient la mthode main). Cependant vous

Le Classpath est une variable d'environnement du projet qui recense l'ensemble des chemins dans lesquels le compilateur va pouvoir trouver des classes ou des bibliothques du projet. Attention l'UTF-8. Par dfaut, Eclipse enregistre les
Numro 37 Dcembre - Janvier 2011/2012 Page 13

Developpez Magazine est une publication de developpez.com

fichiers dans le codage de caractres systme. C'est--dire en gros ISO pour Windows et UTF-8 pour les autres. C'est pourquoi il est conseill de choisir un codage donn et de s'y tenir si vous ne souhaitez pas avoir de problmes avec des caractres accentus qui s'affichent mal (je vous recommande le tout UTF-8). 4. Premires interfaces graphiques En gnral, on fait ses armes sur AWT et (surtout) SWING, deux frameworks graphiques inclus dans le JDK, qui permettent la cration relativement rapide d'interfaces graphiques. Pour quelqu'un qui dbute, le niveau de difficult peut sembler augmenter, car il y a un certain nombre de nouveaux concepts assimiler, notamment ceux de Layout (comment organiser les contrles de l'interface) (Lien 25) et d'EventListener (ou comment relier un bouton une mthode) (Lien 26). Si vous venez d'un langage assez unifi comme le .Net, vous allez commencer prendre conscience qu'en Java comme dans beaucoup d'autres langages, on code partir de multiples briques fonctionnelles forges par d'autres, et qui ne sont pas toujours faciles manipuler. Si jamais vous avez la sensation de vous battre avec un framework, dites-vous que a peut valoir le coup de chercher mieux comprendre quand, par qui, comment et pourquoi il a t conu ;). Pour vous aider dmarrer, il y a plthore de tutoriels sur les interfaces graphiques Java : Lien 27. noter qu'alternativement SWING, vous pouvez aussi vous tourner vers SWT (Lien 28), qui a t dvelopp par IBM pour pallier certains inconvnients de SWING. On peut galement mentionner ici les RCP (RCP signifie "Rich CLient Platform"), qui fournissent des interfaces standard et fournissent un important package logiciel prenant en compte les concepts d'extensibilit, de docking, d'onglets, de menus, de prfrences, etc. mais se situent un niveau au-dessus de SWING et SWT en termes d'abstraction. Citons par exemple les plateformes Eclipse RCP (Lien 29) et Netbeans RCP, sur lesquelles sont bass les IDE du mme nom. Pour aller plus loin : Lien 30. 5. Traduction au sein de mon application (i18n et l10n) Envie de crer un programme qui soit utilisable par des gens parlant diffrents langages ? Il est relativement ais de parvenir ce but. L'astuce est toute simple : l o d'ordinaire vous criviez en dur dans le code la phrase afficher, vous allez en lieu et place utiliser une cl de traduction et utiliser la classe ResourceBundle (Lien 31) pour faire le lien avec la traduction correspondante que vous aurez place dans un fichier de proprits situ dans le classpath. Ceci est davantage dvelopp dans le chapitre 24. L'internationalisation (Lien 32) du cours Dveloppons en Java de J.M.Doudoux : Lien 33. Pour aller plus loin, il est galement intressant de mentionner ce tutoriel : Lien 34. Comme le mentionne la documentation de la classe PropertyResourceBundle (Lien 35), il est prfrable que les fichiers de proprits soient encods au format ISO8859-1 Si vous vous demandez ce que veulent dire i18n et l10n, sachez que ces sigles barbares sont des raccourcis pour InternationalizatioN et LocalisatioN. chaque fois on a

gard la premire et la dernire lettre, et entre les deux on a mis le nombre de lettres intermdiaires. 6. Un peu d'architecture Arrivs un certain stade de dveloppement, avec un projet sans cesse croissant en taille et en complexit, vous allez prouver le besoin de dcouper le projet en plusieurs couches fonctionnelles et d'organiser vos classes au sein de ces couches afin de mieux dgager la structure d'ensemble et rendre la comprhension gnrale plus aise. Le mcanisme des packages est d'une grande aide pour cela. Une architecture trs courante est l'architecture dite "trois tiers" : elle consiste construire une application en trois couches : la couche dite "de prsentation" gre l'interface graphique, la couche dite "mtier" contient le cur de l'application, et la couche dite "d'accs aux donnes" permet de lire/persister les donnes ncessaires l'application (typiquement l'accs une base de donnes). Ayez l'esprit que pour russir crer une application dote d'une bonne architecture, il faut y rflchir avant de commencer coder. C'est toute la phase de modlisation, prliminaire ncessaire la cration de toute application un tant soit peu complexe. Pour cette raison, il y a de nombreux tutoriels sur la question : Lien 36. Mais attention, il n'est pas toujours bon de se lancer dans une modlisation trs complexe, cela doit vraiment dpendre de vos besoins. Abandonnez l'ide du design parfait (qui n'existe pas), car vous aurez forcment besoin de retoucher des dtails pendant que vous coderez. Mieux vaut dfinir une architecture gnrale et spcifier en dtail le fonctionnement des algorithmes les plus complexes, mais inutile d'aller plus loin. Vous entendrez probablement parler aussi de Design Patterns : Lien 37. Il s'agit tout simplement des problmes courants que peut rencontrer un dveloppeur et des moyens reconnus par la communaut comme les plus pertinents pour y rpondre. De mon exprience, la plupart ne sont pas immdiatement accessibles au dbutant. Il est ncessaire d'avoir un minimum d'exprience et avoir vraiment t confront au problme pour saisir la pertinence d'un pattern donn. 7. Bibliothques externes et frameworks Java est un langage trs populaire et relativement ancien, il existe donc de nombreux bibliothques et frameworks qui implmentent les besoins les plus courants du dveloppeur et lui permettent de se concentrer sur la partie mtier, c'est-dire ce qui l'intresse vraiment et qui a trait au but dans lequel il dveloppe, et non pas des trucs bateaux comme les entres/sorties, la connexion Internet, l'export sous forme d'images ou de PDF, l'criture d'emails, etc. La diffrence que je verrais entre une bibliothque et un framework est la suivante : une bibliothque est une archive jar que vous allez rajouter dans votre classpath, et dont vous allez utiliser les classes directement. Exemple typique, jdbc (qui permet d'accder une base de donnes). Alors qu'un framework, pour prendre une analogie a va tre comme un programme dj existant au cur duquel vous insreriez le vtre. Le framework se chargeant de toutes les oprations communes et vous apportant des fonctionnalits intressantes comme l'inversion de contrle (ce n'est plus vous qui appelez les
Numro 37 Dcembre - Janvier 2011/2012 Page 14

Developpez Magazine est une publication de developpez.com

classes du framework, mais le framework qui appelle vos classes) et l'injection de dpendances (utile en programmation par contrats : vous dclarez un objet d'aprs l'interface qu'il doit implmenter et vous utilisez son setter pour lui fournir son implmentation vritable), ce qui vous permettra un meilleur dcouplage des diffrentes couches qui constituent l'architecture de l'application. Les frameworks sont particulirement utiles dans l'univers J2EE (construction d'applications Java tournant dans un serveur Web). Exemple typique : Spring (Lien 38). Pour les plus curieux, quelques explications complmentaires sur l'inversion de contrle. L'explication qui en a t donne ici : "ce n'est plus vous qui appelez les classes du framework, mais le framework qui appelle vos classes" est rductrice car elle ne prsente qu'une facette de l'inversion de contrle. Voici une explication plus dtaille : le principe consiste briser une dpendance bidirectionnelle (ou cyclique), ou encore briser une dpendance unidirectionnelle non voulue comme une couche mtier qui invoquerait directement des mthodes de la couche de l'IHM. Il existe deux grosses techniques : par change de messages (cf. middleware) ; par contrat (cf. interface). Dans le premier cas, il s'agit d'avoir un pont de communication abstrait via lequel les lments s'changent des messages. Dans le second cas, on dtermine un jeu d'interfaces (ou de classes abstraites) qui seront implmentes par la couche invoque de manire directe. Ensuite cette mme couche fournit la couche qui en a besoin les implmentations utiliser (souvent par injection). 8. Fichiers de configuration et annotations Tt ou tard, si vous continuez programmer en Java, vous allez avoir besoin d'utiliser des fichiers de configuration et/ou des annotations. Le but est de dcrire le comportement du programme et la manire dont il va interagir avec d'autres programmes. Typiquement vous pouvez utiliser un fichier de configuration qui vous est propre pour indiquer des chemins d'accs, ou des paramtres que vous voulez pouvoir changer sans avoir besoin de recompiler le programme. Mais la premire fois que vous aurez besoin d'utiliser un fichier de configuration sera sans doute pour configurer un framework ou une bibliothque. On distingue gnralement deux types de fichiers de configuration : les fichiers XML et les fichiers de proprits. Les fichiers de proprits sont les plus simples : ils contiennent un ensemble de paires CL=VALEUR raison d'une par ligne. Les dveloppeurs utilisent souvent des noms de cl qui refltent la catgorie de celle-ci. Par exemple "monappli.macouchemetier.coefficients.usure=15". De cette manire il est trs ais de savoir quoi va servir la cl (et d'viter que deux cls nommes usure ayant trait deux choses diffrentes ne se tlescopent). Les fichiers XML sont un peu plus complexes, mais il ne faut pas en avoir peur. La structure est similaire celle d'un fichier HTML et elle est gnralement plus simple. L'avantage du

XML est qu'il permet d'organiser facilement les donnes de configuration. Ce qu'on lui reproche gnralement est sa verbosit : de nombreuses balises sont ncessaires la description d'une information mme simple. Si vous vous lancez dans le J2EE, vous ne pourrez pas en faire l'conomie, puisque vous aurez ncessairement besoin d'un fichier web.xml pour dcrire le comportement de votre application au serveur d'applications dans lequel elle sera dploye. Venons-en aux annotations : Lien 39. Elles sont apparues avec la cinquime version de Java vers fin 2004. Elles visent rduire le volume des fichiers de configuration (voire s'en passer totalement), en crivant directement dans le code l'aide d'une balise spciale des informations lies son comportement. Ce qu'il faut garder en tte, c'est que les annotations ne sont pas un remde miracle, et il ne faut pas verser dans le tout annotations comme certains font, mais savoir les utiliser avec discernement. Le danger est le risque d'parpiller des informations de configuration un peu partout dans le programme alors qu'elles seraient plus claires en tant centralises dans un unique fichier de configuration. C'est en particulier le cas des annotations qui dcrivent le comportement des classes les unes vis-vis des autres. l'inverse, il y a peu d'intrt reporter dans un fichier de configuration des annotations propres au fonctionnement interne d'une classe donne. 9. Tests unitaires Les tests unitaires sont une partie importante des applications que les dveloppeurs ont trop souvent tendance oublier par manque de temps : Lien 40. Il s'agit tout simplement d'une classe de test qui va vrifier que chaque mthode d'une classe effectue bien le travail demand. C'est particulirement utile en cas de refactoring pour se rendre compte immdiatement des problmes qui ont pu arriver. Par ailleurs les tests unitaires contiennent de prcieuses informations sur le comportement attendu de l'application qui sont plus utiles que de longs commentaires. Une bonne pratique consiste crire ses tests unitaires avant d'crire les classes auxquelles ils correspondent. Cela permet tout la fois : de se poser les bonnes questions : "Quel est le comportement attendu de ma classe ?" plutt que de commencer par modliser et d'adapter les mthodes a posteriori ; d'tre sr d'avoir son test unitaire fonctionnel une fois la classe finie, et de ne pas tre influenc dans le sens "je fais un test qui correspond ce que j'avais en tte quand j'ai fait la mthode", ce qui peut parfois constituer un pige, puisque l'on ne vrifie pas la conformit aux spcifications. Cette manire de programmer est appele le TDD (Test Driven Developpement). En Java, le framework communment utilis pour les tests unitaires est Junit (Lien 41), mais il y a galement TestNG (Lien 42), qui est une variante intressante. De nombreux plugins pour Eclipse rendent aise l'utilisation des tests unitaires. Citons tout d'abord le plugin pour JUnit luimme (gnralement fourni par dfaut avec Eclipse), mais galement MoreUnit, qui facilite le lien entre une classe et son test unitaire et la gnration de mocks, ainsi
Numro 37 Dcembre - Janvier 2011/2012 Page 15

Developpez Magazine est une publication de developpez.com

qu'Infinitest, qui permet de relancer automatiquement le 12. Outils de build dernier test effectu chaque enregistrement d'une Maven (Lien 54) devient trs vite incontournable ds lors modification de fichier. que l'on commence avoir un projet Java qui inclut de multiples bibliothques. Il s'agit d'un outil qui permet Rapidement vous pourrez rencontrer le problme suivant : d'inclure facilement les bibliothques dont le projet lorsqu'une classe dpend d'une autre classe, comment besoin, et de les configurer aisment. Il permet galement tester juste cette classe prcise sans tester aussi la de grer les dpendances de manire transitive sans en dpendance ? La solution passe par l'utilisation de stubs oublier aucune, ce qui est un luxe que vous apprcierez (qui simulent le comportement d'une classe donne) ou de lorsque vous vous serez suffisamment battu avec les mocks (qui vont rejouer une srie de comportements "ClassNotFoundException", caractristiques de l'oubli prtablis). Citons EasyMock (Lien 43), Jmockit d'inclusion d'une bibliothque. (Lien 44), et Mockito (Lien 45) parmi les bibliothques de gnration de mocks rpandues. Mais Maven ne s'arrte pas l. Il s'agit en effet d'un outil de build (en franais: de construction) de projet hautement 10. Traces logicielles (logging) configurable, et qui peut s'interfacer de nombreux outils Lorsque l'on teste un programme, on a besoin de savoir ce d'analyse de code (comme Sonar : Lien 55) et d'intgration qu'il se passe. Au dbut on utilise l'instruction continue (comme Hudson (Lien 56) ou Cruise Control "System.out.println()" pour crire dans la console des (Lien 57)), ce qui en fait un outil connatre absolument informations sur le droulement du programme, mais trs pour tout dveloppeur Java qui se respecte. rapidement, cela ne suffit plus car il est ennuyeux de devoir recompiler pour le dsactiver et qu'il serait Alternativement Maven, il convient de mentionner galement souhaitable de pouvoir dfinir des niveaux de galement ANT : Lien 58. Cet outil est plus ancien que criticit des messages. C'est pourquoi une solution Maven et reste d'autant plus rpandu qu'il est aussi trs communment utilise dans le monde de Java est la utilis pour construire des projets dvelopps dans d'autres librairie commons-logging d'Apache (Lien 46). Elle langages. Notons que les deux ne sont nullement contient toutes les classes que vous aurez besoin d'appeler incompatibles, il est possible de les adapter l'un l'autre, depuis votre programme Java. Au lancement elle par exemple pour migrer en douceur. Pour vous faire une recherchera dans votre classpath une dpendance charge ide des avantages/inconvnients des diffrents outils de de la ralisation effective de l'criture ou l'affichage des build, voici un comparatif : Lien 59. traces. En gnral, on utilise log4j pour cette tche : Lien 47. Il est galement possible d'appeler log4j 13. Java EE directement sans passer par commons-logging, mais Java EE (ou J2EE) dsigne l'ensemble des technologies gnralement on s'en abstient pour viter de rendre les permettant de crer des applications d'entreprise. Le traces du programme dpendantes d'une implmentation principe est simple : on veut viter de devoir recoder dans particulire. chaque projet tout ce qui n'est pas spcifique au cur de mtier de l'application. Par consquent, on va utiliser un Il existe d'autres solutions que commons-logging. On peut serveur d'applications (qui va contenir tout le code non citer par exemple SLF4J qui est assez largement utilis : spcifique), et y embarquer notre application (centre sur Lien 48. Il permet de pallier certains dfauts que l'on ce qui est propre notre mtier). Des fichiers de reproche parfois commons-logging. De la mme configuration permettent de dcrire au serveur manire, il en existe aussi pour log4J, dont notamment le d'applications comment l'application doit se comporter. projet Logback (Lien 49), qui se pose comme le J2EE sert souvent la cration d'applications Web, de successeur non officiel de log4J. manire assez similaire ce que fait PHP. Elle est plus complexe mettre en uvre que PHP, mais elle apporte 11. Bases de donnes beaucoup plus de possibilits lorsque l'on recherche des La plupart des applications un tant soit peu volues vont fonctionnalits un peu pousses. avoir besoin de s'interfacer avec des bases de donnes. L'outil universel utilis dans ce but est JDBC : Lien 50. Il Il y a deux facettes dans J2EE. Celle qui est la plus connue est compos de deux parties distinctes : une API Java est la facette "prsentation Web". On l'aborde contenant les fonctions que vous aurez besoin d'appeler, et gnralement en commenant par coder des servlets et des un driver propre la base de donnes que vous allez JSP suivant le modle MVC : Lien 60. On va utiliser. En gnral on commence faire ses armes sur gnralement utiliser un serveur d'applications dit "conteneur lger" qui n'implmente la spcification J2EE l'utilisation des bases de donnes en Java avec cet outil. que dans ce domaine, comme Tomcat (Lien 61) ou Jetty. Cependant il faut savoir qu'il existe des API de plus haut L'tape suivante consiste utiliser un framework tel que niveau qui permettent de grer plus aisment la persistance Spring (Lien 62) ou Seam (Lien 63) pour avoir la plupart des objets mtiers en base de donnes. Citons par exemple des fonctionnalits requises par une application WEB trois JPA (implmentation de la spcification de rfrence) tiers un petit peu plus complexe, et ventuellement un (Lien 51), Hibernate (de loin la solution la plus rpandue) framework de prsentation tel que JSF (obligatoire dans le (Lien 52) et IBatis (qui permet de contrler finement les cas de Seam, et en train de devenir un standard, JSP tant plus ou moins dprci) (Lien 64) pour parfaire requtes SQL excutes) (Lien 53). l'exprience utilisateur mais aussi celle du dveloppeur.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 16

Ce qui est moins connu, c'est que J2EE ne s'arrte pas l. La spcification touche aussi des aspects qui n'intressent que les concepteurs des applications les plus complexes, comme la distribution d'une application sur plusieurs serveurs, avec des fonctionnalits comme le failover (en gros la tolrance aux pannes, si possible sans interruption du service), et le load-balancing (c'est--dire la rpartition de charge, tant au niveau du trafic HTTP, que de la charge de l'application elle-mme). Il est donc possible d'avoir une mme application Java dont les diffrentes instances d'une mme classe seront rparties sur diffrents serveurs. Pour faire tourner de telles applications, il est ncessaire d'utiliser un serveur d'applications dit "conteneur lourd" qui implmente la totalit de la spcification J2EE, tel que par exemple Glassfish et JBossAS. C'est dans ce contexte que vous pouvez tre amen manipuler des EJB (Lien 65) et JCA (Lien 66), qui lors de sa sortie tait prsente par Sun comme "La solution" au problme d'intgration entre le monde J2EE et les systmes d'information d'entreprise.

14. Conclusion C'est la fin de ce tour d'horizon de l'cosystme Java, j'espre ne rien avoir oubli d'essentiel, mais normalement a devrait suffire quelqu'un dbutant le Java pour se faire une ide de la complexit de ce monde et avoir un aperu d'une manire de l'aborder progressivement. Petite astuce pour finir, sachez qu'il existe de nombreux plugins Eclipse qui peuvent vous faciliter grandement la vie. Le plugin m2eclipse pour l'intgration de Maven, le plugin Instasearch pour effectuer des recherches dans les fichiers du projet et le plugin "properties editor" pour diter des fichiers de proprits avec un codage en UTF8 transparent, en sont de bons exemples. Retrouvez l'article de Gauthier Perrineau en ligne : Lien 67.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 17

MS Office
Les derniers tutoriels et articles
Comment positionner un formulaire un endroit dtermin Ce texte s'adresse des utilisateurs Access dbutants qui veulent s'initier la programmation. Dans ce tutoriel nous allons apprendre : - positionner un formulaire un endroit dtermin de l'cran ; - rcuprer les coordonnes d'un formulaire affich. Nous examinerons en dtail le fonctionnement de l'instruction DoCmd.MoveSize. Nous aborderons les notions de twips et pixels. Nous ferons appel une API : GetWindowRect. Le tout au travers d'un exemple concret : un formulaire construit pas pas.
1. Avant-propos Si vous voulez ouvrir un formulaire indpendant un endroit donn avec des dimensions prcises, vous le Access n'offre pas spontanment beaucoup de moyens positionnez manuellement. Ensuite vous le recouvrez pour positionner un formulaire un endroit dtermin de exactement avec cet utilitaire. La commande l'cran. DoCmd.MoveSize avec les paramtres adquats se trouve dans votre presse-papier. Si on veut y arriver, il faut faire appel des API, c'est-dire des interfaces offertes par d'autres programmes (par 2. Le cas banal exemple Windows) qui autorisent l'interaction avec Access. L'utilisation de ces techniques n'est pas facilement Pour illustrer notre propos, construisons un formulaire abordable par un dbutant. appel fOuSuisJe. Voici les rfrences de deux contributions sur 2.1. Construisons notre formulaire Developpez.com qui abordent le sujet au moyen d'API : Dans la fentre Access : onglet Formulaires , clic sur Argyronet a trait le sujet dans son tutoriel Comment positionner un formulaire ouvert depuis , un autre, droite de l'cran : Lien 68. Arkham46 dans la contribution suivante, donne choisir Mode Cration tout le code pour positionner un formulaire sous un contrle d'un autre formulaire : Lien 69. Notre dmarche consistera utiliser une seule API et d'en expliquer le fonctionnement. , Comment positionner un formulaire un endroit dtermin

Comme exemple concret pour illustrer la thorie, nous pour enregistrer sous le nom fOuSuisJe. allons construire pas pas, ce formulaire gadget clic sur nanmoins utilisable : Dans un premier temps, ce formulaire est totalement vide : il ne contient aucun contrle et n'est rattach aucune source. Nous le garnirons au fur et mesure des besoins de l'expos. Nous modifions quelques-unes des proprits comme illustr ci-aprs :

Si on le dplace l'cran ou si on le redimensionne, les donnes affiches sont instantanment actualises.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 18

Sauvegarder le formulaire et ouvrez-le nouveau en dcrit et aux dimensions spcifies dans les paramtres. double-cliquant sur son nom dans la fentre des objets. Nous allons coder cette instruction. Le formulaire s'affiche l'cran l'endroit o il se trouvait lorsque vous l'avez sauvegard. Ouvrons notre formulaire en mode construction. Ouvrez le formulaire. Double-cliquons sur son coin suprieur gauche pour Dplacez-le. afficher les proprits : Sauvegardez-le. Fermez-le. Ouvrez-le nouveau. Faites l'exprience 3. Positionner et dimensionner un formulaire l'ouverture 3.1. La mthode MoveSize de l'objet Docmd Cette mthode permet de dplacer ou de redimensionner la fentre du formulaire. En d'autres mots, elle permet de positionner le formulaire un endroit dtermin d'avance et de prciser la hauteur et la largeur de sa fentre. Pour dcrire, avec des mots, un rectangle affich l'cran, quatre donnes suffisent : la position horizontale du coin suprieur gauche ; la position verticale du coin suprieur gauche ; Double-cliquez sur le texte Sur ouverture (1) et cliquez la largeur ; ensuite sur les (2) qui apparaissent l'extrme la hauteur. droite de la ligne. Ce sont, prcisment, les paramtres de la mthode Vous ouvrez ainsi l'diteur de code VBA, l'endroit qui Docmd.MoveSize. correspond au code associ l'vnement Sur ouverture (Form_Open) du formulaire. Un exemple de syntaxe : DoCmd.MoveSize 2835, 3405, 5670, 5100 Les units de ces arguments sont exprimes en twips. Twip est l'acronyme de TWentIeth of a Point soit de point. C'est une mesure d'affichage indpendante de la rsolution de l'cran. 1 pouce (inch) = 1440 twips. 1 cm = 567 twips. Dans l'exemple, les paramtres expriment que l'on veut placer le coin suprieur gauche 5 cm droite et 6 cm en dessous (nous expliquerons par rapport quoi, plus bas) Vous refermez la fentre de l'diteur de code. et que le formulaire aura 10 cm de large et 9 cm de hauteur. Vous enfoncez la touche <F5> pour passer en mode Formulaire. Ce dernier s'ouvre 5 cm droite et 6 cm en 3.2. Si le formulaire est une fentre indpendante dessous du coin suprieur gauche de l'cran et sa fentre Reprenons notre formulaire fOuSuisJe et essayons de voir fait 10 cm de large et 9 cm de hauteur. quoi correspond une telle syntaxe. Si le formulaire est une fentre indpendante, le point de Nous allons communiquer Access, que l'vnement Sur repre pour positionner avec DoCmd.MoveSize est le coin ouverture du formulaire fOuSuisJe doit dclencher suprieur gauche de l'cran. l'instruction DoCmd.MoveSize 2835, 3405, 5670, 5100. Ceci nous permet d'attirer l'attention sur l'importance de la Nous demandons donc Access que lorsqu'un utilisateur proprit Fen indpendante pour dterminer la position ouvre le formulaire fOuSuisJe, ce dernier soit l'endroit qu'occupera l'cran, le formulaire aprs excution de l'instruction DoCmd.MoveSize.
Numro 37 Dcembre - Janvier 2011/2012 Page 19

Une fentre s'ouvre et affiche les proprits du formulaire. Cliquez sur l'onglet vnement .

L o se situe le curseur, vous saisissez le code : DoCmd.MoveSize 2835, 3405, 5670, 5100. Vous obtenez finalement ceci :

1/20 e

Developpez Magazine est une publication de developpez.com

Le positionnement du formulaire avec la mthode Pour constater o se situe le repre, nous allons modifier MoveSize de l'objet Docmd dpend de la valeur attribue l'instruction : la proprit Fen indpendante . DoCmd.MoveSize 0, 0, 5670, 5100 Nous avons associ DoCmd.MoveSize l'ouverture du formulaire, nous aurions pu l'associer d'autres En franais : dplacer le formulaire 0 twip droite ; 0 twip vnements : le clic sur un bouton par exemple. en dessous ; avec une largeur de 10 cm ; avec une hauteur de 9 cm. 3.4. En rsum Pour accder au code, enfoncez simultanment les touches <ALT> et <F11> (on note : <Alt-Key-F11>). Modifiez l'instruction. Fermez la fentre. Ouvrez le formulaire, il s'ouvre maintenant dans le coin suprieur gauche de votre cran. 3.3. Et si le formulaire n'est pas indpendant ? Essayons ! Basculons notre formulaire en mode cration. Faites un clic droit sur le formulaire et dans le menu contextuel qui s'affiche, cliquez sur l'icne Essayons de faire l'inverse. C'est--dire pouvoir exprimer Affichez les proprits et positionnez NON Fen o se trouve un formulaire ouvert et quelles sont sa largeur et sa hauteur. indpendante. C'est plus dur, car Access, du moins dans la version 2000 ne fournit pas, nativement, ce genre de renseignement. Par contre, de telles informations sont disponibles dans le systme d'exploitation Windows. Windows API ou WinAPI est le nom donn par Microsoft l'interface de programmation (API) qui permet une application comme Access d'interagir avec le systme d'exploitation Windows. Fermez la fentre de l'diteur de code. Fermez le 4.1. GetWindowRect : une API utile pour localiser un formulaire l'cran formulaire en le sauvegardant. GetWindowRect Ouvrez le formulaire nouveau. Cette fonction nous renseigne les coordonns du coin Cette fois la position du formulaire se situe l'intrieur de suprieur gauche et du coin infrieur droit d'un rectangle la fentre de l'application ACCESS en dessous des barres affich l'cran. d'outils et coll au bord gauche. Pour la dclarer dans notre application, il faut insrer ce code dans un module : Dclaration de GetWindowRect
Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" ( _ ByVal hwnd As Long, _ lpRect As RECT) As Long

4. Trouver la position et les dimensions d'un formulaire

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 20

Pour l'utiliser, il faut dfinir un type de donnes : Type Rect


Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type

bas (down) : Top. Rien n'est simple ! Non seulement ce vocabulaire est droutant : quand Access dit droite (Right) Windows dit Left ; quand Access dit Bas (down) Windows dit Top . Mais en plus Windows s'exprime en pixels tandis qu'Access mesure en twips !

Il faudra l'appeler en donnant le paramtre hWnd du rectangle qui nous intresse, en l'occurrence le rectangle Et pour encore corser les choses : le nombre de pixels occup par notre formulaire. dpend de la rsolution de votre cran ! Un hWnd est un nombre entier gnr permettant d'identifier de manire unique l'cran. Dans Access, chaque formulaire ouvert a hWnd qui renseigne ce descripteur Windows. par Windows Il nous faut donc un convertisseur pixels => twips. une fentre En ralit il en faut deux : une proprit attribu par - nombre de pixels d'une distance horizontale => twips ; - nombre de pixels d'une distance verticale => twips. Mais ne brlons pas les tapes. Essayons d'abord de rcuprer les donnes fournies par GetWindowRect. 4.2. Une fonction pour rcuprer les donnes de la position Voici une fonction qui permet de rcuprer, pour un formulaire ouvert dont le nom est donn en paramtre, sa position et ses dimensions exprimes en pixels : Fonction
Option Compare Database Option Explicit

Faites l'exprience Ouvrez fOuSuisJe. Enfoncez <Ctrl-key-G> pour atteindre la fentre d'excution (<Ctrl-Key-G>). Saisissez : ? Forms!fOuSuisJe.hwnd (en franais : afficher la proprit hWnd du formulaire fOuSuisJe) Notez ce numro. Fermez la fentre pour revenir au formulaire. Fermez-le et ouvrez-le nouveau. Retournez la fentre d'excution et rptez la commande. Le numro a chang ! La fonction va nous donner accs quatre nombres : Left, Top, Right et Bottom qui dtermine le rectangle l'cran.

Type Position Droite As Long Bas As Long Largeur As Long Hauteur As Long End Type

Prcisons : Top renseigne la position du premier pixel l'intrieur de la fentre. Par contre, Bottom est en dehors, c'est le pixel qui suit le bord infrieur de la fentre. Si l'un vaut t et l'autre vaut b, alors la hauteur en pixels vaut b t. Pareil, pour Left (dedans) et Right (dehors). Le coin suprieur gauche de notre formulaire a donc comme coordonnes par rapport au coin suprieur gauche de l'cran : droite (Right) : Left ;

Public Function PositionFormPx(NomDuFormulaire As String) As Position Dim rectForm As RECT 'Rcuprer le rectangle de la fentre du formulaire GetWindowRect Forms(NomDuFormulaire).hwnd, rectForm 'Copier les coordonnes du coin sup gauche PositionFormPx.Droite = rectForm.Left PositionFormPx.Bas = rectForm.Top 'Calculer la largeur PositionFormPx.Largeur = rectForm.Right rectForm.Left 'Calculer la hauteur PositionFormPx.Hauteur = rectForm.Bottom rectForm.Top End Function

On commence par dfinir un type de donnes spcifique, qui nous permettra de stocker :

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 21

- Droite la distance entre le bord gauche de l'cran et le coin suprieur du formulaire ; - Bas la distance entre le bord suprieur de l'cran et le coin suprieur du formulaire ; - Largeur de la fentre du formulaire ;

rectForm.Left 'Calculer la hauteur PositionFormPx.Hauteur = rectForm.Bottom rectForm.Top End Function

Dans Access, pour en savoir plus sur un mot-cl, placez le curseur de la souris l'intrieur du mot et enfoncez la touche <F1> : l'aide s'affiche la bonne page. - Hauteur de la fentre du formulaire. Exemple, placez le curseur l'intrieur de Type et enfoncez <F1> : la documentation relative l'instruction Toutes ces donnes seront exprimes en pixels s'affiche. Dans la fonction proprement dite, on invoque Si vous utilisez systmatiquement cette technique durant GetWindowRectpour rcuprer les coordonnes des votre apprentissage, vos progrs seront spectaculaires. quatre coins que l'on exploite pour construire les rsultats Ce conseil vaut aussi pour les proprits des objets (tats, formulaires...) : cliquez sur la proprit, elle s'affiche en de la fonction. surbrillance, et enfoncez <F1>. Testons tout cela concrtement. Dans la barre des menus, cliquez sur Dbogage et Dans la fentre des objets, cliquez sur Modules et ensuite sur Compiler... . ensuite sur Nouveau . Entre autres, ceci nous permet de vrifier l'absence d'erreur Dans la fentre qui s'ouvre, collez ce code qui correspond de code. la dclaration de GetWindowRect : Sauvegardez en donnant ce module le nom mFonctions (par exemple). Declare Function GetWindowRect Lib "user32" ( _
ByVal hwnd As Long, _ lpRect As RECT) As Long Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type

Fermez la fentre de l'diteur VBA. Nous allons maintenant constater que la fonction nous donne le rsultat attendu.

Modifiez le formulaire fOuSuisje comme suit : proprit Fen indpendante => OUI ; code de l'vnement Sur ouverture => Sauvegardez en donnant ce module le nom mAPI (par DoCmd.MoveSize 2835, 3405, 5670, 5100 exemple). Puisque la proprit Fen indpendante est OUI, le Fermez la fentre de l'diteur VBA. formulaire va se positionner par rapport l'cran : 2835 twips du bord gauche ; Dans la fentre des objets, cliquez nouveau sur 3405 twips du bord suprieur ; Modules et ensuite sur Nouveau . avec une largeur de 5670 twips ; avec une hauteur de 5100 twips. Dans la fentre qui s'ouvre, collez le code de notre fonction PositionFormPx : Affichez le formulaire.
Type Position Droite As Long Bas As Long Largeur As Long Hauteur As Long End Type

Accdez la fentre d'excution (<Ctrl-Key-G>) et saisissez : ? PositionFormPx("fOuSuisJe").Droite <Enter> => un nombre s'affiche en dessous. Rptez avec

Public Function PositionFormPx(NomDuFormulaire As String) As Position Dim rectForm As RECT 'Rcuprer le rectangle de la fentre du formulaire GetWindowRect Forms(NomDuFormulaire).hwnd, rectForm 'Copier les coordonnes du coin sup gauche PositionFormPx.Droite = rectForm.Left PositionFormPx.Bas = rectForm.Top 'Calculer la largeur PositionFormPx.Largeur = rectForm.Right -

? PositionFormPx("fOuSuisJe").Bas <Enter> ? PositionFormPx("fOuSuisJe").Largeur <Enter> ? PositionFormPx("fOuSuisJe").Hauteur <Enter> Les nombres qui vont s'afficher dpendent de la rsolution de votre cran. Mon cran actuel a une rsolution de 1280 x 1024.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 22

J'obtiens respectivement : 189 227 378 340. Cela veut donc dire que, dans mon environnement : une distance horizontale de 1 pixel vaut 15 twips (2835 / 189 = 15 ; 5670 / 378 = 15) ; une distance verticale de 1 pixel vaut 15 twips (3405 / 227 = 15 ; 5100 /340 = 15). De par sa construction, le rapport twips/pixels est un nombre entier. Si la rsolution de votre cran est diffrente de celle que j'utilise (1280 x 1024), vous aurez peut-tre des rapports diffrents, voire mme avec des dcimales ! C'est d aux arrondis. Vous en comprendrez l'origine plus loin dans ce texte, lorsqu'on affectera des nombres premiers aux paramtres de DoCmd.MoveSize pour voir Nos zones de texte n'ont pas de source. Nous allons les ce que cela donne. garnir par programmation. 4.3. Comment dterminer la conversion Pixels => Twips Sauvegardons notre travail : <Ctrl-Key-S>.

Avec quelques API, on pourrait calculer les deux 5.2. Le code pour calculer le nombre de twips par pixel coefficients (horizontal et vertical) de conversion Pixels Comme dit plus haut, lors de l'ouverture du formulaire, vers Twips. nous allons calculer le nombre de twips par pixel horizontal en divisant sa largeur exprime en twips par sa C'est la solution que choisiront les virtuoses, entre autres largeur en pixels. les deux auteurs cits plus haut. Nous allons utiliser une mthode plus artisanale, cela nous permettra de mettre profit ce que nous savons dj faire : nous pouvons localiser un formulaire ouvert l'cran et trouver ses dimensions en nous exprimant en pixels, c'est notre fonction PositionFormPx ; d'autre part, depuis la version Access2000 un formulaire dispose de deux proprits WindowHeight (HauteurFentre) et WindowWidth (LargeurFentre) toutes deux exprimes en twips. Ds lors, si nous affichons notre formulaire et que dans la foule, nous rcuprons : sa largeur avec PositionFormPx(NomDuFormulaire).Largeur ; ainsi que sa hauteur avec PositionFormPx(NomDuFormulaire).Hauteur, toutes deux exprimes en pixels, nous disposerons ainsi de deux longueurs (une horizontale et une verticale) exprimes dans les deux units de mesure... et nous pourrons calculer leur rapport de conversion. Nous traduirons ceci en code dans le paragraphe suivant. 5. Un formulaire talon pour trouver les paramtres de doCmd.MoveSize Nous procderons de mme avec sa hauteur pour dterminer le nombre de twips par pixel vertical. Voici le code pour effectuer ces actions :
Me.ZdtNbreTwipspPixelHor = Me.WindowWidth / PositionFormPx(Me.Name).Largeur

En franais : on divise la largeur en twips par la largeur en pixels et on loge le rsultat dans le contrle ZdtNbreTwipspPixelHor. De mme :
Me.ZdtNbreTwipspPixelVer = Me.WindowHeight / PositionFormPx(Me.Name).Hauteur

On divise la hauteur en twips par la hauteur en pixels et on loge le rsultat dans le contrle ZdtNbreTwipspPixelVer. Nous allons dclencher l'excution de ce code dans l'vnement Sur ouverture de notre formulaire. Accdez au code actuel : - <Alt-key-F11> pour ouvrir l'diteur de code VBA ; - <Ctrl-key-R> pour afficher l'explorateur de projets ;

Nous allons utiliser tout ceci dans notre formulaire - double-cliquez sur Form_fOuSuisJe ; fOuSuisJe. Vous devriez avoir quelque chose comme ceci l'cran :Ds lors, si nous affichons notre formulaire et que Garnissons-le de quelques tiquettes et zones de texte. dans la foule, nous rcuprons : Pour rester cohrent avec la suite des explications, veuillez baptiser les zones de texte comme indiqu ci-aprs : 5.1. Les contrles du formulaire
Numro 37 Dcembre - Janvier 2011/2012 Page 23

Developpez Magazine est une publication de developpez.com

Me.zdtDroitePix = PositionFormPx(Me.Name).Droite Me.zdtBasPix = PositionFormPx(Me.Name).Bas

Et dans zdtDroiteTwi et zdtBasTwi la conversion en twips en multipliant les prcdents par leur coefficient multiplicateur : Remplacez le code actuel par celui-ci :
Option Compare Database Option Explicit Me.zdtDroiteTwi = Me.zdtDroitePix * Me.ZdtNbreTwipspPixelHor Me.zdtBasTwi = Me.zdtBasPix * Me.ZdtNbreTwipspPixelVer

Procdons par analogie, pour les largeur et hauteur :


Me.zdtLargeurTwi = Me.WindowWidth Me.zdtHauteurTwi = Me.WindowHeight Me.zdtLargeurPix = Me.zdtLargeurTwi / Me.ZdtNbreTwipspPixelHor Me.zdtHauteurPix = Me.zdtHauteurTwi / Me.ZdtNbreTwipspPixelVer

Private Sub Form_Open(Cancel As Integer) 'Calculer le Nbre de twips par Pixel 'Diviser la largeur en Twips (Me.WindowWidth) par la largeur en Pixels (PositionFormPx) Me.ZdtNbreTwipspPixelHor = Me.WindowWidth / PositionFormPx(Me.Name).Largeur 'Diviser la Hauteur en Twips (Me.WindowHeight) par la hauteur en Pixels (PositionFormPx) Me.ZdtNbreTwipspPixelVer = Me.WindowHeight / PositionFormPx(Me.Name).Hauteur End Sub

Pour la zone de texte zdtParam, il suffit de coller les morceaux : La commande


Me.zdtParam = "DoCmd.MoveSize " & Me.zdtDroiteTwi & " , " & Me.zdtBasTwi & " , " _ & Me.zdtLargeurTwi & " , " & Me.zdtHauteurTwi

Pour WindowWidth et WindowHeight, rappelez-vous

Refermez la fentre de l'diteur de code. Fermez le formulaire en le sauvegardant. Ouvrez-le nouveau et vous obtenez quelque chose comme ceci :

Et pour que l'utilisateur puisse rcuprer cette commande dans le presse-papier, on programme les oprations qu'il ferait manuellement : slectionner le texte et copier Commande dans le presse-papier
Me.zdtParam.SetFocus 'on slectionne tout le texte Me.zdtParam.SelStart = 0 Me.zdtParam.SelLength = Len(Me.zdtParam.Text) 'on copie dans le presse-papier DoCmd.RunCommand acCmdCopy 'quivalent du raccourci Ctrl-Key-C

5.4. Quand dclencher le processus ? L'ide est que le formulaire affiche ses donnes instantanment quelles que soient la position et les dimensions choisies par l'utilisateur qui le dplace et le redimensionne sa guise. Nous allons faire en sorte que le code se dclenche par exemple toutes les secondes. Affichons les vnement , proprits du formulaire , onglet

fixons 1000 (millisecondes) l'intervalle de minuterie et double-cliquons sur Sur minuterie : 5.3. Le code pour attribuer une valeur chaque zone de texte Compltons l'habillage des autres contrles. Mmorisons dans zdtDroitePix et zdtBasPix les coordonnes en pixels du coin suprieur gauche l'aide des valeurs de notre fonction PositionFormPx :
Numro 37 Dcembre - Janvier 2011/2012 Page 24

Developpez Magazine est une publication de developpez.com

Votre presse-papier contient donc la syntaxe de la commande. Un clic sur les ... pour ouvrir l'diteur de VBA, o Fermez fOuSuisJe. nous insrons notre code : vnement sur minuterie
Private Sub Form_Timer() 'La position du coin sup gauche Me.zdtDroitePix = PositionFormPx(Me.Name).Droite Me.zdtBasPix = PositionFormPx(Me.Name).Bas Me.zdtDroiteTwi = Me.zdtDroitePix * Me.ZdtNbreTwipspPixelHor Me.zdtBasTwi = Me.zdtBasPix * Me.ZdtNbreTwipspPixelVer 'La Largeur et la hauteur Me.zdtLargeurTwi = Me.WindowWidth Me.zdtHauteurTwi = Me.WindowHeight Me.zdtLargeurPix = Me.zdtLargeurTwi / Me.ZdtNbreTwipspPixelHor Me.zdtHauteurPix = Me.zdtHauteurTwi / Me.ZdtNbreTwipspPixelVer Me.zdtParam = "DoCmd.MoveSize " & Me.zdtDroiteTwi & " , " & Me.zdtBasTwi & " , " _ & Me.zdtLargeurTwi & " , " & Me.zdtHauteurTwi 'Commande dans le presse-papier Me.zdtParam.SetFocus 'on slectionne tout le texte Me.zdtParam.SelStart = 0 Me.zdtParam.SelLength = Len(Me.zdtParam.Text) 'on copie dans le presse-papier DoCmd.RunCommand acCmdCopy 'quivalent du raccourci Ctrl-Key-C End Sub

Dans un formulaire indpendant quelconque, dans l'vnement sur ouverture, collez le code qui se trouve dans votre presse-papier (<Ctrl-Key-V>). Ouvrez ce formulaire : il recouvre exactement la fentre des objets. Cqfd. 5.6. Si ce gadget vous intresse Vous pouvez l'importer dans votre base de donnes, par exemple comme ceci : vous affichez cte cte l'cran la base de donnes jointe et la vtre ;

Sauvegardez le formulaire par prcaution. Ouvrez-le, dplacez-le, redimensionnez-le : les donnes s'actualisent. 5.5. La preuve que a marche Faites l'exprience : dans PositionnerFormulaire.mdb vous mettez en surbrillance le module mAPI et avec le bouton gauche de la souris enfonc, vous faites glisser dans la fentre de Positionnez fOuSuisJe de manire telle qu'il recouvre votre application ; exactement la surface de la fentre des objets. vous procdez de mme pour mFonctions et fOuSuisJe... et c'est vous ! 6. Une dernire pour la route... Quand nous avons labor la fonction pour dterminer la conversion Pixels => Twips, j'avais attir votre attention
Numro 37 Dcembre - Janvier 2011/2012 Page 25

Developpez Magazine est une publication de developpez.com

sur le fait qu'Access ne positionne pas ncessairement de 15 les plus proches des paramtres originaux. exactement, droite et en bas, au nombre de twips mentionns dans la commande DoCmd.MoveSize. Chaque 7. Conclusion paramtre est arrondi au plus proche multiple de twips par Ceci est une premire tape. pixel. Un tutoriel suivra dans lequel on mettra en pratique la technique qui vient d'tre expose : positionner un formulaire par rapport un Dans l'vnement Sur ouverture , placez cette contrle d'un autre formulaire ; instruction en tte : rendre deux formulaires solidaires : le dplacement de l'un, entranant le dplacement de DoCmd.MoveSize 2887, 5167, 10267, 8269 l'autre. Quelle que soit la rsolution de votre cran, donc votre nombre de twips par pixel, vous constaterez que le Cela nous permettra d'voquer les proprits WindowLeft fOuSuisJe affich n'a aucun paramtre qui concide avec et WindowTop disponibles seulement partir de ceux de la commande. En effet, 2887, 5167, 10267 et 8269 Access2002 mais nous dcrirons un moyen de pallier leur sont des nombres premiers, ils ne sont donc pas des absence en Access2000. multiples de vos rapports twips/pixels. Vous pouvez tlcharger la base de donnes qui a servi titre d'exemple, avec ma rsolution 1280 x 1024, j'ai en d'exemple : Lien 70. ralit : 2880, 5160, 10260 et 8265 qui sont les multiples Retrouvez l'article de Claude Leloup en ligne : Lien 71. Vido Excel 2010: comparer des listes grce la mise en forme conditionnelle Notre fOUSuisJe nous permet de constater le phnomne.

Vido Excel 2010 : comparer des listes grce la mise en forme conditionnelle

Cette vido illustre la manire de signaler les lments d'une liste non prsents dans une autre. Au dpart d'une liste existante, je vous dtaille les tapes raliser pour crer un outil gnrique de comparaison bas sur une Mise en Forme Conditionnelle (MFC) personnalise.
1. Introduction 1.1. Objectifs rsoudre.

On pourrait donc, grce cet exercice, vrifier : la prsence ou l'absence de membres du personnel Cette vido formative poursuit les objectifs suivants : dans une liste de pointage ; illustrer l'utilisation des tableaux 2010 ; la prsence ou l'absence de certains types d'incidents dans une liste de non-conformits matriser la cration d'une mise en forme rencontres ; conditionnelle base sur le rsultat d'une formule ; ... mettre en lumire l'utilit d'une conception La "complexification" de la formule conditionnelle vous professionnelle d'un classeur Excel. permettra de rsoudre divers problmes lis la Ces objectifs seront approchs par la cration de deux comparaison de donnes au sein de listes de donnes. tableaux de donnes, l'un permettant la saisie de donnes dont on veut vrifier la prsence ou l'absence dans un Comme toujours, la bonne conception d'un classeur et l'utilisation d'outils adquats tels qu'illustrs dans la vido, deuxime tableau. tant pour la forme (affichage, multifentre) que le fond L'exemple utilis dans la vido montrera comment mettre (tableaux, formules, fonctions, mise en forme en vidence des articles qui n'ont pas t vendus durant conditionnelle) garantiront une prennit et une volutivit une certaine priode. L'on disposera donc d'une liste de des classeurs. ventes ralises et d'un tableau comparatif dans lequel seront reprises les rfrences d'articles. Les articles de 1.2. Prrequis cette liste qui n'ont pas t vendus seront affichs Matriser les rfrences absolues et relatives (utilisation automatiquement dans un format spcifique grce une du signe $ dans l'adressage d'une rfrence) est le mise en forme conditionnelle personnalise. minimum requis. L'utilisateur mal l'aise avec ces notions gagnera lire mon tutoriel sur le sujet : Lien 72. Dans la vido, j'ai choisi de mettre en vidence les articles non vendus, mais il suffira de modifier l'oprateur de Dans ce tutoriel, nous utiliserons une formule requrant la comparaison pour afficher les articles vendus, voire manipulation de fonctions Excel (ET() et NB.SI()). uniquement ceux qui ont t vendus un certain nombre de Comprendre la cration d'une formule et l'utilisation de fois, etc. fonctions basiques sera videmment utile l'exploitation de cette vido. C'est votre imagination et vos "besoins mtier" qui vous feront adapter l'exemple illustr aux cas que vous devrez
Numro 37 Dcembre - Janvier 2011/2012 Page 26

Developpez Magazine est une publication de developpez.com

1.3. Niveau

diffrents outils d'Excel (tableaux, formules, mise en forme conditionnelle) pour mettre en place rapidement des A priori, cette vido s'adresse des personnes ayant des classeurs prennes et professionnels. bases en Excel et voulant progresser. Une matrise globale de ce que peut faire Excel allie Les utilisateurs d'anciennes versions d'Excel (2003 et une conception rigoureuse de vos classeurs vous permettra antrieures) trouveront ici des ides d'utilisation des de raliser des outils performants aptes vous aider dans nouveaux outils disponibles depuis la version 2007. la gestion, et surtout l'analyse, des donnes avec Excel. 1.3.1. Dure Cette vido d'une dure de 14 minutes est dcoupe en huit chapitres techniques, vous donnant ainsi la possibilit de reprendre la vido sur une thmatique que vous souhaitez revoir. 2. La vido Lien 73. 3. Conclusions La vido illustre qu'il n'est gure compliqu de manipuler N'hsitez pas me faire part de vos remarques et suggestions, par rapport la problmatique pose en dbut de tutoriel. Si vous souhaitez un tutoriel vido sur un sujet prcis de l'utilisation d'Excel, vous pouvez bien entendu m'en faire part. Bon travail avec Excel ! Retrouvez l'article de Pierre Fauconnier en ligne : Lien 74.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 27

Business Intelligence
Les derniers tutoriels et articles
Import et export des fichiers Microsoft dans l'environnement SAS 9.2 sur Windows 64-bits Identification des problmes et solutions envisageables pour l'import et l'export des fichiers Microsoft Excel ou Access dans l'environnement SAS 9.2 sur Windows 64-bits.
1. Introduction Avec l'arrive des OS Windows 64-bits, de nombreux problmes d'importation et d'exportation de fichiers Office sont apparus sur SAS. En effet, lorsque l'on souhaite importer des fichiers Excel ou Access dans les environnements Windows 64-bits (Windows 2008 64-bits, Windows 2008 R2, Windows Vista 64 et Windows 2003 64-bit) ce message est susceptible d'apparatre lorsque l'on utilise un code dvelopp initialement sur les platesformes 32-bits : 2. Accs aux fichiers sur la plate-forme SAS 9.2 64-bits Dans cette premire partie, nous allons nous intresser aux deux modules d'accs aux donnes Office (Excel et Access) prsents dans SAS : le module SAS ACCESS TO PC FILES et le module SAS PC FILE SERVER. Tout d'abord, une prsentation du nouveau module SAS PC FILE SERVER sera donne. Les moteurs inclus dans ce module permettent de grer les accs aux donnes sur les plates-formes UNIX et Windows 64-bits. Import et export des fichiers Microsoft dans l'environnement SAS 9.2 sur Windows 64-bits

ERROR: DBMS type EXCEL (ACCESS) not valid for Ensuite, nous tudierons grce des exemples concrets le import. moteur de connexion des donnes Excel 2003 et 2007, puis sur le mme mode travail, nous prsenterons le Le problme est rcurrent, car la stratgie de la plupart des moteur de connexion des donnes Access 2003 et 2007. socits tant d'installer la version 64-bits de SAS sur des serveurs ou des PC, l'application n'est alors plus Les exemples dtaills de cette partie concerneront tout compatible avec le moteur de connexion DBMS=EXCEL aussi bien l'importation de donnes que l'exportation de qui est un moteur 32-bits. celles-ci, au travers des procdures et du LIBNAME. Si cette stratgie est conserve, il est ncessaire d'utiliser les moteurs de connexion 64-bits tels qu'ils sont dcrits dans les exemples ci-dessous et de connatre les incompatibilits entre les commandes SAS, les moteurs et les types de fichiers Office. Autrement, il est possible d'installer la version 32-bits de SAS sur la plate-forme 64bits et d'utiliser les connecteurs habituels. Ce dossier technique prsente les diffrents changements qui doivent tre pris en compte pour importer et exporter les fichiers Office. Il a t prpar partir du retour d'exprience des missions de conseil ralis par l'auteur chez ses clients et des discussions avec certains experts chez l'diteur et le support. Bien entendu, l'auteur prsente par avance ses excuses si d'autres cas rels n'ont pas t apprhends dans ce dossier alors qu'ils auraient pu aider le lecteur. Les donnes utilises n'ont rien de spcifique ce dossier. L'ensemble des tests a t ralis grce aux tables de la bibliothque SASHELP. Ainsi, les donnes de la table SASHELP.CLASS ont t copies dans un fichier Excel 2003 (nomm D_Excel_2003.xls) puis 2007 (nomm D_Excel_2007.xlsx) et ensuite dans un fichier Access 2003 (nomm D_Access_2003.mdb) et 2007 (nomm D_Access_2007.accdb). 2.1. La nouvelle solution SAS PC FILE SERVER PC FILE SERVER est une application qui gre les requtes de lecture et d'criture de fichiers Office. Elle est fournie en standard pour des plates-formes UNIX et Windows 64-bits dans les dpts SAS.

Elle propose deux moteurs de connexion, EXCELCS et ACCESSCS, permettant de rpondre des besoins prcis que nous verrons plus loin. Installe en tant que service La premire partie de cet article prsente les possibilits partir des plans dans le dpt SAS, elle utilise le Microsoft d'accs aux fichiers en utilisant le client traditionnel de Access Connectivity Engine et les drivers ODBC version SAS sur la plate-forme SAS 9.2 64-bits. 12 pour Microsoft Excel et Microsoft Access. La seconde partie dtaille les erreurs courantes rencontres Par extension, cette application permet d'accder lors de l'utilisation des nouvelles syntaxes fournies galement des SGBD ayant des connecteurs ODBC, dtailles auparavant. mais ce point ne sera pas abord dans cet article. La dernire partie donne des solutions pour stabiliser le systme d'change entre SAS et Office et prsente la faon 2.2. Les moteurs de connexion envisageables dont SAS Enterprise Guide gre l'import et l'export de Avec l'ajout de cette solution, il est possible de grer les donnes. diffrentes versions des fichiers Office sur la plate-forme 64-bits de Windows avec diffrents moteurs : la source de donnes MS-Excel amne
Numro 37 Dcembre - Janvier 2011/2012 Page 28

Developpez Magazine est une publication de developpez.com

l'utilisation des moteurs SAS suivants : XLS , EXCELCS , PCFILES ; la source de donnes MS-Access amne l'utilisation des moteurs SAS suivants : ACCESSCS , PCFILES .

Mais pourquoi avoir autant de moteurs ? Se valent-ils en performance ? Ce dossier amnera les rponses ces questions. 2.3. Connexion avec le logiciel Excel

fichier Excel ; SHEET : option permettant de spcifier une feuille particulire du classeur Excel, tant pour l'import que pour l'export ; MSENGINE : option permettant de changer le moteur de connexion fourni par Windows ; REPLACE : option ncessaire pour remplacer le fichier en sortie d'une procdure.

Ensuite, l'tape LIBNAME sera utilise pour illustrer ce type de connexion.

Sur une plate-forme 64-bits, il existe trois moteurs de 2.3.1. Utilisation de la PROC IMPORT connexion qui possdent leurs propres contraintes. Voir tableau en ligne : Lien 75 Le moteur XLS Ne peut pas communiquer avec les fichiers 2.3.2. Utilisation du LIBNAME Microsoft Office 2007 files (XLSX, XLSM, et Voir tableau en ligne : Lien 76 XLSB). Ne peut pas tre utilis avec un LIBNAME. Il ne peut tre utilis qu'au sein des PROC IMPORT et 2.3.3. Utilisation de la PROC EXPORT EXPORT. Les rsultats de ces excutions valent pour la cration d'un Reste le moteur le plus stable pour tout autre type fichier ou pour l'ajout d'un onglet dans un classeur de fichiers (i.e. hormis Excel 2007). existant. Le moteur EXCELCS Peut communiquer avec les fichiers Microsoft Office 2007 files (XLSX, XLSM, et XLSB). Ne peut pas tre utilis avec un LIBNAME. Il ne peut tre utilis qu'au sein des PROC IMPORT et EXPORT. Ne renomme pas les colonnes ayant des caractres spciaux (il remplace ces caractres par des soulignements alors que le moteur XLS renomme compltement la variable en VARn). Peut crer des fichiers Excel 2007. Toutefois, s'il s'agit de crer un fichier au format Excel 2007 plutt que de mettre jour un fichier existant, il faut lui donner une extension XLSB (B pour Binaire). noter galement, lorsque l'export doit craser un fichier existant, un backup est cr sous la forme d'un fichier ayant une extension .bak aprs l'extension .xls (par exemple : monfichier.xls.bak) Voir tableau en ligne : Lien 77 2.4. Connexion avec le logiciel Access Sur une plate-forme 64-bits, il est obligatoire d'utiliser le moteur ACCESSCS pour grer les accs dans les procdures (PROC). Les affectations de bibliothques (LIBNAME) utiliseront le moteur PCFILES.

Le moteur ACCESSCS : peut lire les fichiers Microsoft Office 2007 (ACCDB) ; Le moteur PCFILES ne peut pas tre utilis avec un LIBNAME. Il ne Peut communiquer avec les fichiers Microsoft peut tre utilis qu'au sein des PROC IMPORT et Office 2007 (XLSX, XLSM, et XLSB). EXPORT ; Doit tre utilis avec un LIBNAME. Il ne peut gre correctement les noms de colonnes ayant pas tre utilis au sein des PROC IMPORT et plusieurs caractres spciaux. EXPORT. L'utilisation de PCFILES est base sur les Le moteur PCFILES : moteurs (engine) Microsoft : Microsoft Jet peut lire les fichiers Microsoft Office 2007 Engine et Microsoft ACE engine. Par dfaut le (ACCDB) ; LIBNAME utilise MSENGINE= ACE. doit tre utilis avec un LIBNAME. Il ne peut pas Nous allons dtailler ci-dessous quelques exemples d'importation et d'exportation des donnes Excel 2003 (*.xls) et 2007 (*.xlsx) en utilisant SAS 9.2 64-bits. Nous allons comparer les rsultats des moteurs du module SAS PC FILE SERVER avec les moteurs du module ACCESS to PC FILES (classiquement utilis dans les versions 32bits de SAS). tre utilis au sein des PROC IMPORT et EXPORT ; l'utilisation de PCFILES est base sur les moteurs (engine) Microsoft : Microsoft Jet Engine et Microsoft ACE engine. Par dfaut le LIBNAME utilise MSENGINE= ACE.

Nous allons dtailler ci-dessous quelques exemples d'importation et d'exportation des donnes Access 2003 Pour cela, les procdures IMPORT et EXPORT seront (*.mdb) et 2007 (*.accdb) en utilisant SAS 9.2 64-bits. prsentes avec quelques options spcifiques, savoir : Nous allons comparer les rsultats des moteurs du module GETNAMES : option permettant de rcuprer les SAS PC FILE SERVER avec le moteur du module noms de colonnes dans la premire ligne du ACCESS to PC FILES (classiquement utilis dans les
Numro 37 Dcembre - Janvier 2011/2012 Page 29

Developpez Magazine est une publication de developpez.com

versions 32-bits de SAS).

ERROR: Export unsuccessful. details

See SAS Log for

Pour cela, les procdures IMPORT et EXPORT seront Solution : comme le montre l'exemple de code suivant, il prsentes avec quelques options spcifiques, savoir : SHEET : option permettant de spcifier une faut crer avant la PROC EXPORT un LIBNAME sur le feuille particulire du classeur Excel, tant pour fichier de destination qui pourtant n'existe pas encore. l'import que pour l'export ; REPLACE : option ncessaire pour remplacer le fichier en sortie d'une procdure. Ensuite, l'tape LIBNAME sera utilise pour illustrer ce type de connexion. 2.4.1. Utilisation de la PROC IMPORT Pour importer une table de la base Access, 2003 ou 2007, il convient d'utiliser uniquement le moteur ACCESSCS. Voir tableau en ligne : Lien 78. 2.4.2. Utilisation du LIBNAME 3.1.2. Erreur sur les LIBNAME

Problme : lors de l'utilisation d'un LIBNAME, ici La seule faon de crer un LIBNAME sur une base Access xls_obj, il arrive que la connexion n'ait pas le temps de s'initialiser correctement. reste la solution employant le moteur PCFILES. Voir tableau en ligne : Lien 79. 2.4.3. Utilisation de la PROC EXPORT Les tests confirment qu'un seul moteur est exploitable sur cette plate-forme. Le moteur habituel "Access" ne fonctionne plus. Voir tableau en ligne : Lien 80. 3. Erreurs couramment rencontres avec le module PCFILE SERVER sas
data EXTRACTION (drop=CENTRE CODE_CENTREPRODUIT 2011-04-01T07:45:23,871 INFO [00000015] - 612! rename=(centre2=centre id_centre=CODE_CENTRE PRODUIT2=PRODUIT )); 2011-04-01T07:45:23,871 INFO [00000015] - 613 set xls_obj.OBJECTIFS_RM; ERROR: CLI prepare error: Server communication failure. The client log file (PCFILES.log) may contain additional information.

Solution : lorsqu'il s'agit d'accder des fichiers Excel Ce chapitre prsente les erreurs rencontres au fil du temps 2000-2003, il est prfrable d'utiliser l'option dans l'usage de ces connecteurs sur la plate-forme 64-bits. MSENGINE= JET afin de minimiser ce genre d'erreur. Ces erreurs sont non imputables au code SAS mais plutt LIBNAME xls_obj PCFILES path= la stabilit du systme et des composants SAS. "\ref\OBJECTIFS_RM.xls" MSENGINE= JET ; 3.1. Mauvaise initialisation du service PCFILE SERVER 3.1.1. Erreur sur les procdures L'utilisation de PCFILES est base sur les moteurs Microsoft : Microsoft Jet Engine et Microsoft ACE Engine. Par dfaut le LIBNAME utilise MSENGINE= ACE.

Problme : Il arrive que la connexion n'ait pas le temps de 3.2. Impossibilit d'atteindre un fichier sur le rseau s'initialiser correctement, notamment lors des PROC Problme : l'erreur suivante provient encore de EXPORT. l'interaction de PC FILE SERVER avec le systme.
1 PROC EXPORT OUTFILE='d:\xlsair.xls' DATA=sashelp.air 2 DBMS=Excelcs REPLACE; 3 run; ERROR: Error attempting to CREATE a DBMS table. ERROR: CLI execute error: Server communication failure. The client log file (PCFILES.log) may contain additional information.. ERROR: CLI disconnect failed: Server communication failure. The client log file (PCFILES.log) may contain additional information. ERROR: CLI disconnect failed: Server communication failure. The client log file (PCsFILES.log) may contain additional information. ERROR: Error in the LIBNAME statement. Libname xl2007 PCFILES "SasData\D_Excel_2007.xlsx"; ERROR: CLI error trying to establish connection: [Microsoft] [ODBC Excel Driver] '(unknown)' is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on which the file resides. ERROR: Error in the LIBNAME statement. Connection Failed. See log for details.

Solution : lorsque le fichier importer ou exporter se trouve sur un lecteur rseau (i.e. en dehors des lecteurs physiquement rattachs la machine, soit dans 95 % des
Numro 37 Dcembre - Janvier 2011/2012 Page 30

Developpez Magazine est une publication de developpez.com

cas maintenant) il arrive que PC FILE SERVER en tant apparatre lors de l'utilisation de celle-ci. que service Windows n'ait pas pu reconnatre le mappage rseau (ce dernier tant dclar aprs le dmarrage des Pour viter tout problme de stabilit entre SAS et Excel services). 2007, il vaut mieux utiliser la version 12.0.4518. Autrement, les utilisateurs qui vont ouvrir des fichiers Dans ce cas, il faut spcifier le nom universel du chemin Excel depuis le serveur (lorsque les utilisateurs travaillent du fichier, soit redmarrer le service aprs que le mappage directement sur le serveur depuis MSTSC par exemple), rseau a t ralis. risqueront de visualiser un fichier avec de nombreuses donnes manquantes alors que ce mme fichier peut tre Le nom universel (UNC, Universal Naming Convention en ouvert sur leur poste (XP 32-bits) sans problme. anglais) est le nom du rpertoire compos de la faon suivante : 4.3. Installer les drivers spcifiques Microsoft Access \\nom_du_serveur\Nom_du_repertoire\D_Excel_2007.xlsx Database Engine 2010 Ces drivers semblent plus stables pour les changes. Indpendamment du niveau de maintenance de SAS 9.2 Cette erreur est susceptible d'apparatre lorsque de (M1, M2, M3). nombreuses PROC EXPORT sont gnres par une boucle MACRO (%do %end). Le systme ne semble plus suivre http://www.microsoft.com/download/en/details.aspx? et refuse d'accder aux fichiers. displaylang=en&id=13255 3.3. Impossibilit de remplacer un fichier existant Dans ce cas, plutt que de laisser SAS tenter de remplacer 4.4. Donner les pleins droits aux utilisateurs sur une le fichier cible, il est prfrable de le supprimer soi-mme. clef de registre La mthode la plus simple tant de passer la commande Afin d'viter certaines erreurs du service PC FILE SAS suivante juste avant la PROC EXPORT. SERVER, il est parfois ncessaire de modifier les droits sur Dans l'exemple, elle permet de supprimer physiquement le HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Nod fichier nomm mybook.xls : e\ODBC en donnant les pleins droits au groupe SAS. Dans l'exemple ci-dessous le groupe SAS se nomme data _null_; LogAsBatch et hrite des pleins droits sur la clef ODBC. fname="fictmp";
rc=filename(fname,"D:\temp\mybook.xls"); if rc=0 and fexist(fname) then rc=fdelete(fname); rc=filename(fname); run;

Note : il peut arriver dans certains cas que le fichier ne puisse mme plus tre supprim. L'exprience a montr que l'utilisateur SYSTEM se retrouvait propritaire du fichier et ne pouvait rendre les droits au propritaire originel : si l'tape DATA prsente ci-avant est excute par l'utilisateur, elle ne peut fonctionner car il ne sera plus le propritaire du fichier. 4.5. Utiliser SAS Enterprise Guide Il faut alors redmarrer le service PC FILE SERVER et se connecter en tant qu'administrateur pour librer les La version SAS Enterprise Guide (EG) 4.1 possde quelques bogues : le plus connu tant le blocage des futurs fichiers. Ce cas est fort heureusement peu courant. imports d'un fichier sur le nombre d'observations issu du 4. Les solutions apporter pour stabiliser ou russir ses premier import. Par exemple, si le fichier a t import l'instant avec vingt lignes, une seconde importation n'en changes entre SAS et les produits Office importera pas plus mme si le fichier Excel a t modifi entre-temps (cf. Lien 82). 4.1. Installer une version rcente de SAS 9.2 Installer SAS 9.2 Maintenance 3 permet de profiter des derniers correctifs. Cette version a t largement amliore au niveau de la stabilit et supporte la plupart des platesformes 64-bits. Nanmoins, si l'on se focalise sur la version EG 4.2 et 4.3, il arrive trs souvent que l'utilisateur de SAS Enterprise Guide (EG) constate un meilleur fonctionnement dans ces imports/exports qu'avec le client traditionnel.

SAS 9.3 M0 n'a pas chang la gestion des drivers Excel, ce la diffrence du client traditionnel, SAS Enterprise Guide n'utilise pas le module SAS ACCESS TO PC ne peut tre la raison de migrer malheureusement. FILES. SAS EG ralise ces importations et exportations en deux temps. Dans un premier temps, il utilise un 4.2. Installer une version d'Excel compatible composant Windows pour transformer les fichiers Excel La dernire version mise jour par MS Office pour Excel ou Access en un fichier texte stock dans un espace 2007 est la version 12.0.6557, le support SAS liste dans temporaire (dans l'image illustrant cette action, le cette note : Lien 81, quelques problmes pouvant encore rpertoire est C:\Users\datametric\AppData\Local\Temp\
Numro 37 Dcembre - Janvier 2011/2012 Page 31

Developpez Magazine est une publication de developpez.com

SEG4020).

5. Conclusion Afin d'utiliser les procdures d'import et d'export de SAS 9.2 sur une plate-forme 64-bits, il est ncessaire de connatre les diffrents moteurs de connexion ainsi que leurs impacts sur les fichiers de rsultat. Les exemples fournis plus haut permettent de se faire une ide des erreurs qui peuvent tre gnres et des options utilisables ou non. Dans le cas d'une migration d'une plate-forme Windows 32-bits 64-bits, les programmes devront tre modifis sur ces points, mme si l'ensemble parat s'intgrer dans une migration isoprimtre.

Dans un second temps, l'assistant d'importation cre une tape DATA pour rcuprer le rsultat. L'image montre Ce tableau synthtise les possibilits d'utilisation des moteurs de connexion selon la source et l'utilisation d'une bien que SAS cre une tape DATA base sur l'INFILE. Procdure ou d'un LIBNAME. Pour les fichiers Excel 2003 Nom du moteur Excel LIBNAME Non xls Non ExcelCS Non Oui Oui PCFILES Oui Non Non

Proc IMPORT Non Oui Il faut donc conclure que la tche d'import de SAS visible Proc EXPORT Non Oui dans le projet n'est donc que la phase finale du processus d'importation. Il en va de mme pour la tche Pour les fichiers Excel 2007 d'exportation, l'outil va utiliser une API pour crer les fichiers au format XLS et MDB. Nom du moteur Excel xls

ExcelCS

PCFILES

Non Non Non Oui En ce qui concerne les exports au format XLSX, EG 4.3 LIBNAME n'a pas la possibilit d'exporter nativement dans ce format. Proc IMPORT Non Non Oui Non Il faut utiliser cette tche personnalise mise disposition Proc EXPORT Non Oui Oui/ Non Non par SAS : Pour les fichiers Access (2003 et 2007 ) http://support.sas.com/documentation/onlinedoc/g uide/customtasks/samples/SAS.Tasks.ExcelExpor Nom du moteur Access AccessCS PCFILES t.zip LIBNAME Non Non Oui Une fois de plus, cet outil n'utilise pas le module SAS Proc IMPORT Non Oui Non mais les composants Windows. Proc EXPORT Non Oui Non Sachez que SAS Enterprise Guide pourrait utiliser ce module et donc gnrer des PROC IMPORT et EXPORT Par exprience, la PROC IMPORT doit tre utilise avec rexploitables. Cependant, les conditions d'utilisation sont DBMS=XLS plutt que EXCELCS qui exploite un service strictes et le code gnr utilisera le moteur de connexion spcifique sur Windows et apparat l'usage plus lent. DBMS=EXCEL ou ACCESS. Indpendamment de SAS, il est ncessaire d'utiliser les Les conditions sont les suivantes : drivers Office de dernire gnration tout en sachant que le fichier Excel doit tre stock l o se trouve le SAS ne sait pas grer les toutes dernires versions. Il n'est moteur d'excution (si SAS est excut en local donc pas vain de suivre les mises jour et les notes alors le fichier doit tre en local ou sur un techniques ce sujet. rpertoire visible depuis l'explorateur Windows) ; si le moteur DBMS=EXCEL ou ACCESS n'est Cet article nous a montr que les changes entre SAS et pas valide (comme sur les plates-formes 64-bits), Excel/Access prsentent de srieux problmes. Pour y remdier, il est envisageable de crer une base SQL Server l'outil ne permettra pas d'activer cette option. qui supporterait la fonction de stockage des donnes. En L'image suivante montre que l'assistant dsactive l'option effet SAS et Excel/Access communiquent trs bien avec ce systme de base de donnes ; SAS utilise un connecteur sur une plate-forme 64-bits. ODBC pour communiquer avec ce systme de base de donnes. On pourrait alors imaginer qu'Excel serve d'interface de saisie pour des donnes qui iraient dans les tables SQL. Ainsi SAS pourrait charger les donnes par la suite pour
Numro 37 Dcembre - Janvier 2011/2012 Page 32

Developpez Magazine est une publication de developpez.com

les traitements utilisateurs. Ce genre de projet parat surdimensionn pour de simples bases mais les utilisateurs rencontreront une meilleure stabilit dans leur Procdure et profiteront des avantages d'une base SQL Server. 6. Liens Wikipedia : Lien 83. Support SAS : Lien 84. Lien 85. Lien 86. Lien 87. Lien 88. Lien 89. Lien 90. Lien 91. Lien 92. Lien 93. Retrouvez l'article de Stphane Colas en ligne : Lien 94.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 33

Qt
Les dernires news Sortie de PySide 1.1.0
La dernire version en date de PySide, la 1.1.0, vient de sortir. Il s'agit plus d'une version de maintenance que d'une version majeure, aprs la 1.0.9. Le seul changement principal concerne le systme de types, qui adopte une nouvelle manire de fonctionner, sans oublier les nombreuses corrections de bogues, qui assurent maintenant une bonne compatibilit avec Python 3.2, dont le support a t ajout la 1.0.8, de faon assez erratique sur certaines plateformes. Qt 4.8 n'est toujours pas support, bien que sorti le mois dernier (Lien 95). Pour ceux qui dsireraient installer cette nouvelle version, les instructions de l'article Installation de PySide : compilation et binaires (Lien 96) devraient toujours tre valables pour Python 2 ; pour Python 3, il faut configurer Shiboken d'une manire diffrente :
mkdir build cd build cmake .. -DUSE_PYTHON3=ON make sudo make install sudo ldconfig

Gits et Digia.

Toutes les informations jour en anglais sont disponibles sur le Qt Developer Network : Lien 97. Point important noter pour cette version : c'est la premire sortir sans le soutien financier de Nokia (Lien 98) (partiellement, cependant, vu qu'il devait s'arrter fin 2011), cela ne semble pas avoir eu trop d'impact sur le dveloppement, si ce n'est le peu de nouveauts pour cette version - qu'en sera-t-il pour les suivantes ? Commentez la news de Thibaut Cuvelier en ligne : Lien 99.

Les sessions d'entrainements sont les suivantes. Bien commencer avec Qt (e-Gits) : introduction rapide et pratique de Qt bas sur l'utilisation de Qt Core et des QWidgets. Qt avanc, un plongeon en profondeur (KDAB) : prsentation des fondations de Qt les plus importantes savoir la Vue Graphique (Graphics View), le multithread et la Vue/Modle (Model/View). Programmation avec Qt Quick (basysKom) : dcouverte de la programmation avec Qt Quick et du langage QML. Raliser des interfaces graphiques avec Qt Quick (KDAB) : session plus axe sur le ct design des applications Qt Quick. Qt apps avec Nokia - Designer, Dvelopper, Distribuer (Digia, Nokia) : une mise en bouche du dveloppement de app sur tlphone portable Nokia, du design la distribution. En parallle et chaque pause, les participants pourront se promener travers les expositions proposes par Nokia et ses sponsors (cf. photos attaches).

Reportage en direct, les Qt Dev Days 2011 Munich


Lundi 24 octobre 2011 Aujourd'hui, lundi 24 octobre 2011, c'est l'ouverture des Qt Dev Days 2011 Munich, l'vnement de tous les dveloppeurs Qt en Europe.

9 h 00 ce matin, des centaines de personnes sont arrives au Dolce Munich htel pour l'inscription et la journe des "trainings" qui va avoir lieu aujourd'hui (cf. la suite de ces prsentations, une rception organise par photos attaches). Digia permettra aux dveloppeurs de se rencontrer et galement de partager avec l'quipe de Qt (Trolls), 10 h 00, cinq salles vont tre remplies par des impatiente de rpondre aux questions des participants dveloppeurs Qt assistant aux entrainements raliss par l'vnement. les partenaires de Nokia, savoir KDAB, basysKom, eNumro 37 Dcembre - Janvier 2011/2012 Page 34

Developpez Magazine est une publication de developpez.com

Lars knoll parle de l'Open Gouvernance Lars Knoll (Chief Architecte Qt) volution de Qt Comme vous l'avez srement dcouvert, le projet Qt passe en Open Gouvernance (Lien 100). Lars Knoll a apport des informations sur ce nouveau modle de dveloppement. Notamment, il dcrit les quatre points suivants, au centre du projet : - l'quitabilit ; - la transparence ; - le fait de pouvoir participer ; - la mritocratie.

Mais ce n'est pas parce que cette orientation existe que les dveloppeurs bureau sont abandonns. En effet, les QWidget sont toujours d'actualit. Ainsi, comme on a dj pu le voir avec les dernires versions de Qt, deux faons sont possibles pour dvelopper une application : - la voie habituelle en C++ ; - la voie nouvelle en QML.

Lars Knoll a aussi dcrit les nouveauts / changements dans Qt 5 : - Qt 5 sera modulaire ; - un tat de l'art des interfaces utilisateur (toujours plus fluides / plus animes) ; - fonctionne entirement dans l'cosystme ; - compatible Qt 4.x ; - Qt Quick 2.0 ; - une toute nouvelle pile graphique ; Il a mme rpt plusieurs fois que, si un code n'est pas - une nouvelle structure ; visible, c'est qu'il n'existe pas au sein du projet (principe - un meilleur support des plateformes. de transparence). En bref : Les bnfices prsents sont : - dans Qt 5, on ne parlera plus de Qt Mobility ; - une stabilit accrue (car plus de dveloppeurs peuvent - les widgets sont vus comme add-ons (car les applications corriger le code et le tester) ; mobiles peuvent ne pas en avoir besoin). - des versions plus riches (plus de gens pourront apporter du contenu) ; Pour le rendu, un nouveau paradigme a t mis en place, il - une visibilit accrue ; est possible d'utiliser un rasteriser logiciel, en place avec le - que Qt corresponde plus vos besoins (et, s'il ne le fait systme QPainter, ou alors d'utiliser Qt Quick 2.0 pas, vous pouvez toujours proposer / dvelopper vos entirement construit et optimis pour OpenGL ES. morceaux de code) ; - de meilleures opportunits pour les experts Qt. Il a t dit que mme le rasteriser logiciel obtient de bonnes performances. Le systme fonctionne suivant la hirarchie suivante propos de cela et en lien avec l'Open Gouvernance, le (hirarchie pyramidale): groupe DirectFB a dj publi du code sur le projet Qt. - tout en haut, on retrouve le mainteneur en chef (au moins un par module de Qt) ; - les mainteneurs ; - les approbateurs (qui regardent le code soumis et qui l'acceptent) ; - les contributeurs (rapport de bogues / patches). Finalement, M. Knoll a donn les premiers chiffres de ce systme. Entre vendredi et aujourd'hui (mardi), il y a eu : - 270 nouveaux comptes ; - 53 contributions ; - 33 patches accepts. Cela prouve que le systme est dj en marche. Le futur de Qt Le portage d'application Qt 4 sera facile et compos des points suivants : - excution d'un script pour les en-ttes ; - suppression de #include <QMimeData> ; - peu d'incompatibilits. Il a insist sur le fait que les applications Qt 4 seront compatibles ( part quelques exceptions) avec Qt 5. Nokia cherche viter les problmes qu'ils ont eus auparavant, lors du passage de Qt 3 Qt 4. De plus, M. Knoll a annonc que Nokia ferait mettre disposition deux versions de Qt par an, suivant la rapidit des versions que l'on retrouve chez Ubuntu ou encore Firefox.

Le planning actuel pour Qt 5 est : Tout d'abord, parlons un peu de Qt 4.8, qui va bientt tre - arrt d'intgration des fonctionnalits, dbut 2012 (rien disponible. Qt 4.8 apporte : de nouveau n'est ajout, il n'y aura que de la rsolution de - Qt Quick 1.1 ; bogues partir de cette date) ; - meilleures performances ; - version bta durant le printemps 2012 (mars / avril) ; - support de HTML5 dans QWebkit ; - version finale dans la premire moiti de l'anne 2012. - facilit du portage sur de nouvelles plateformes. Pour finir, Lars Knoll a dcrit les possibles Rapidement, M. Knoll a abord le sujet de Qt 5. Avec Qt dveloppements futurs pour Qt : 5, une nouvelle structure du code a t mise en place. De - un support complet de Qt Quick pour les plateformes de plus, cette version de Qt 5 s'oriente sur le dveloppement bureau ; d'applications utilisant des interfaces utilisateur fluides et - une intgration d'un rendu logiciel OpenGL (avec rpondant au toucher. MESA : Lien 101) ; - QWebkit 2 ;
Numro 37 Dcembre - Janvier 2011/2012 Page 35

Developpez Magazine est une publication de developpez.com

- un support du JavaScript tendu sur plus d'architecture de processeurs. Lundi 24 octobre 2011 Nous voici aujourd'hui la seconde journe de la huitime dition des Qt Dev Days 2011 Munich, avec une matine rythme par les traditionnelles "keynotes". La premire prsentation ralise par Marco Argenti (SVP Nokia Developer Experience) a donn une ide de la stratgie de Nokia autour de Qt. Aujourd'hui, 100 millions de smartphones actifs avec Qt install sont sur le march, cela reprsente un nombre de tlchargements de 9 millions d'applications par jour. Le N9, rcemment sorti, est de loin le meilleur tlphone jamais ralis pour les dveloppeurs. Qt est devenu trs populaire au cours des dernires annes et reste un investissement stratgique pour Nokia en concordance avec le Qt Project. Nokia utilise dailleurs Qt pour ses propres outils internes notamment le logiciel Nokia Store.

socit aujourd'hui ; comment les tlphones portables changent CNN ; comment les innovations nous aident suivre le rythme.

Pour terminer cette matine, Lars Knoll (Chief Maintener du Qt Project) a prsent Qt 4.8, Qt 5 et l'Open Gourvenance via Qt Project dmarr vendredi dernier (21 octobre 2011), la partie probablement la plus attendue par l'ensemble des dveloppeurs prsents pour savoir o va Qt dans l'avenir proche comme dans l'anne future.

Le Qt Project tant maintenant en ligne (Lien 103), les Pour plus d'information sur la keynote, retrouvez les dveloppeurs Qt (communaut et commercial) peuvent commentaires de Vincent Meyer sur place : Lien 102. participer directement Qt de diffrentes faons (code source, rapport de bogues, tests, etc.). Tout l'cosystme de Qt fait partie du projet savoir, les outils, Qt 4 et Qt 5, etc. Plus de personnes contribuant Qt permet d'avoir au final plus de testeurs pour l'ensemble du code ce qui va amliorer la qualit du Framework dans son ensemble. Qt 4.8 va sortir d'ici la fin de l'anne avec Qt Quick 1.1, de meilleures performances, des nouvelles fonctionnalits HTML5 et un portage plus facile sur diffrentes plateformes. La seconde keynote prsente par Rick Spencer (Director of Engineering chez Canonical) a permis d'avoir une vue sur un autre projet, Open Source depuis quelques annes, savoir : Ubuntu. Il s'est agi principalement d'une prsentation de Ubuntu, de son fonctionnement Open Source et d'informations sur l'utilisation de Qt par Ubuntu. Le nouveau systme de fentrage fourni avec Ubuntu par dfaut utilise Qt Quick (QML) dans sa version 2D pour netbooks. Cela a l'avantage de fournir par dfaut toutes les bibliothques ncessaires au bon fonctionnement d'applications Qt. Ubuntu est probablement la distribution Linux la plus utilise avec un nombre d'utilisateurs approximatif de 20 millions. Pour plus d'informations sur la keynote, retrouvez les commentaires de Vincent Meyer sur place : Lien 102. Qt 5 sera disponible dans la premire moiti de 2012 avec une compatibilit Qt 4.x malgr la restructuration modulaire. Qt Quick 2.0 avec OpenGL ES fera partie de Qt 5 ainsi que l'intgration complte de Qt Mobility. Une sparation nette entre Qt Essentials et Qt Add-ons sera cependant faite vous permettant d'emporter avec votre application seulement ce dont vous avez besoin. Pour plus d'information sur la keynote, retrouvez les commentaires de Alexandre Laurent sur place : Lien 104.

Une troisime session par Louis Gump (Vice-Prsident CNN Mobile) sur l'application CNN pour tlphone portable Nokia tait trs enrichissante. La discussion tait dcoupe en trois parties : comment les tlphones portables changent notre

Une interview avec Lars Knoll la suite de sa keynote a permis d'obtenir les informations suivantes : il n'y aura pas de compatibilit binaire mais une compatibilit du code source entre les deux branches majeures, Qt 4.x et Qt 5, avec quelques exceptions mineures ; Qt Network sera un module spar et non inclus dans Qt Core, comme suggr au Contributor Summit en juin dernier ;
Numro 37 Dcembre - Janvier 2011/2012 Page 36

Developpez Magazine est une publication de developpez.com

Les dernier tutoriels et articles

simplement repousse une version mineure la structure de l'Open Gourvernance, compose ultrieure, permettant de respecter le cycle de de Maintainers et Approvers, sera pour deux nouvelles versions par an ; commencer principalement compose de personnes de Nokia avec quelques personnes la structure actuelle de release savoir Technical d'autres entreprises telles que Thiago Macieira Preview, Beta, Release Candidate, etc. sera (Intel) ; utilise pour le moment mais, en cas de ncessit ventuelle, change pour une plus adapte. les deadlines seront respectes dans le sens o, si une fonctionnalit n'est pas prte pour une date prcise, au lieu de retarder tout le monde en Commentez la news de Jonathan Courtois et Alexandre attendant qu'elle soit prte, elle sera tout Laurent en ligne : Lien 105. Le livre blanc Qt (suite de la parution du numro prcdent)

Le livre blanc Qt (suite de la parution du numro prcdent) Ce livre blanc dcrit le framework C++ Qt. Qt aide au dveloppement d'interfaces graphiques multiplateformes avec son approche crit une fois, compil n'importe o . Utilisant une seule arborescence de source et une simple recompilation, les applications peuvent tre excutes sous Windows, Mac OS X, Linux, Solaris, HP-UX et bien d'autres versions d'Unix avec X11. Les applications Qt peuvent galement tre compiles pour s'excuter sur des plateformes embarques comme Linux embarqu, Symbian ou Windows CE. Qt fournit un excellent support multiplateforme pour le multimdia et les reprsentations 3D, l'internationalisation, SQL, XML et les tests unitaires, tout en proposant des extensions spcifiques aux plateformes pour les applications spcialises.
6. Graphique et multimdia Qt fournit un excellent support pour les graphismes en 2D et 3D. Les classes 2D de Qt supportent les graphismes vectoriel et matriciel, peuvent charger et enregistrer une large gamme extensible de formats d'image et exporter du texte et des graphismes dans des fichiers PDF. Qt peut dessiner du texte riche Unicode transform, des documents SVG (Scalable Vector Graphics) et fournit un canevas pleinement fonctionnel pour des applications interactives plus pousses. Qt fournit aussi des fonctionnalits pour lire des fichiers et des flux audio et vido. Les applications graphiques qui requirent un canevas interactif peuvent tirer profit du framework de la vue graphique (graphics view) pour grer et rendre les scnes avec un grand nombre d'lments interactifs, en utilisant de multiples vues si ncessaire. Le support de Qt pour OpenGL et OpenGL ES aide les dveloppeurs intgrer des graphismes 3D dans leurs applications, en mme temps qu'il leur permet de profiter du matriel graphique moderne pour amliorer les performances de rendu 2D. Le support des couleurs de manire indpendante du matriel permet de spcifier des couleurs par des valeurs RVBA, HSVA ou CMJNA ou par des noms usuels. Les canaux de couleur utiliss font seize bits de largeur et un niveau d'opacit optionnel peut tre spcifi. Qt alloue automatiquement la couleur demande dans la palette systme ou utilise une couleur similaire sur des affichages limits.

Les graphismes sont affichs en utilisant des objets de dessin indpendants du matriel, qui permettent au dveloppeur de rutiliser le mme code sur diffrents types de priphriques, reprsents dans Qt par des priphriques de dessin. Cette approche assure qu'une large gamme de puissantes oprations de dessin sont disponibles pour chaque plateforme supporte par Qt et permet galement aux dveloppeurs de choisir les 6.1. Dessin priphriques les plus adapts leurs besoins. Qt fournit une API indpendante de la plateforme pour dessiner sur des widgets et d'autres priphriques de dessin. Il fournit des primitives de dessin comme des fonctionnalits avances (notamment, les transformations). Tous les widgets de Qt se dessinent l'aide de QPainter et les programmeurs utilisent cette mme classe pour implmenter leurs widgets personnaliss. QPainter fournit des fonctions standard pour dessiner des points, des lignes, des ellipses, des arcs, des courbes de Bzier et d'autres primitives. Des oprations de dessin plus complexes incluent le support des polygones et des chemins vectoriels, permettant la prparation des dessins dtaills (dessinables alors avec un simple appel de fonction). Le texte peut aussi tre affich directement avec un dessinateur ou incorpor dans un chemin pour
Numro 37 Dcembre - Janvier 2011/2012 Page 37

La dmonstration des botes prsente une srie de fonctionnalits graphiques de Qt.

Developpez Magazine est une publication de developpez.com

utilisation future. Le systme de dessin de Qt fournit aussi un certain nombre de fonctionnalits pour amliorer la qualit globale du rendu, dont des fondus alpha, des modes de composition Porter-Duff, l'anti-aliasing, des remplissages avec des dgrads linaires, radiaux et coniques. 6.2. Images Qt supporte l'entre, la sortie et la manipulation d'images dans divers formats, dont BMP, GIF, JPEG, MNG, PNG, PNM, TIFF, XBM et XPM. Les deux classes (QImage et QPixmap) peuvent tre utilises comme priphriques de dessin et utilises dans des applications graphiques interactives ou pour prparer les images pour utilisation future dans des composants de l'interface.

QImage (indpendants du matriel) et des objets QPixmap, optimiss pour l'affichage. Les formats de fichier standard peuvent tre crs en effectuant un rendu dans une image avec la profondeur de couleur et le format de pixels dsirs. Les images peuvent tre cres avec support de diffrents niveaux de transparence et dessines sur des widgets personnaliss pour obtenir certains effets. Les fichiers vectoriels et les mtafichiers sont aussi supports par le systme de dessin. QSvgGenerator cre des images SVG en traduisant les commandes de dessin par les structures correspondantes du format SVG. QPicture est utilis pour contenir une srie de commandes de dessin qui peuvent tre rejoues pour dessiner sur un autre priphrique ou pour stockage dans un fichier. L'impression est effectue avec un rendu dans un QPrinter, qui reprsente une imprimante physique. Sur Windows, les commandes de dessin sont envoyes au moteur d'impression de Windows, qui utilise les pilotes installs. Sur UNIX, les donnes PostScript ou PDF sont envoyes au dmon d'impression - ceci est gr par CUPS (Common Unix Printing System) sur des systmes rcents.

QImage est utilise pour la manipulation d'images et peut effectuer des conversions entre diverses profondeurs de couleur et formats de pixel. Les programmeurs peuvent manipuler les pixels et les donnes de la palette, appliquer des transformations comme des rotations et rduire la profondeur de couleur avec tramage si dsir. Le support des canaux alpha permet d'utiliser la transparence et les En utilisant l'API de dessin gnrique de Qt, des fusions alpha pour la composition d'images et d'autres applications peuvent crer des fichiers PDF et PS qui fins. peuvent tre gnrs sur toutes les plateformes, donc crer des documents de haute qualit qui peuvent tre visualiss La gamme de formats de fichiers supports qui peuvent par des applications de lecture appropries. tre utiliss avec ces classes peut tre tendue avec des plug-ins d'extension. 6.4. Framework de la vue graphique Qt contient un nouveau mais trs puissant framework pour les applications graphiques interactives, utilis pour grer et afficher un grand nombre d'items dans une scne 2D. La vue graphique fournit une API oriente objet pour ajouter de nouveaux items une scne et une API plus traditionnelle, semblable celle du canevas, contenant des fonctions auxiliaires pour crer des items prdfinis. Une fois crs, les items peuvent tre placs avec les position, orientation et chelle requises dans une scne. Les fonctionnalits d'affichage et de gestion des items sont implmentes sparment dans les classes QGraphicsView et QGraphicsScene, ce qui facilite des fonctionnalits comme les multiples vues sur la mme scne et le support de moteurs de rendu changeables. Une slection de types d'item standard est fournie, ceux-ci peuvent tre tendus par le biais de sous-classes pour fournir des types d'item personnaliss. Ils peuvent tre groups pour un contrle de plus haut niveau de la scne. Chaque scne, vue et item fournit un ensemble complet de fonctions pour transformer les coordonnes entre les diffrents systmes. Les items standard et personnaliss peuvent tre rendus slectionnables et dplaables, avec un niveau basique d'interactivit et un minimum de code. La vue graphique a t pense avec les animations en tte : les items peuvent tre utiliss pour crer des objets anims qui sont transforms en fonction d'une srie de transformations dfinies certains points sur une ligne du temps.

Le framework de la vue graphique permet la cration d'applications graphiques qui combinent une haute qualit de rendu des fonctionnalits compltes pour l'interaction avec l'utilisateur. 6.3. Priphriques de dessin et impression QPainter peut tre utilis sur n'importe quel priphrique de dessin. Le code requis pour dessiner sur n'importe quel priphrique support est le mme, peu importe le priphrique. Tous les widgets sont des priphriques de dessin. Les fentres transparentes avec une forme spcifique peuvent tre cres sur des systmes correctement configurs. Les surfaces OpenGL utilises avec QGLWidget sont aussi des priphriques de dessin qui convertissent les appels standard QPainter en appels OpenGL, ce qui fait que des oprations 2D sont acclres sur des priphriques avec un matriel support.

Des images peuvent aussi tre cres en dessinant sur des Certains items standard apportent des fonctionnalits
Numro 37 Dcembre - Janvier 2011/2012 Page 38

Developpez Magazine est une publication de developpez.com

trouvables d'autres endroits de Qt au framework, dont des diteurs de texte riche, la navigation sur le Web, l'affichage de dessins SVG et l'utilisation de formes, chemins et images. Les items d'une scne peuvent tre rendus indpendamment de la vue attache, les scnes peuvent donc tre rendues dans des images et imprimes dans des fichiers PDF.

3D qui peut tre utilise par les dveloppeurs Qt pour inclure des graphismes 3D dans leurs applications graphiques. Le module OpenGL de Qt est disponible sur Windows, X11 et Mac OS X et utilise la bibliothque OpenGL de chaque systme. Pour utiliser OpenGL dans une application Qt, il suffit aux dveloppeurs de sous-classer QGLWidget et de dessiner dessus avec les fonctions standard d'OpenGL. Qt fournit des fonctions pour convertir les valeurs des couleurs dans le format d'OpenGL pour fournir une interface constante pour les applications.

Un modle vnementiel complet permet une gestion efficace des vnements en les distribuant aux items qui en ont besoin. Puisque la gestion basique des items est effectue par le framework, les items doivent seulement rpondre aux vnements s'ils ont besoin d'une information particulire sur leur environnement. Qt supporte aussi des fonctionnalits et extensions d'OpenGL, avec une utilisation plus pratique l'intrieur Les applications qui doivent mlanger des lments des applications Qt. Des fonctions auxiliaires permettent d'interface utilisateur classique avec du contenu interactif de crer des textures depuis des images et le support des peuvent embarquer des widgets directement dans une tampons de pixels et de frames est fourni par des classes scne en utilisant QGraphicsProxyWidget ou crer en appropries. Le support de fonctionnalits comme les partant de rien avec QGraphicsWidget des lments tampons d'chantillons peut tre activ si elles sont ressemblant des items. Comme pour les interfaces disponibles sur le systme sous-jacent. conventionnelles, les gestionnaires de disposition peuvent tre utiliss pour disposer les widgets et les items dans une Les applications 2D peuvent utiliser des sous-classes de scne. QGLWidget pour amliorer les performances de rendu sur du matriel appropri. Dans ce cas, les oprations standard de QPainter sont transformes en appels OpenGLCeci rendu aussi possible de recouvrir des contrles sur des scnes 3D peintes avec seulement OpenGL. Sur des plateformes embarques, o l'acclration matrielle est souvent limite, ce moteur de rendu est restreint aux fonctionnalits d'OpenGL ES 2.0, ce qui permet de s'assurer qu'il fonctionne parfaitement sur un grand nombre de priphriques. Sur du matriel appropri, le support du rendu anti-alias Les dessins SVG peuvent tre rendus sur n'importe quel peut tre activ pour amliorer la rapidit du rendu et la qualit des graphismes produits en utilisant le moteur priphrique de dessin support par Qt. OpenGL. Sur du matriel moins puissant, les dveloppeurs peuvent donner le choix l'utilisateur entre la qualit et la 6.5. SVG rapidit, en exposant ces options de rendu l'utilisateur Scalable Vector Graphics est un format de fichier bas sur l'excution. XML et un langage pour dcrire des applications graphiques, habituellement associ aux graphismes 2D du 6.7. Multimdia Web. Le support SVG dans Qt est bas sur le standard SVG 1.1, une recommandation du W3C (World Wide Web Qt utilise le framework multimdia Phonon, un projet Consortium). Il fournit des fonctionnalits additionnelles open source de KDE, pour fournir des fonctionnalits de lecture de mdias, travers une API constante et pour le support des profils Tiny de SVG 1.1 et 1.2. multiplateforme. Qt s'assure que les applications sur Qt peut rendre des dessins SVG sur n'importe quel Linux, Unix, Windows et Mac OS X utilisent de manire priphrique de dessin, dont ceux pour les images et les transparente le framework multimdia de chaque widgets OpenGL. Cette flexibilit laisse les dveloppeurs plateforme - ceci signifie que les applications peuvent changer la qualit pour la rapidit quand cela est aussi profiter du support spcifique la plateforme pour ncessaire. Les dessins SVG peuvent aussi tre utiliss les codecs et formats audio et vido. pour des icnes dans des contrles d'interface, enlevant ainsi le besoin de gnrer des bitmaps dans une srie de Les fonctionnalits de Phonon peuvent tre intgres d'autres technologies de Qt. Par exemple, des widgets de tailles prdfinies. films peuvent tre ajouts des pages Web affiches avec Les dveloppeurs peuvent aussi gnrer des dessins SVG le moteur d'affichage WebKit et des scnes rendues avec en utilisant les fonctions de QPainter pour dessiner sur un le framework de la vue graphique. priphrique de dessin spcialis SVG, les graphiques utiliss dans des applications peuvent donc tre exports Des classes supplmentaires pour le multimdia sont incluses dans le module QtMultimedia. Ces classes sont comme dessins SVG avec peu d'effort supplmentaire. orientes sur l'accs de bas niveau aux donnes audio et vido. 6.6. Graphismes 3D OpenGL est une API standard pour le rendu de graphismes
Numro 37 Dcembre - Janvier 2011/2012 Page 39

Developpez Magazine est une publication de developpez.com

6.8. Rfrences en ligne Qpainter : Lien 106. La vue graphique : Lien 107. QtOpenGL : Lien 108. QtMultimedia : Lien 109. QtSVG : Lien 110. Phonon : Lien 111.

QListView, QTableView et QTreeView ont les composants modle-vue quivalents. Ils fournissent une manire plus propre et plus oriente composant de grer les ensembles de donnes. De plus, une srie de modles standard de donnes sont fournis pour aider les dveloppeurs organiser leurs donnes. 7.1. Vues d'items standard Les implmentations standard des widgets de vue en liste, en arbre, en tableau et d'icnes sont fournies par Qt. Elles supportent les oprations de glisser-dposer dans la mme vue et entre des vues diffrentes. Comme pour tous les widgets Qt, elles sont aussi compltement intgres au systme de ressources de Qt.

7. Vues d'items

Les widgets de visualisation d'items fournissent des contrles GUI standard pour afficher et modifier de larges quantits de donnes. Le framework modle-vue sousjacent isole le stockage des donnes et leur prsentation l'utilisateur, ce qui fait que des fonctionnalits comme le partage de donnes, le tri et le filtrage, les vues multiples Les classes de vue sont utilises pour afficher des donnes et les multiples reprsentations peuvent utiliser le mme de diverses botes de dialogue dans Qt et sont utilises de manire extensive dans Qt Designer, Qt Assistant et Qt ensemble de donnes. Linguist. Lors de l'criture d'applications qui traitent de grandes quantits de donnes, les dveloppeurs utilisent Les vues classiques servent gnralement afficher et gnralement des widgets de vue d'items pour afficher les grer quelques centaines d'items, en usant d'une donnes rapidement et efficacement. Des vues standard architecture qui utilise des objets individuels pour que l'on peut trouver dans des botes outils graphiques encapsuler des donnes. Cette approche devrait tre modernes incluent gnralement des vues en liste familire des dveloppeurs Qt et fournit une manire contenant de simples listes d'items, des vues en arbre avec agrable de construire rapidement des interfaces riches une liste hirarchique d'items et des tableaux, qui pour grer des quantits raisonnables de donnes. fournissent des fonctionnalits de positionnement Pour la cohrence et la fiabilit, les vues classiques se semblables aux tableurs. basent sur le framework modle-vue de Qt, qui fournit une manire plus adapte de grands volumes de donnes et plus personnalisable pour grer ces vues. 7.2. Le framework modle-vue Le framework modle-vue fourni par Qt est une variation du patron de conception MVC bien connu (Model-ViewController, modle-vue-contrleur), spcifiquement adapt aux vues d'items de Qt. Dans cette approche, les modles sont utiliss pour fournir des donnes d'autres composants, des vues qui affichent des items l'utilisateur et des dlgus qui grent le rendu et l'dition.

L'architecture oriente composant du framework modlevue facilite la personnalisation des vues d'items. Les modles ne sont que de fins emballages autour des sources de donnes, crites conformment une interface standard fournie par QAbstractItemModel. Cette interface autorise les widgets drivant de QAbstractItemView accder aux donnes fournies par le modle, peu importe la nature de la source des donnes.

Qt fournit des vues standard pour les arbres, listes et tableaux d'items.

La sparation entre les donnes et leur reprsentation dans Les classes de vue d'items de Qt sont disponibles en deux cette approche fournit un certain nombre d'avantages par formats : des widgets classiques et des composants rapport aux vues classiques : modle-vue. Les listes, tableaux et arbres classiques sont puisque les modles fournissent une interface des widgets autonomes qui grent leurs objets d'item, standard pour accder aux donnes, ils peuvent explicitement crs par le dveloppeur. tre conus et crits sparment, mme remplacs au besoin ;
Numro 37 Dcembre - Janvier 2011/2012 Page 40

Developpez Magazine est une publication de developpez.com

les donnes obtenues de modles peuvent tre partages par les vues ; ainsi, des applications peuvent offrir plusieurs vues des mmes donnes, potentiellement avec plusieurs reprsentations ; les slections peuvent tre partages entre les vues ou gardes spares, en fonction des attentes et demandes de l'utilisateur ; pour les listes, arbres et tableaux standard, le gros du rendu est effectu par les dlgus, ce qui facilite la personnalisation des vues sans devoir rcrire beaucoup de code ; Les documents peuvent tre exports au format en utilisant des modles proxy, les donnes OpenOffice pour utilisation dans un logiciel de traitement de texte. fournies par des modles peuvent tre transformes avant d'tre passes aux vues ; les applications peuvent donc fournir des 8.1. dition de texte riche fonctionnalits de tri et de filtrage que l'on peut L'affichage interactif de texte riche et son dition sont partager entre les vues. grs par Qt dans les widgets QTextBrowser et QTextEdit. Ils supportent compltement Unicode et sont construits sur Le systme modle-vue est aussi utilis par les modles une reprsentation de la structure du document fournie par SQL de Qt pour rendre l'intgration d'une base de donnes QTextDocument, il n'y a pas besoin d'utiliser des langages plus simple pour les dveloppeurs ne les matrisant pas. de balisage intermdiaires pour crer du texte riche. QTextDocument fournit aussi un support de l'import et de 7.3. Rfrences en ligne l'export d'un sous-ensemble de HTML 4.0, des capacits d'undo-redo (dont les actions groupes) et la gestion des Programmation modle-vue : Lien 112. ressources. Exemples : Lien 113. 8. Gestion du texte Qt fournit un puissant diteur de texte dans lequel l'utilisateur peut crer et diter des documents riches, il peut aussi tre utilis pour prparer des documents pour l'impression. La structure de document sous-jacente est compltement accessible aux dveloppeurs, ce qui fait que la structure et le contenu du document peuvent tre manipuls. Les documents riches contiennent gnralement du texte dans plusieurs fontes (police, taille, corps) et couleurs, arrang dans une srie de paragraphes. Il peut aussi tre organis dans des listes et des tableaux, ainsi qu'tre visuellement spar du corps du document avec des cadres. L'apparence de chaque lment du document peut tre prcisment ajuste en utilisant les nombreuses fonctionnalits disponibles aux dveloppeurs grce l'API de texte riche. Qt fournit une API oriente objet pour les documents qui aide le dveloppeur obtenir une vue globale de haut niveau sur les structures. Une API base sur des curseurs est aussi fournie pour faciliter l'exploration, le traitement et la transformation des documents. En plus des classes correspondant la structure et au contenu, il y a bon nombre d'autres classes pour contrler l'apparence du texte et des lments de document. Ceci fait que les styles de texte pour les tableaux, les listes, les cadres et les paragraphes ordinaires peuvent tre personnaliss pour donner aux documents l'apparence dsire. Les documents crs par le code restent ditables dans les widgets QTextEdit et conservent un historique complet d'undo-redo. Les dveloppeurs peuvent ajouter de nouvelles fonctionnalits l'diteur, faisant en sorte que les utilisateurs puissent alors insrer des structures et du contenu personnaliss. 8.2. Personnalisation, impression et export du document Les fonctionnalits de gestion du texte de Qt peuvent tre utilises pour fournir du formatage spcialis du texte pour des widgets personnaliss et des documents riches. On peut les crire avec des classes de bas niveau comme QTextLayout pour disposer le texte ligne par ligne, puis les intgrer dans le systme de disposition extensible de texte fourni par QTextDocument pour utilisation avec QTextEdit. Des rgles de coloration syntaxique peuvent aussi tre appliques des documents riches avec QSyntaxHighlighter. Un simple widget QTextEdit pourra Les fonctionnalits avances d'dition de texte riche de Qt permettent la cration et l'dition de documents complexes tre utilis comme base d'un diteur de code, cela peut aussi servir des outils de recherche dans le document. dans QTextEdit. Les documents peuvent aussi tre formats selon les informations obtenues d'une bote de dialogue
Numro 37 Dcembre - Janvier 2011/2012 Page 41

Developpez Magazine est une publication de developpez.com

QPrintDialog dans une srie de pages que l'on peut passer Inversement, l'intgration entre Qt et le moteur de rendu un QPrinter. permet d'intgrer des contrles Qt natifs dans les pages Web, ce qui rend possible de combiner du contenu Web La classe QTextDocumentWriter fournit un support de avec des interfaces natives hautement dynamiques. l'export de documents en HTML, texte brut et fichiers OpenDocument Format (ODF). Cette classe expose ses Les applications peuvent aussi profiter de WebKit pour fonctionnalits par le biais d'une API gnrique et est utiliser le stockage natif pour les donnes persistantes, prvue pour tre tendue d'autres formats dans de futures cette fonctionnalit tant supporte par Qt. Les versions. dveloppeurs peuvent activer le stockage natif pour des applications qui interagissent avec des services distants et prendre appui sur les options de configuration pour dfinir 8.3. Rfrences en ligne un endroit appropri et un quota sur le systme utilisateur. Les classes du framework Scribe : Lien 114. Traitement du texte riche : Lien 115. 9.2. API d'accs l'arbre DOM QtextDocumentWriter : Lien 116. La manire standard de manipuler la structure de pages Web est d'utiliser l'API DOM (Document Object Model, 9. Intgration Web avec QtWebKit modle objet du document). QtWebKit inclut une L'intgration de Qt avec le moteur WebKit fait que les implmentation de l'API des slecteurs du W3C qui fournit dveloppeurs peuvent introduire des fonctionnalits Web un accs trs simple la structure des pages, ainsi que leur dans leurs applications avec des API et paradigmes de la modification. mme veine que Qt pour afficher et interagir avec du contenu Web. Cette API rend intuitif l'accs au DOM en laissant les dveloppeurs rutiliser leurs connaissances sur les Qt inclut un support intgr pour Web Kit, un moteur de slecteurs CSS, sans occasionner de surcharge ou de rendu Web open source complet, qui se focalise sur la maintenance supplmentaire. stabilit et les performances. La version de WebKit fournie avec Qt supporte bon nombre de standards du Web, dont 9.3. Support des plug-ins Netscape HTML 4.01, XHTML 1.1, CSS 2.1 et JavaScript 1.5. Des fonctionnalits plus avances sont aussi disponibles, elles Les plug-ins se conformant l'API Netscape, un standard de facto pour les composants tiers des navigateurs, sont prsentes dans le livre blanc ddi. peuvent tre embarqus et affichs dans des pages Web La gestion du rseau de WebKit est assure de manire rendues par QtWebKit. La configuration de cette transparente par les classes de Qt, qui donnent aux fonctionnalit est effectue dans une classe Qt qui est aussi composants du navigateur une implmentation conforme utilise pour configurer d'autres sortes de plug-ins, comme aux standards HTTP 1.1, supportant la communication les plug-ins de widgets exposs par l'application l'environnement Web. SSL (Secure Sockets Layer) et les proxies.

Les widgets Qt peuvent tre embarqus dans des pages Web affiches par l'intgration WebKit dans Qt ; ces pages Web peuvent tre affiches comme des items avec le framework de la vue graphique. 9.1. Intgration aux applications natives

Les plug-ins tiers sont supports par QtWebKit via l'API Netscape. 9.4. Rfrences en ligne

Le module QtWebKit : Lien 117. Le support de Qt pour WebKit dpasse l'affichage de HTML en exposant les fonctionnalits de WebKit aux Dmo : un navigateur Web : Lien 118. applications en utilisant les paradigmes Qt. Par exemple, le Intgrer des widgets avec QtWebKit : Lien 119. mcanisme de signaux et de slots pour la communication facilite la connexion de composants Web des widgets et Retrouvez l'intgralit de l'article des Qt Developer d'autres objets de l'application. Network traduit par Aldiemus et Thibaut Cuvelier en ligne : Lien 120

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 42

Utilisation de QGraphicsItem Ce tutoriel traite de l'utilisation des QGraphicsItem. Il est destin aux dveloppeurs Python ayant dj de bonnes connaissances dans l'usage du framework Qt.
1. Introduction QGraphicsItem est la classe de base pour tous les objets graphiques pouvant tre affichs dans un QGraphicsScene. Cette classe permet de crer ses propres objets graphiques et de grer leurs proprits telles que les donnes de gomtrie de l'objet et ses interactions avec les autres lments prsents dans la scne (dont la dtection de collisions entre lments graphiques). 2. Les items graphiques de base Qt propose une srie de QGraphicsItem de base destins reprsenter les objets graphiques les plus courants : QGraphicsEllipseItem : dfinit un item ellipse ; QGraphicsLineItem : dfinit un item ligne ; QGraphicsPathItem : dfinit un item chemin de trac ; QGraphicsPixmapItem : dfinit un item pixmap ; QGraphicsPolygonItem : dfinit un item polygone ; QGraphicsRectItem : dfinit un item rectangle ; QGraphicsSimpleTextItem : dfinit un item simple texte ; QGraphicsTextItem : dfinit un item texte plus complexe que l'item prcdent. Nous nous intresserons plus particulirement, dans cet article au QGraphicsPixmapItem en ralisant un objet graphique utilisant la fois les classes QPixmap, QPainter, QPainterPath, l'application de texture, la dcoupe de zone transparente, les vnements souris et clavier et les signaux pour communiquer avec l'interface utilisateur. Pour cela nous raliserons un outil loupe pour visionneuse d'image. 3. Les scripts Python En bas de cet article, se trouvent les liens permettant de tlcharger l'archive contenant les scripts ncessaires. Le code main.py est celui qu'il faut lancer, magnifier.py est celui de la loupe et sera principalement dcrit ici et le script miniView.py est une version simplifie de la visionneuse dcrite dans cet article : Lien 121, et dont le code ne demande plus tre dtaill. L'image cre en premier tant la rfrence ncessaire de la visionneuse pour recrer la pixmap lors de zoom, on va en crer une copie et la mettre directement au facteur de grossissement choisi pour la loupe. On dposera ensuite sur cette copie un gabarit de la forme et de la taille de la loupe, qui servira prlever la texture qui sera peinte dans le QGraphicsPixmapItem. Ensuite, par un systme de pantographe informatique on assurera le dplacement du gabarit sur l'image de rfrence suivant les dplacements de la loupe effectus par l'utilisateur. La classe Magnifier se prsentera comme ceci :
magnifier.py class Magnifier(QtGui.QGraphicsPixmapItem): def __init__(self, main, parent=None, graphic=None, scene=None, i mg=None, zoom=None): super(Magnifier, self).__init__(parent, scene) self.main = main d = dict(shape = "square", size = 160, factor = 1.0, image = img, graphic = graphic, scene = scene, cur_pos = None, zoom = zoom, background_color = (255, 255, 255, 255), old_X = None, old_Y = None) for key, value in d.iteritems(): setattr(self, key, value) self.setFlags(QtGui.QGraphicsItem.ItemIsM ovable | QtGui.QGraphicsItem.ItemI sFocusable) self.setAcceptHoverEvents(True) self.build_settings() self._moved = Moved() self._optionChanged = OptionChanged()

Utilisation de QGraphicsItem

4. Principes de base Voyons d'abord le fonctionnement de la loupe. On part du principe que l'on dispose d'une image cre en tant que QImage sa taille relle et une pixmap QPixmap issue de l'image, rduite aux dimensions de la vue et affiche dans celle-ci. La loupe aura trois paramtres : sa forme, sa taille et son facteur de grossissement.

Les arguments ncessaires l'instanciation de la classe sont les suivants :


Numro 37 Dcembre - Janvier 2011/2012 Page 43

Developpez Magazine est une publication de developpez.com

main : l'application principale ; parent : le parent, gnralement laiss None ; graphic : l'instance du QGraphicsView de notre visionneuse utilise pour centrer la loupe et pour mapper des coordonnes entre scne et vue ; scene : l'instance de la QGraphicsScene ; img : l'instance de la QImage originale ; zoom : le facteur de zoom actuel de la pixmap affiche dans la visionneuse.

La loupe ncessite quelques attributs supplmentaires : shape : la forme de la loupe, "square" ou "circle" ; size : sa taille en pixels ; factor : le facteur de grossissement ; cur_pos : la position courante de la loupe une fois affiche ; background_color : la couleur de fond du QGraphicsView ; old_X et old_Y : des rfrences de positionnement lors de dplacement. Aprs les attributs d'instances il faut initialiser quelques drapeaux ncessaires au QGraphicsItem. 5. Les drapeaux La liste suivante dcrit les drapeaux les plus couramment utiliss. QGraphicsItem.ItemIsMovable : l'item peut tre dplac avec la souris ; si l'item comporte des items enfants, ceux-ci seront dplacs avec lui et, si l'item fait partie d'un groupe d'items slectionns, l'ensemble de ceux-ci sera dplac ; QGraphicsItem.ItemIsSelectable : l'item peut tre slectionn. La slection pourra se faire au moyen de la souris, en cliquant dessus, ou en traant un QRubberBand, ou de la mthode QGraphicsItem.setSelected(), ou encore par QGraphicsScene.setSelectionArea() ; QGraphicsItem.ItemIsFocusable : l'item peut avoir le focus. Indispensable pour des interactions avec le clavier ; QGraphicsItem.ItemSendsGeometryChanges :

l'item peut notifier les changements dcrits par QGraphicsItem.itemChange(). L'utiliser peut avoir une incidence sur les performances du programme ; QGraphicsItem.ItemSendsScenePositionChan ges : l'item peut notifier ses changements de position. L'usage de ce drapeau est moins rducteur en performances que ItemSendsGeometryChanges, car il ne notifie que les dplacements de l'item, soit ItemScenePositionHasChanged ; QGraphicsItem.ItemIgnoresTransformations : l'item n'hrite pas des transformations de son parent. Lorsqu'un item possde des enfants, ceuxci subissent aussi ses transformations (rotation, dimensionnement, etc.). Avec ce drapeau l'item enfant devient insensible aux transformations de son parent. Utile si l'item contient du texte, pour garantir que celui-ci reste toujours lisible ; QGraphicsItem.ItemIgnoresParentOpacity : l'item est insensible aux changements d'opacit de son parent. Par dfaut, l'opacit d'un item, dfinie avec setOpacity(), s'applique aussi ses items enfants ; QGraphicsItem.ItemDoesntPropagateOpacity ToChildren : l'inverse du drapeau prcdent, ici c'est l'item qui ne transmet pas sa valeur d'opacit ses items enfants.

Voir les documentations respectives de PyQt (Lien 122) et PySide (Lien 123) des GraphicsItemFlag. Pour la loupe, il est ncessaire que celle-ci soit dplaable et puisse recevoir le focus.
magnifier.py self.setFlags(QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIsFocusable)

Les dernires lignes du code de __init__() seront vues plus loin dans l'article. Retrouvez la suite de l'article de Vincent Vande Vyvre en ligne : Lien 124

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 44

C/C++/Gtk+
Les derniers tutoriels et articles
Utilisation de la LibZip Tutoriel sur l'utilisation de la bibliothque LibZip.
1. Introduction Pour utiliser les archives zip plusieurs bibliothques sont disponibles. Dans ce tutoriel nous allons nous intresser la libzip (Lien 125). Cette bibliothque est crite en C et permet de lire, crer ou modifier les archives zip. ce jour, la dernire version est la 0.10 qui date du 18/03/2010. C'est cette version qui a t utilise pour ce tutoriel. Le manuel de la bibliothque est trs clair et quasiment toutes les fonctions sont dtailles. Il se trouve en ligne (Lien 126) ou via man libzip pour la bibliothque en gnral et man "nom de la commande". Ce document prsente comment : lister le contenu d'une archive zip ; effacer un fichier/dossier d'une archive zip ; renommer un fichier/dossier d'une archive zip ; remplacer un fichier d'une archive zip ; extraire un fichier/dossier d'une archive zip ; dcompresser une archive zip ; crer une archive zip. Tous les codes sont en C. Les codes ci-dessous peuvent faire appel des fonctions non prsentes dans cette page mais le tout est disponible dans le code source C prsent la fin de la page. Le tutoriel n'est disponible que pour les systmes UNIX/POSIX. Il ne devrait pas tre difficile adapter pour la plateforme Windows. Le code prsente des appels particuliers POSIX et considre que les chemins sont de type UNIX '/' et non de type Windows '\'. Tout a t test sur FreeBSD, si des modifications sont apporter pour d'autres systmes n'hsitez pas me le faire savoir. 2. Exemple de Code 2.1. Lister le contenu d'une archive zip 2.1.1. Algorithme Ouvrir l'archive (Fonction zip_open). Compter le nombre d'lments dans l'archive (Fonction zip_get_num_files). Pour chaque lment, afficher son nom (Fonction zip_get_name). Fermer l'archive (Fonction zip_close). 2.1.2. Code source Afficher le contenu d'une archive Zip /**
* \fn static int afficherFichierZip(const char* fichierZip) * \brief Affiche les fichiers l'intrieur de l'archive Zip. * * \return ZIPZAP_SUCCESS : Retour OK ; ZIPZAP_FAILURE : Retour d'erreur. */ static int afficherFichierZip(const char* fichierZip) { if(fichierZip == NULL) return ZIPZAP_FAILURE; int err = 0; struct zip *f_zip=NULL; f_zip = zip_open(fichierZip, ZIP_CHECKCONS, &err); /* on ouvre l'archive zip */ /* s'il y a des erreurs */ if(err != ZIP_ER_OK) { zip_error_to_str(buf_erreur, sizeof buf_erreur, err, errno); printf("Error %d : %s\n",err, buf_erreur); return ZIPZAP_FAILURE; } /* si le fichier zip n'est pas ouvert */ if(f_zip==NULL) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); return ZIPZAP_FAILURE; } /* on rcupre le nombre de fichiers dans l'archive zip */ int count = zip_get_num_files(f_zip); if(count==-1) { printf("Erreur la lecture du fichier %s\n", fichierZip); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; } int i = 0; printf("Nombre de fichiers dans l'archive : %d\n",count); for(i=0; i<count; i++) { /* on utilise la position "i" pour rcuprer le nom des fichiers */ printf("%s\n", zip_get_name(f_zip, i,

Utilisation de la LibZip

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 45

ZIP_FL_UNCHANGED)); } zip_close(f_zip); f_zip = NULL; return ZIPZAP_SUCCESS;

%s\n", fichier, fichierZip); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; }

} 2.2. Effacer un fichier/dossier d'une archive zip 2.2.1. Algorithme Ouvrir l'archive (Fonction zip_open). Rechercher le fichier/dossier dans l'archive (Fonction zip_name_locate). Si c'est un dossier pour chaque lment du dossier, le supprimer (Fonction zip_delete). Sinon le supprimer (Fonction zip_delete). Fermer l'archive (Fonction zip_close). 2.2.2. Code source Effacer un fichier/dossier d'une archive zip /**
* \fn static int effacerFichierZip(const char* fichierZip, const char* fichier) * \brief Efface le fichier/dossier "fichier" de l'archive zip "fichierZip". * * \param fichierZip Archive zip contenant le fichier effacer. * \param fichier Nom du fichier/dossier effacer. * * \return ZIPZAP_SUCCESS : Retour OK ; ZIPZAP_FAILURE : Retour d'erreur. */ static int effacerFichierZip(const char* fichierZip, const char* fichier) { int visu = 0; struct zip * f_zip=NULL; int err = 0; f_zip=zip_open(fichierZip,ZIP_CREATE,&err); /* s'il y a des erreurs */ if(err != ZIP_ER_OK) { zip_error_to_str(buf_erreur, sizeof buf_erreur, err, errno); printf("Error %d : %s\n",err, buf_erreur); return ZIPZAP_FAILURE; } /* si le fichier zip n'est pas ouvert */ if(f_zip==NULL) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); return ZIPZAP_FAILURE; } visu=zip_name_locate(f_zip,fichier,0); if (visu==-1) /* recherche de l'emplacement du fichier dans le zip */ { printf("Le fichier %s n'existe pas dans

*/

/* si on demande la suppression d'un rpertoire

if(fichier[strlen(fichier)-1]=='/') { char *ptr = NULL; int i = 0; int count = zip_get_num_files(f_zip); if(count==-1) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); zip_close(f_zip); f_zip = NULL; ptr = NULL; return ZIPZAP_FAILURE; } for(i=0; i<count; i++) {

/* on parcourt tous les fichiers du zip pour savoir si un fichier est dans le dossier supprimer */ if( (ptr=strstr(zip_get_name(f_zip, i, ZIP_FL_UNCHANGED), fichier)) != NULL) { /* on efface le fichier positionn l'index i */ if(zip_delete(f_zip,i) == -1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; ptr = NULL; return ZIPZAP_FAILURE; } printf("Le fichier %s a t supprim dans %s\n", zip_get_name(f_zip, i, ZIP_FL_UNCHANGED), fichierZip); } } ptr = NULL; } else { /* sinon on supprime simplement le fichier trouv par zip_name_locate la position visu */ if(zip_delete(f_zip,visu) == -1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; } printf("Le fichier %s a t supprim dans %s\n", fichier, fichierZip); }

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 46

/* lecture termine, fermeture de l'archive */ zip_close(f_zip); f_zip = NULL; return ZIPZAP_SUCCESS;

} 2.3. Renommer un fichier/dossier d'une archive zip 2.3.1. Algorithme Ouvrir l'archive (Fonction zip_open). Rechercher le fichier/dossier dans l'archive (Fonction zip_name_locate). Si c'est un dossier pour chaque lment du dossier, le renommer (Fonction zip_rename). Sinon le renommer (Fonction zip_rename). Fermer l'archive (Fonction zip_close). 2.3.2. Code source Renommer un fichier/dossier d'une archive /**
* \fn static int renommerFichierZip(const char* fichierZip, const char* fichierFrom, const char* fichierTo) * \brief Efface le fichier/dossier "fichierFrom" en "FichierTo" de l'archive zip "fichierZip". * * \param fichierZip Archive zip contenant le fichier effacer. * \param fichierFrom Nom du fichier/dossier en entre. * \param fichierTo Nom du fichier/dossier en sortie. * * \return ZIPZAP_SUCCESS : Retour OK ; ZIPZAP_FAILURE : Retour d'erreur. */ static int renommerFichierZip(const char* fichierZip, const char* fichierFrom, const char* fichierTo) { int visu = 0; struct zip * f_zip=NULL; int err = 0; f_zip=zip_open(fichierZip,ZIP_CREATE,&err); /* s'il y a des erreurs */ if(err != ZIP_ER_OK) { zip_error_to_str(buf_erreur, sizeof buf_erreur, err, errno); printf("Error %d : %s\n",err, buf_erreur); return ZIPZAP_FAILURE; } /* si le fichier zip n'est pas ouvert */ if(f_zip==NULL) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); return ZIPZAP_FAILURE; } /* recherche de l'emplacement du fichier dans le zip */ visu=zip_name_locate(f_zip,fichierFrom,0);

if (visu==-1) { printf("Le fichier %s n'existe pas dans %s\n", fichierFrom, fichierZip); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; }

/* si on demande de renommer un rpertoire */ if(fichierFrom[strlen(fichierFrom)-1]=='/') { char *ptr = NULL; int i = 0; int count = zip_get_num_files(f_zip); if(count==-1) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); return ZIPZAP_FAILURE; } for(i=0; i<count; i++) { /* on parcourt tous les fichiers du zip pour savoir si un fichier est dans le dossier supprimer */ if( (ptr=strstr(zip_get_name(f_zip, i, ZIP_FL_UNCHANGED), fichierFrom)) != NULL) { /* si c'est le rpertoire on lui applique un traitement particulier */ if(strlen(fichierFrom)==strlen(zip_ get_name(f_zip, i, ZIP_FL_UNCHANGED))) { if(zip_rename(f_zip,i,fichierTo ) == -1) { printf("%s\n", zip_close(f_zip); f_zip = NULL; ptr = NULL; return ZIPZAP_FAILURE; } printf("Le fichier %s a t renomm en %s dans %s\n", fichierFrom, fichierTo, fichierZip); } else { /* si c'est un fichier de ce rpertoire */ char *buf = NULL; buf = malloc(FILENAME_MAX*sizeof(char)); if(buf==NULL) { printf("Erreur d'allocation mmoire.\n"); zip_close(f_zip); f_zip = NULL; FREE(buf); ptr = NULL; return ZIPZAP_FAILURE; }

zip_strerror(f_zip));

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 47

strcpy(buf,fichierTo); strcat(buf,zip_get_name(f_zip, i, ZIP_FL_UNCHANGED)+strlen(fichierFrom)); printf("%s\n",buf); if(zip_rename(f_zip,i,buf) == -1) { printf("%s\n", zip_close(f_zip); f_zip = NULL; FREE(buf); ptr = NULL;

2.4.2. Code source Remplacer le fichier d'une archive /**


* \fn static int remplacerFichierZip(const char* fichierZip, const char* fichier, int ajout) * \brief Remplace le fichier/dossier "fichier" dans l'archive zip "fichierZip". * * \param fichierZip Archive zip contenant le fichier effacer. * \param fichier Nom du fichier/dossier remplacer. * \param ajout Si le fichier n'existe pas dans l'archive, on l'ajoute ou non suivant la valeur de ajout (REPLACE_ADD ou REPLACE_NOT_ADD). * * \return ZIPZAP_SUCCESS : Retour OK ; ZIPZAP_FAILURE : Retour d'erreur. */ static int remplacerFichierZip(const char* fichierZip, const char* fichier, int ajout) { /* Source de Troumad original : http://www.developpez.net/forums/d1012322/ccpp/c/contribuez/faq-modifier-fichier-zip/ */ /* modifi pour ajouter la gestion des erreurs et quelques fonctionnalits */ int visu = 0; struct zip * f_zip=NULL; struct zip_source * n_zip=NULL; int err = 0; f_zip=zip_open(fichierZip,ZIP_CREATE,&err); /* s'il y a des erreurs */ if(err != ZIP_ER_OK) { zip_error_to_str(buf_erreur, sizeof buf_erreur, err, errno); printf("Error %d : %s\n",err, buf_erreur); return ZIPZAP_FAILURE; } /* si le fichier zip n'est pas ouvert */ if(f_zip==NULL) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); return ZIPZAP_FAILURE; } /* on met dans le zip_source le fichier que l'on veut remplacer */ if((n_zip=zip_source_file(f_zip,fichier, (off_t)0, (off_t)0)) == NULL) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; } /* recherche de l'emplacement du fichier dans le zip */ visu=zip_name_locate(f_zip,fichier,0); if (visu==-1) { printf("Le fichier %s n'existe pas dans %s\n", fichier, fichierZip); if(ajout==REPLACE_ADD) {

zip_strerror(f_zip));

return ZIPZAP_FAILURE; } printf("Le fichier %s a t renomm en %s dans %s\n", fichierFrom, fichierTo, fichierZip); FREE(buf); } } } ptr = NULL; } else { /* sinon on renomme simplement le fichier trouv par zip_name_locate la position visu */ if(zip_rename(f_zip,visu,fichierTo) == -1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; } printf("Le fichier %s a t renomm en %s dans %s\n", fichierFrom, fichierTo, fichierZip); }

/* lecture termine, fermeture de l'archive */ zip_close(f_zip); f_zip = NULL; return ZIPZAP_SUCCESS;

} 2.4. Remplacer un fichier d'une archive zip 2.4.1. Algorithme Ouvrir l'archive (Fonction zip_open). Rechercher le fichier dans l'archive (Fonction zip_name_locate). Si le fichier n'existe pas et si on a demand de l'ajouter dans ce cas-l ajouter le fichier (Fonction zip_add). Sinon le remplacer (Fonction zip_replace). Fermer l'archive (Fonction zip_close).

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 48

/* nouveau document dans le fichier zip : le fichier n'y est pas */ /* c'est l qu'on fixe le nom qu'aura le nouveau document dans le fichier zip */ if(zip_add(f_zip,fichier,n_zip) == -1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; zip_source_free(n_zip); n_zip = NULL; return ZIPZAP_FAILURE; } printf("Le fichier %s a t ajout dans %s\n", fichier, fichierZip); } else if(ajout==REPLACE_NOT_ADD) { printf("Le fichier %s n'a pas t ajout ou remplac dans %s\n", fichier, fichierZip);

zip_name_locate). Si c'est un dossier pour chaque lment du dossier, l'extraire (Fonction extraireFichier -> Fonctions zip_stat, zip_fopen, zip_fread, zip_fclose). Sinon l'extraire (Fonction extraireFichier -> Fonctions zip_stat, zip_fopen, zip_fread, zip_fclose). Fermer l'archive (Fonction zip_close). 2.5.2. Code source Voir code source en ligne : Lien 127 2.6. Dcompresser une archive zip 2.6.1. Algorithme Ouvrir l'archive (Fonction zip_open). Compter le nombre d'lments dans l'archive (Fonction zip_get_num_files). Extraire chaque lment (Fonction extraireFichier -> Fonctions zip_stat, zip_fopen, zip_fread, zip_fclose). Fermer l'archive (Fonction zip_close). 2.6.2. Code source Dcompresser une archive static int decompresserFichierZip(const char* fichierZip, const char* repSortie, const char* motDePasse)
{ /* Code d'origine : */ /* http://www.siteduzero.com/forum-83-372372p1-c-zip-et-unzip.html#r3519929 */ /* http://forum.ubuntu-fr.org/viewtopic.php? pid=2596893#p2596893 Visit le 02/01/2011 */ /* modifi pour ajouter la gestion des erreurs et quelques fonctionnalits */ int err=0; struct zip *f_zip=NULL;

} else { printf("Erreur d'utilisation de la fonction %s\n", __FUNCTION__);

} } else { /* modification d'un document dans le fichier zip : le fichier est dj dedans */ /* notre document remplace le document qui se trouve l'emplacement visu */ if(zip_replace(f_zip,visu,n_zip) == -1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; zip_source_free(n_zip); n_zip = NULL; return ZIPZAP_FAILURE; } printf("Le fichier %s a t remplac dans %s\n", fichier, fichierZip); } zip_close(f_zip); f_zip = NULL; zip_source_free(n_zip); n_zip = NULL; return ZIPZAP_SUCCESS;

} 2.5. Extraire un fichier/dossier d'une archive zip 2.5.1. Algorithme Ouvrir l'archive (Fonction zip_open). Rechercher le fichier/dossier dans l'archive (Fonction

/* 1. Ouverture de l'archive */ f_zip = zip_open(fichierZip, ZIP_CHECKCONS, &err); /* s'il y a des erreurs */ if(err != ZIP_ER_OK) { zip_error_to_str(buf_erreur, sizeof buf_erreur, err, errno); printf("Error %d : %s\n",err, buf_erreur); return ZIPZAP_FAILURE; } /* si le fichier zip n'est pas ouvert */ if(f_zip==NULL) { printf("Erreur l'ouverture du fichier %s\n", fichierZip); return ZIPZAP_FAILURE; } /* 2. on rcupre le nombre de fichiers dans l'archive zip */ int count = zip_get_num_files(f_zip); if(count==-1)

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 49

{ printf("Erreur l'ouverture du fichier %s\n", fichierZip); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; } printf("Nombre de fichiers dans l'archive : %d\n", count); int i; /* 3. on lit tous les fichiers */ for(i=0; i<count; i++) { /* on lance la fonction qui extraira le fichier en position "i" dans l'archive Zip */ if(extraireFichier(i, f_zip, repSortie, motDePasse)==ZIPZAP_FAILURE) { printf("Erreur l'extraction du fichier %s\n", zip_get_name(f_zip, i, ZIP_FL_UNCHANGED)); zip_close(f_zip); f_zip = NULL; return ZIPZAP_FAILURE; } } /* lecture termine, fermeture de l'archive */ zip_close(f_zip); f_zip = NULL;

"fichierZipEnSortie" suivant le mode "modeZip" avec les fichiers contenus dans *arg[]. * * \param fichierZipEnSortie Le nom de l'archive zip crer en sortie. * \param modeZip Mode de cration de l'archive ADD ; CREATE ou EXIST. (voir les dfinitions). * \param argc Nombre de fichiers reus par le programme et transmis la fonction. * \param argv Chanes de caractres reues par le programme et transmises la fonction. Ces chanes contiennent les fichiers/rpertoires ajouter. * * \return ZIPZAP_SUCCESS : Retour OK ; ZIPZAP_FAILURE : Retour d'erreur. */ static int creerFichierZip(const char* fichierZipEnSortie, int modeZip, int argc, char *arg[]) { struct zip *f_zip=NULL; struct zip_source *doc = NULL; int err = 0; /* Suivant le mode choisi pour la cration de l'archive on dfinit les flags */ if(modeZip==CREATE) { /* on supprime l'archive pour en crer une nouvelle */ remove(fichierZipEnSortie); f_zip=zip_open(fichierZipEnSortie, ZIP_CREATE, &err); /* on cre l'archive */ } else if(modeZip==EXIST) { f_zip=zip_open(fichierZipEnSortie, ZIP_EXCL|ZIP_CREATE, &err); /* on ne cre pas l'archive si elle existe, Jacques THERY2011-1206T12:28:12.39Vous ne pensez pas que la phrase qui suit n'a pas d'utilit ?mais si elle n'existe pas on la cre */ } else if(modeZip==ADD) { f_zip=zip_open(fichierZipEnSortie, ZIP_CREATE, &err); /* on cre l'archive si elle n'existe pas */ } else { printf("Erreur du choix du mode\n"); usage(arg[0]); return ZIPZAP_FAILURE; } /* s'il y a des erreurs */ if(err != ZIP_ER_OK) { zip_error_to_str(buf_erreur, sizeof buf_erreur, err, errno); printf("Error %d : %s\n",err, buf_erreur); return ZIPZAP_FAILURE; } /* si le fichier zip n'est pas ouvert */ if(f_zip==NULL) { printf("Erreur l'ouverture du fichier %s\n", fichierZipEnSortie); return ZIPZAP_FAILURE;

return ZIPZAP_SUCCESS;

} 2.7. Crer une archive zip 2.7.1. Algorithme Crer l'archive suivant le mode choisi (Fonction zip_open). Vrifier que le fichier/dossier n'est pas dj prsent dans l'archive (Fonction verfiPresenceFichier). Si on ajoute un dossier on l'ajoute l'archive (Fonction zip_add_dir), on ajoute tous ses lments dans l'archive (Fonction ajouteDossier ->Fonctions zip_source_file, zip_add_dir, zip_add). Sinon on ajoute le fichier l'archive (Fonctions zip_source_file, zip_add). Fermer l'archive (Fonction zip_close). 2.7.2. Code source Crer une archive /* Ajoute les fichiers tels qu'ils sont envoys dans la ligne de commande */
/* Pose problme avec les fichiers du style "../../fichiers" */ /** * \fn static int creerFichierZip(const char* fichierZipEnSortie, int modeZip, int argc, char *arg[]) * \brief Crer l'archive zip

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 50

} /* on positionne i 3 car on a dans le tableau : "0. Le nom du programme" "1. Le mode de cration" "2. Le nom de l'archive" */ int i = 3; for(; i<argc; i++) { if(verifPresenceFichier(f_zip, arg[i])==ZIPZAP_FAILURE) { printf("Erreur lors de l'ajout du fichier/dossier \"%s\" l'archive %s\n", arg[i], fichierZipEnSortie); zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_FAILURE; } #if defined(__POSIX_VISIBLE) || defined(_POSIX_C_SOURCE) /* on teste si le fichier demand est un dossier ou non */ struct stat f_stat; if(lstat(arg[i], &f_stat) != -1) { if(S_ISDIR(f_stat.st_mode)) { /* Si cela en est un, on l'ajoute l'archive */ if(zip_add_dir(f_zip, arg[i]) == -1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_FAILURE; } /* Puis on ajoute tous les fichiers du dossier et de ses sous-dossiers */ if(ajouteDossier(arg[i], f_zip)==ZIPZAP_FAILURE) { printf("Erreur l'ajout du dossier %s\n", arg[i]); zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_FAILURE; } } else /* Sinon on le traite comme un fichier normal */ { /* que l'on rcupre dans un zip_source */ if((doc=zip_source_file(f_zip,arg[i

],(off_t)0,(off_t)0))==NULL) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_FAILURE; } /* pour l'inclure dans l'archive */ if(zip_add(f_zip, arg[i], doc)==-1) { printf("%s\n", zip_strerror(f_zip)); zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_FAILURE; }

} } else { printf("Le fichier %s n'existe pas\n", arg[i]); zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_FAILURE; } #endif /* posix */ /* TODO : la mme chose pour Windows */ } zip_close(f_zip); f_zip = NULL; zip_source_free(doc); doc = NULL; return ZIPZAP_SUCCESS;

} 3. Conclusion Les codes sources prsents ci-dessus montrent comment il est facile avec la LibZip de raliser les oprations classiques sur des archives. Je vous recommande l'utilisation de cette bibliothque trs puissante et trs simple d'utilisation. Elle est d'ailleurs utilise par de nombreux gros projets et ce n'est sans doute pas pour rien. Vous pouvez tlcharger le code source complet et la Makefile dans cette archive zip cre avec les exemples du code. Tlcharger ZipZap : Lien 128. Retrouvez l'article de Loc Bartoletti en ligne : Lien 129.

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 51

Visual Basic
Les derniers tutoriels et articles
Le dbogage sous Visual Basic 6 & Visual Basic pour Application (1re partie) Tout ce que vous devez savoir sur le dbogage et la gestion des erreurs sous Visual Basic 6.
1. Introduction cration. L'absence de typage tant une source importante d'erreurs, La lecture du forum Visual Basic laisse penser que il est recommand d'effectuer le typage de chaque variable beaucoup d'utilisateurs ne connaissent pas ou mal certaines (il est mme recommand de pratiquer un typage fort => possibilits de l'IDE VB6 concernant le traitement des non-utilisation du type Variant). erreurs ni l'ventail des possibilits offertes pour le dbogage : il m'a donc sembl utile de rdiger ce tutoriel Option Explicit sommaire concernant les spcificits de Visual Basic 6 dans ce domaine. '- Exemples de ce qu'il faut faire et NE PAS Pour tout complment d'information, consultez la MSDN : Lien 130. 2. Les outils L'IDE Visual Basic est riche d'outils d'assistance qui permettent notamment l'aide l'criture, son contrle, la gestion personnalise du mode runtime ou la possibilit d'interactions, etc. 2.1. Les outils d'aide l'criture Menu Outils/Options (Alt OT) > Onglet diteur
faire : Dim MyVar ' INCORRECT: MyVar est de type Variant Dim MyVar As String ' CORRECT: Typage fort, MyVar est dfinie comme type String Dim MyVar1, MyVar2 As Integer ' INCORRECT: seule MyVar2 est type comme Integer, MyVar1 est de type Variant Dim MyVar1 As Integer, MyVar2 As Integer ' CORRECT: MyVar1 ET MyVar2 sont correctement types comme Integer

Le dbogage sous Visual Basic 6 & Visual Basic pour Application (1re partie)

Vous devrez ajouter manuellement Option Explicit dans tous les modules de votre projet, crs ou imports L'IDE Visual Basic dispose avec la technologie AVANT d'avoir coch cette case ! (Form, Module, Module Intellisense de diffrents outils d'aide l'criture (Listes de classe, etc.) automatiques , Info-bulles, des Infos-express ). Outre le fait de limiter le risque d'erreurs de syntaxe, ils ont pour proprit de devenir non fonctionnels s'il existe une erreur 2.1.3. Autocompltion (dfaut de typage, de paramtres, etc.) ce qui permet donc L'autocompltion (liste automatique des membres) fournit indirectement de signaler une erreur. au dveloppeur dans une zone de liste les proprits, mthodes, etc. du modle objet slectionn (racine) ce qui permet de rduire le temps de dveloppement et assure un code syntaxiquement correct (caractre d'activation . ).

2.1.4. Info-express automatique Cocher toutes les options Paramtres du code. 2.1.1. Vrification automatique de la syntaxe La vrification automatique de la syntaxe permet de vrifier la syntaxe chaque ligne de code. 2.1.2. Dclaration des variables obligatoire Cocher systmatiquement l' Option Explicit force dclarer chaque variable en ajoutant une instruction Option Explicit en tte de module au moment de sa
Numro 37 Dcembre - Janvier 2011/2012 Page 52

La zone d'Info-express (Ctrl+Maj+I/Ctrl+I) est complmentaire de l'autocompltion ; elle fournit la syntaxe de fonction, d'instruction, de mthode et des paramtres lis en indiquant le paramtre en cours d'dition.

Developpez Magazine est une publication de developpez.com

2.1.5. Info-bulle automatique L'outil Info-bulle fonctionne en mode arrt ; il permet d'afficher (dans la limite des 72 premiers caractres - nom de variable inclus) la valeur en cours de l'expression se situant sous le curseur.

visualiser le rsultat de partie de code en cours d'excution en mode runtime (instruction Debug.Print) :

lancer une procdure particulire quand le code actif s'excute et se trouve en mode arrt.

L'utilisation de la fentre d'excution est utilisable en mode arrt lors d'une excution en mode runtime ou Le paramtrage des options de l'IDE va conditionner le directement en mode conception. comportement des gestionnaires d'erreurs notamment l'activation ou la dsactivation des gestionnaires. La fentre des variables locales (VB:Alt+I+L - VBA: Alt+A+V) 2.2. Le paramtrage des Options de gestion d'erreurs

Elle permet de visualiser ou modifier les variables en cours. La capacit d'affichage d'une variable est fonction de la largeur maximum d'affichage de la fentre. Trois possibilits sont prsentes sur le comportement face une erreur : arrt sur toutes les erreurs : dsactive tous les gestionnaires d'erreurs et marque un arrt sur toutes les erreurs ; arrt sur les erreurs non gres : active les gestionnaires d'erreurs et marque un arrt uniquement sur les erreurs non gres ; arrt dans les modules de classe : se distingue de l'option prcdente marquant un point d'arrt dans le module de classe au lieu du module d'appel de la classe. 2.3. Les outils ddis au dbogage La fentre d'excution (Ctrl+G) permet les actions suivantes : excuter directement des instructions (pour une utilisation d'instructions multiples, utilisez une seule ligne et le sparateur d'instructions : ) : Pour modifier la valeur d'une variable dans la fentre Variables locales : double-cliquer sur la valeur concerne afin de l'diter. La fentre Espions Permet de suivre la valeur de retour de proprits, de fonctions, etc. ou de dterminer une expression dont la valeur stoppera l'excution du code en mode runtime. L'affichage des variables est limit aux 250 premiers caractres. Les menus en rapport : Ajouter un espion - Modifier un espion

gnrera la fentre suivante en cours d'excution...

et un arrt sur la ligne suivante.


Numro 37 Dcembre - Janvier 2011/2012 Page 53

Developpez Magazine est une publication de developpez.com

Il peut tre fastidieux d'ajouter une gestion d'erreur de nombreuses procdures ; cet outil rpond ce problme en suivant un modle prdfini en fonction de diffrentes variables. Les champs disponibles pour dfinir le modle sont : Il est possible d'ajouter un espion en effectuant un Glisser Dposer de la variable pralablement slectionne dans la fentre Espions. Pile des Appels (Ctrl+L) Cette fentre affiche la liste des procdures en cours d'excution pendant le mode arrt et ventuellement affiche le code de la procdure slectionne. Cet outil est utile pour analyser les procdures rcursives ou pour retrouver un gestionnaire d'erreur parent. Variables {PROJECT_ FILENAME} {PROJECT_ NAME} {MODULE_ TYPE} {MODULE_ FILENAME} {MODULE_ NAME} Description quivalence

Nom du fichier VBProject.FileName de projet Nom du projet VBProject.Name Type module de VBComponent.Type

Nom de fichier VBComponent.FileN du module ame Nom module du VBComponent.Name

{FUNCTION_ Nom du type ex : Long, Boolean, RETURN_TYPE_ de retour de la etc. NAME} procdure Prfixe (1re {FUNCTION_ lettre) du type RETURN_TYPE_ de retour de la PREFIX} procdure 2.4. Les utilitaires ddis Les outils fournis par MZ-Tools : Lien 131. L'addin MZ-Tools met disposition intressants pour la gestion d'erreurs : Le numroteur de lignes Cet outil permet d'automatiser l'indexation des lignes de code soit au niveau procdure ; soit au niveau d'un module ; soit au niveau de tout le projet. deux outils {PROCEDURE_ TYPE} {PROCEDURE_ NAME} Type de procdure Nom de procdure la la Member.Type Member.Name

{PROCEDURE_ BODY}

Corps de procdure (reprsente le code de la Lines procdure aprs le premier bloc de dclaration)

Il est possible de dterminer dans le paramtrage de l'addin, l'incrmentation des Soit, par exemple, le modle suivant : numros de lignes. La numrotation au niveau projet ou module est possible en utilisant le menu contextuel (clic droit) aprs slection du contexte dans l'Explorateur de projet.

Le modle est dfinir dans l'interface des Options MZ-Tools (onglet Gestionnaire d'erreur).

On Error GoTo {PROCEDURE_NAME}_Error {PROCEDURE_BODY} On Error GoTo 0 Exit {PROCEDURE_TYPE} {PROCEDURE_NAME}_Error: MsgBox "Error " &amp; Err.Number &amp; " (" &amp; Err.Description &amp; ") in procedure {PROCEDURE_NAME} of {MODULE_TYPE} {MODULE_NAME}"

qui gnrera le rsultat suivant : Ajouter une procdure d'erreur

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 54

prfrer Err.Raise. IsError Expression Renvoie Vrai si expression est une valeur d'erreur. CVErr Function Permet de crer des erreurs dfinies par l'utilisateur dans N. B. Les lignes ajoutes sont marques d'un signet dans la des procdures cres par l'utilisateur (voir galement la constante vbObjectError). marge. L'outil Signet permet de signaler une ligne Err Object La porte de l'objet Err est limite la procdure laquelle en ajoutant un tag dans la marge. est associ un gestionnaire d'erreurs On Error.... 3. Gestion des erreurs par le code 3.1. Les instructions de gestion On Error ... Instruction L'instruction On Error supporte plusieurs syntaxes : On Error Goto Etiquette : permet de rerouter l'excution vers un bloc de gestion de l'exception leve, plac en gnral immdiatement aprs une instruction Exit Sub/Exit Function/Exit Property ; On Error Goto 0 : supprime toute gestion d'erreur pralablement installe ; On Error Resume Next : permet de gnrer un gestionnaire d'erreurs passif : le contrle de l'excution est transmis directement la ligne suivante sans qu'aucun traitement ne soit effectu. Utiliser imprativement une variable intermdiaire si une instruction de test doit tre effectue sous le contrle d'une instruction On Error Resume Next.
' exemple : On Error Resume Next ret= Val(myString) If ret<>0 Then '.../... endif ' et non pas : If Val(myString) Then

Proprits Description Number Source

Type

Lect/Ecr. Description Description d'un objet Err ID Nom de l'objet (module) ou de l'application l'origine de l'erreur. Id du contexte d'aide associ. Chemin vers fichier d'aide un

String RW Long RW

String RW

HelpContext HelpFile LastDllError Mthodes Clear Raise

String RW String RW Long R

Dernier code d'erreur produit par un appel DLL

Description Rinitialise l'objet Err Gnre une erreur

ERL Function Retourne le n de ligne (Long) sur laquelle s'est produite la dernire erreur leve (porte procdure). Debug Object Mthodes Print Description Retourne la valeur d'une expression dans la fentre d'excution quand le code s'excute en mode runtime Arrte l'excution en mode runtime sur la ligne concerne quand la valeur de l'expression est fausse (ignore en mode compil)

La porte d'une instruction On Error ... est limite la procdure courante. Resume Instruction Provoque une rinitialisation de l'objet Err (quivalent Err.Clear) et la poursuite de l'excution aprs la gestion de l'exception : Resume : l'excution reprend la ligne o l'interruption a eu lieu ; Resume Next : l'excution reprend la ligne suivante en ignorant la ligne ayant lev l'exception ; Resume Line : l'excution reprend une ligne spcifique en fonction d'un numro de ligne ou d'une tiquette. Error Instruction Assure la compatibilit avec les versions prcdentes ; Assert

3.2. Crer un gestionnaire d'erreurs La cration d'un gestionnaire d'erreurs actif consiste laborer une gestion au cas par cas afin de rpondre toutes les erreurs susceptibles de se produire. Illustration par l'exemple...
Option Explicit ' Ncessite que l'option de l'Ide Arrt sur les erreurs non gres soit active Private Sub Form_Load() Dim strErrnum As String

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 55

Dim intErr As Integer Dim intReturn As Integer On Error GoTo Exemple1_Error 10 intErr = 3 / intReturn 20 intErr = 10 ^ 31 capacit 30 40 50 strErrnum = 71 intErr = Val(strErrnum) Err.Raise Number:=intErr ' (div 0) ' dpassement de

3.4. Gestionnaire d'erreurs centralis tablir un gestionnaire centralis consiste raliser une ou plusieurs procdures spcifiques de traitement des exceptions qu'il suffira ensuite d'appeler lors de l'interception de l'erreur. Comme pour le choix du mode de sortie, c'est le contexte qui dterminera le choix entre gestionnaire en ligne et/ou gestionnaire centralis : un gestionnaire centralis prsente l'avantage de ne pas multiplier les actions similaires, en consquence, sa modification s'en trouve simplifie puisque rpercute sur l'ensemble de l'application ; c'est mme un investissement si le gestionnaire est rutilisable dans des projets diffrents ; un gestionnaire en ligne est, au contraire, destin aux cas particuliers. L'un comme l'autre peuvent ventuellement dpendre d'un fichier de ressources ddi qui sera aisment traductible (ex. vb6xx.dll pour Visual Basic). 4. Spcificits en mode compil Uniquement Visual Basic. 4.1. Les options et paramtres de compilation > Proprits du projet (Alt PP) > Onglet Compilation > Options avances Conditionnent le comportement de l'excutable compil face une exception. Si elles permettent d'optimiser la vitesse d'excution en supprimant des contrles internes, leur utilisation risque galement de crer de graves dysfonctionnements pour peu que la gestion d'erreurs ne soit pas des plus strictes. Nophytes, s'abstenir !! 4.2. Dbogage symbolique > Proprits du projet (Alt PP) > Onglet Compilation Gnrer les informations de dbogage symbolique : cette option permet de gnrer automatiquement la compilation un fichier pdb utilisable notamment par VC++ afin de dboguer l'excutable pralablement compil en mode natif. Ces informations sont gnres chaque fois qu'un fichier OBJ est cr par le compilateur ; elles contiennent les informations de type, de prototype des fonctions destines au dbogueur. 4.3. Remarques Le dploiement et l'installation d'un excutable ncessitent de respecter quelques rgles incontournables pour viter certaines erreurs lies l'installation. Lorsque qu'un excutable inclut des dpendances ActiveX, il importe de conserver les fichiers dep associs ainsi que les dpendances avec les sources, car ils dcrivent les ventuelles
Numro 37 Dcembre - Janvier 2011/2012 Page 56

' disque non prt

Exit Sub Exemple1_Error: Select Case Err.Number Case 6 Resume Next ' Erreur non corrige : Passer la ligne suivante Case 11 intReturn = 1 ' Correction de l'erreur ... MsgBox "=> La valeur 0 va tre remplace par la valeur 1" Resume ' Reprendre l'excution Case 68 If MsgBox(Err.Description, vbRetryCancel) = vbRetry Then Resume ' Excuter nouveau ou annuler ? Case Else ' Signaler toute autre erreur et sortie du code de la procdure incrimine MsgBox Err.Description ,, "Form_Load (Line " & Erl & ")" End Select End Sub

3.3. Le choix de l'externalisation Le choix du mode de sortie de l'erreur dpend du contexte : la bote de dialogue (Msgbox) : pour interagir avec l'utilisateur final ou permettre d'entrer en mode pas pas pendant la mise au point ; la fentre d'excution (Debug.Print) : permet de signaler une erreur sans interrompre le droulement du programme ; le fichier journal : il a le mrite de ne pas tre phmre, de transmettre des informations non dformes et de pouvoir tre trait automatiquement - rserver en production ou dans le cadre de mise au point suite erreur fatale (dans ce cadre, l'criture doit tre optimise) ; le presse-papier : ce peut tre une solution intermdiaire entre la fentre de Debug et le fichier log pour la phase de mise au point ; la console : peut ventuellement prsenter un intrt lorsqu'une quantit importante d'information doit tre prsente l'utilisateur final ; l'imprimante : accessoirement, peut tre utilise pour analyser la gnration de rsultats errons.

Developpez Magazine est une publication de developpez.com

dpendances imbriques qu'il sera ultrieurement difficile d'identifier sans eux. Il est essentiel de raliser (et de conserver avec les sources) un Setup d'installation car il n'est pas acquis que la version du systme d'exploitation sur lequel l'installation s'effectuera distribue les dpendances du systme sur lequel a t compil l'excutable (par exemple, Vista/Seven ne distribue pas une partie des DLL/OCX distribues sous Win2000/XP). Rappelez l'utilisateur qu'il est essentiel avant l'installation de fermer les autres programmes et d'effectuer l'installation en mode administrateur. Il est ncessaire de tester l'excutable sous les diffrents OS disponibles afin de connatre les ventuelles contraintes d'installation ou incompatibilits (par exemple, installation en mode compatible sous Seven 32 ou 64 bits).

galement indispensable car, si un code s'excute sans problme jusqu' son terme ou a contrario permet de mettre en vidence les erreurs, rien ne prouve qu'il s'excutera correctement en condition extrme (charge CPU, saturation mmoire, etc.). Outre des outils professionnels ddis cet usage, il est possible d'excuter un test de charge simple qui consiste appeler conscutivement une mme routine (ou un ensemble de routines) un grand nombre de fois - on observera en parallle l'utilisation des ressources. Exemple :
Dim x As Long, ret As Long Const k As Long = 1000 On Error Goto cath_Err For x=1 To k ret = myFunction() Next cath_Err: Debug.Print ret If x<=k Then Debug.Print "Error at " & k & " cycles"

L'Observateur d'vnements de Windows et les journaux lis peuvent tre une source d'information complmentaire sur les erreurs. 5. Le dbogage 5.1. Mise au point d'un programme 5.1.1. L'excution en mode runtime

Un second test simple consiste renouveler plusieurs fois la routine prcdente et comparer le rsultat final retourn chaque test.

Tout contrle d'un excutable commence par une 5.1.3. Erreur inattendue excution en mode runtime... Personne n'imaginerait compiler directement un C'est l'erreur qui se produit lors d'une nime excution, voire mme alatoirement sans qu'on puisse de premier excutable et le distribuer sans cette tape intermdiaire. abord en identifier l'origine. L'IDE VB6 permet d'excuter du code en mode runtime tout en permettant d'intervenir sur celui-ci lors de son On pourra tenter d'identifier si l'environnement pose problme - il faudra dans ce cadre : excution ds qu'il entre en mode arrt. travailler avec un environnement restreint Cette proprit essentielle permet : (fermeture de tous les programmes, dsactivation des ventuels complments, etc.) ; la modification du code existant ; si ncessaire, utiliser une session de l'OS en mode l'ajout de lignes d'instructions ; sans chec ; l'ajout ou la modification de dclarations ; accessoirement, tester si l'erreur se reproduit sous la modification de valeur de variables ; diffrents systmes d'exploitation. le saut d'instructions, de procdures, etc. La runion de ces possibilits laisse imaginer la puissance 5.2. Excuter le code offerte pour la mise au point. Il est possible dans le mme temps, d'excuter du code en parallle depuis la fentre d'Excution => l'excution des instructions, procdures ou fonctions se rpercutera sur le code global en mode arrt. L'usage de cette technique a toutefois des limites : il faut l'viter dans les procdures de rappels au risque d'un crash de l'IDE ; il n'est pas question d'effectuer des modifications importantes dans ce contexte car la stabilit de l'IDE est en relation avec le cumul des erreurs interceptes, leur gravit et les modifications opres conscutivement. 5.1.2. Tester la stabilit Il existe deux modes d'excution : le mode Pas pas (F8) qui permet d'excuter le programme ligne ligne, le mode normal (F5) qui excute le programme d'une traite jusqu' ce qu'une erreur ou un point d'arrt soit ventuellement rencontr. Les deux modes peuvent tre utiliss conscutivement au sein d'une mme session. Une fois en mode arrt, il est possible d'excuter le code par tranche en utilisant : mode Pas pas principal (Maj+F8) ; mode Pas pas sortant (Ctrl+Maj+F8) ; Excuter jusqu'au curseur (Ctrl+F8).

Tester la stabilit (la robustesse) d'un excutable est Arrter l'excution sur une ligne particulire :
Numro 37 Dcembre - Janvier 2011/2012 Page 57

Developpez Magazine est une publication de developpez.com

le point d'arrt (clic dans la marge de la ligne ligne) concerne) : il permet de stopper l'excution juste avant l'excution d'une ligne prcise, dposer le contrle tester sur la feuille du projet de test => la partie Concepteur du code l'instruction Stop est identique au point d'arrt, s'excute... en fonction d'un test dans le code (cf. l'instruction excutez le projet de test en mode Runtime (F5) Debug.Assert), => la partie du code Utilisateur s'excute... arrts conditionnels en fonction d'un Espion (cf. Outils). L'ordre d'ouverture des projets dans le groupe dtermine le L'instruction Stop ne doit pas apparatre dans un projet qui s'excutera en mode runtime. excutable compil. 5.3.2. DLL ActiveX => Durant la phase de mise au point, il peut tre Pratiquer comme pour un Control en utilisant un groupe de intressant d'utiliser les arguments de compilation projets, mais en ajoutant une rfrence (Alt PR) au projet conditionnelle dans le projet de test. (VB: Alt PP > onglet Crer - VBA: Utiliser des constantes => Une entre Nom_du_projet (Chemin d'accs : conditionnelles #Const ... ) Chemin_du_projet.vbp) a t ajoute la liste des afin de grer automatiquement la non-compilation des rfrences disponibles. instructions d'aide au dbogage (Stop, Msgbox, Debug.Print, etc.). Il existe toutefois une autre solution l'utilisation d'un exemple VB : Arguments de compilation conditionnelle > NOCOMPILATION=1 exemple VBA : #Const NOCOMPILATION=1
#If NOCOMPILATION Then Stop #End If

groupe de projets : ajouter un module standard au projet tester ; ajouter une procdure de test dans laquelle est initialise la classe tester ; excuter la procdure en l'appelant depuis la fentre d'Excution. 5.3.3. AddIn

5.3. Cas particuliers des excutions d'instances

L'excution de l'addin est lance en mode normal depuis le projet de l'addin (F5) : l'instance en cours se met en attente Uniquement Visual Basic de connexion Si l'excution en mode runtime d'un excutable standard => la connexion l'instance en cours s'effectuera en (Exe) ne pose pas de problmes particuliers, il est moins ouvrant une instance de l'application lie. vident d'excuter le code des DLL ActiveX, controls et Afin de ne pas avoir grer l'installation de l'addin Addins qui ne peut tre excut directement dans l'IDE puisqu'une l'ouverture de l'application cliente : => Dfinir le mode de dmarrage de l'addin instance doit tre cre. (Comportement Initial) Startup . Leur dbogage ncessite donc quelques artifices... Utilisez le paramtrage : (Outils/Options> Onglet 6. Conclusion Gnral) : Arrt sur les erreurs non gres ou Arrt La gestion des erreurs est un vaste sujet, incontournable dans les modules de classe . pour toute application, et les outils de mise au point sous VB6 sont nombreux. 5.3.1. Control ActiveX En faire le tour ncessiterait la rdaction d'un ouvrage- les lecteurs dsireux d'approfondir le sujet peuvent toutefois Crer un nouveau projet Exe Standard (Ctrl N) ; trouver plus d'information en consultant la MSDN. celui-ci servira de projet support pour le test. Crer un groupe de projet en ajoutant le projet du Note aux utilisateurs VB : il existe galement un projet de contrle tester (Alt FA) => les contrles sont dmo Errors.vbp illustrant la gestion d'erreurs dans le disponibles dans la Boite Outils du projet de rpertoire de la MSDN test. (path_to_MSDN\MSDN98\98VSa\1036\SAMPLES\VB98 \Errors\ERRORS.VBP). Aprs avoir plac si ncessaire, un point d'arrt l'endroit o commencer l'excution en mode Pas pas (ligne par Retrouvez l'article de DarkVader en ligne : Lien 132

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 58

Dveloppement Web
Les dernires news Pourquoi gnrer le code JavaScript est une fausse bonne ide.
Bonjour. En lisant le forum et en rpondant aux questions, je me suis dit qu'une petite mise au point semblait ncessaire. Souvent, dans nos dveloppements, nous avons un serveur dynamique PHP, ASP, JAVA, C#, Ruby, etc. Il est trs facile et tentant de gnrer les divers lments dont on a besoin directement avec le langage de ce serveur. C'est simple, a apporte des facilits mais ce n'est pas toujours aussi efficace qu'on le pense. Lorsqu'on cre le code HTML de la page, on place au fur et mesure le code JavaScript dont on a besoin en incluant directement dans celui-ci, tout comme pour le HTML, les valeurs des variables du langage hte.
<?PHP $Message = '"Hello World!"'; print '<script type="text/javascript">'; print ' function confirm(message) { ..... }'; print '</script>'; print "<a href='#' onClick = 'return confirm(". $Message.");'>Test</a>"; ?>

variables. Il le parse et cre le DOM correspondant. Il donne l'interprteur JavaScript la source JavaScript qu'il contient. 4. L'interprteur JavaScript compile le code (partiellement) et le relie au DOM. L'interprteur ne peut mettre le code compil en cache car il est embarqu dans une source qui n'est pas cache. 5. La page est disponible pour l'utilisateur. 6. L'utilisateur active le code JavaScript par une action (un click dans l'exemple). 7. L'interprteur JavaScript compile si besoin le code non compil et l'excute. Si l'action est encore invoque, elle est juste excute. Si le client au cours de son activit revient sur la mme page, on repart du dbut. Le code est rgnr, retransfr, rinterprt par le moteur HTML, recompil pour le JavaScript et ce chaque fois qu'on invoque lURL. Peut-on gagner en efficacit ? La rponse est oui videmment, en utilisant le protocole et la capacit du navigateur. La premire chose faire est de mettre le code JavaScript dans des fichiers spars
function confirm(message) { ..... }

et inclure le fichier dans la page. Reste l'utilisation des variables du langage hte dans JavaScript. J'ai donn une solution (Lien 133), avec celle-ci il n'est plus du tout ncessaire de placer les valeurs des variables du langage hte dans JavaScript.

Parmi les avantages, le regroupement de tout le code concernant un point prcis. Ici la confirmation du message. Dans le langage hte, nous avons la dfinition de la valeur, la gnration du code JavaScript qui l'utilise et le code HTML qui permettra de l'invoquer.

Autre avantage, on peut trs facilement ne produire que le code JavaScript ncessaire ce besoin. Si la fonction En quoi une telle solution peut-elle amliorer l'efficacit ? JavaScript utiliser dpend d'une proprit dans le Reprenons le droulement des oprations. 1. Le client invoque une URL langage hte, un simple if permet de produire la bonne 2. Le serveur droule son code et produit fonction. dynamiquement une source HTML. 3. Le client reoit cette source. Bref, je ne vais pas numrer les avantages et encore Il ne peut pas la mettre en cache car elle moins les inconvnients. est dynamique et contient des donnes variables. Mon propos est juste de montrer pourquoi cette ide est Il la parse et cre le DOM correspondant. une fausse bonne ide. Il charge les fichiers JavaScript lis. Pour cela revenons, au fonctionnement du Web, c'est-dire HTTP. Il met la source JavaScript dans le cache. 1. Le client invoque une URL. 4. L'interprteur JavaScript compile le code 2. Le serveur droule son code et produit (partiellement) et le relie au DOM. dynamiquement une source HTML. L'interprteur met en cache le code 3. Le client reoit cette source. compil. Il ne peut pas le mettre en cache car il est 5. La page est disponible pour l'utilisateur. dynamique et contient des donnes 6. L'utilisateur active le code JavaScript par une
Numro 37 Dcembre - Janvier 2011/2012 Page 59

Developpez Magazine est une publication de developpez.com

print "<a href='#' onClick = 'return confirm" . action (un clic dans l'exemple). 7. L'interprteur JavaScript compile si besoin le $property . "(".$Message.");'>Test</a>"; ?> code non compil et l'excute. Si l'action est encore invoque elle est On a ainsi le code prcis de la fonction que l'on veut dans juste excute. le JavaScript tout en bnficiant du cache du compilateur Si la page est rappele, le fichier JavaScript n'est pas JavaScript et du cache du navigateur. recharg et il n'est pas recompil. Cet aspect des choses peut avoir de gros effets. Du coup diront certains, on se retrouve avec un gros Sur de tout petits JavaScript, a ne se voit quasiment pas. JavaScript qui contient tous les cas alors qu'en gnrant le Mais ce n'est pas le cas lorsqu'ils se multiplient ou si le JavaScript la vole, je peux gnrer la fonction dont j'ai code devient plus gros. besoin Ajoutez les caches rseau dans l'affaire et la diffrence peut devenir norme. <?PHP $Message = '"Hello World!"'; print '<script type="text/javascript">'; print ' function confirm(message) {'; if ($property == 'some value' { print " //ici le code JavaScript dans un cas"; } else { print " //ici le code JavaScript dans l'autre cas"; } print ' }'; print '</script>'; print "<a href='#' onClick = 'return confirm(". $Message.");'>Test</a>"; ?>

Vous avez srement remarqu que certaines applications sur le net sont trs lentes dmarrer la premire fois et bien plus rapides par la suite. Imaginez une telle application dont le serveur est l'autre bout du monde. Tout le code statique, CSS statique, images statiques est mis en cache dans des caches rseau tout au long du parcours (le proxy de l'entreprise fait aussi cela).

Du coup, lorsqu'un autre client vient chercher une de ces ressources et que le rseau la trouve en cache dans l'acheminement de la requte, c'est cette version en cache qui est livre. Ce n'est donc plus simplement juste entre le C'est en fait un faux problme. Il suffit de faire plusieurs client et le serveur qu'on optimise ainsi les transferts mais sur toute la ligne. fichiers JavaScript et d'inclure le bon.
<?PHP $Message = '"Hello World!"'; print '<script type="text/javascript" src="' . $property . '.js">'; print '</script>';

Avec JavaScript, il y a en plus le cache du code compil qui apporte un rel confort l'utilisateur. L'application devient beaucoup plus fluide et ractive. Commentez la news de sekaijin en ligne : Lien 134.

Les blogs Dveloppement Web Le "core" JavaScript s'enrichit de nouvelles mthodes.


C'est une information qui est, il me semble, passe relativement inaperue mais qui est selon moi assez intressante souligner. Le noyau JavaScript, qui tait rest longtemps fig, s'est enrichi avec les dernires versions des navigateurs, de nouvelles mthodes bien utiles. Pour rappel, le noyau JavaScript (aussi appel core JavaScript), par opposition au DOM JavaScript (ou JavaScript ct client) regroupe les objets natifs de JavaScript et surtout, la partie cense tre commune toutes ses variations. Il regroupe en particulier les objets natifs Array et String qui ont vu leur prototype amlior. Il est noter que ces ajouts sont aussi disponibles (sauf mention contraire) dans Internet Explorer depuis la version 9. L'objet Array La mthode every() Cette mthode permet d'appliquer tous les membres du tableau une fonction de rappel afin de savoir si tous les lments du tableau remplissent une condition. Syntaxe
Array.every(callback, thisObjet);

Exemple
function isImpair(nb){ return nb & 1; } alert([1,5,17,89].every(isImpair)); alert([1,5,17,89, 100].every(isImpair));

La mthode filter() Comme son nom l'indique, cette mthode permet de filtrer les lments d'un tableau selon le rsultat renvoy par une fonction de rappel. Syntaxe
Array.filter(callback, thisObjet);

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 60

Exemple
function isInferieurADix(nb){ return nb < 10; } alert([2,5,6,8,10,11].filter(isInferieurADix));

Exemple
function isInferieurADix(nb){ return nb < 10; } alert([10,20,30,40,50].some(isInferieurADix)); alert([5,10,20,30,40,50].some(isInferieurADix));

La mthode forEach() Cette mthode permet d'appliquer un traitement chaque L'objet String lment du tableau. Ces mthodes renvoient la nouvelle chane mais ne modifient pas celle d'origine. Syntaxe La mthode trim() Array.forEach(callback, thisObjet); Supprime tous les caractres d'espacement en dbut et fin de chane. Exemple Syntaxe
var tab = ['a','b','c','d','e'], resultat = '', i = 0; function arrayToString(){ resultat += 'Rang '+i+'\t\tvaleur : '+this[i] +'\n'; i++; } tab.forEach(arrayToString, tab); alert(resultat); String.trim();

Exemple
var str = '\tTest '; var strTrimmed = str.trim(); alert('!'+str+'!\n!'+strTrimmed+'!');

La mthode map() La mthode map() va appliquer chaque lment du Syntaxe tableau le traitement de la fonction de rappel.La mthode map() Syntaxe
Array.map(callback, thisObjet);

La mthode trimRight() Supprime les espacements en fin de chane.

String.trimRight();

Exemple
var str = '\tTest '; var strTrimmed = str.trimRight(); alert('!'+str+'!\n!'+strTrimmed+'!');

Exemple
var tab = ['a','b','c','d','e']; function double(val){ return val + val; } alert(tab.map(double));

La mthode trimLeft() Supprime les espacements en dbut de chane. Attention : tonnamment, cette mthode n'est pas (encore) disponible pour Internet Explorer et Opera...

Syntaxe La mthode some() Similaire la mthode every(), cette mthode va vrifier si au moins un des lments du tableau est valide selon le String.trimLeft(); rsultat renvoy par la fonction de rappel. Exemple Syntaxe
Array.some(callback, thisObjet);

var str = '\tTest '; var strTrimmed = str.trimLeft(); alert('!'+str+'!\n!'+strTrimmed+'!');

noter aussi, pour l'objet Date, l'apparition de la mthode toISOString(). Retrouvez ce billet blog de Bovino en ligne : Lien 135

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 61

Les dernier tutoriels et articles


Un chat en HTML5 avec les websockets Voici un tutoriel permettant de crer un chat grce l'API websocket en HTML5.
1. Compatibilit commencer utiliser les websockets via l'API websockets.

Un chat en HTML5 avec les websockets

Tous les navigateurs modernes proposent un support du Celle-ci nous fournit des fonctions nous permettant de websocket de manire native ou via un plugin. mettre trs facilement en place une communication via les websockets. Voici la liste des navigateurs : Chrome : support natif ; Comment utiliser l'API websockets ? Safari : support natif ; Firefox : support natif ; En JavaScript, il faut d'abord instancier un Opra : support natif mais ncessite de l'activer ; objet Websocket qui prend pour paramtre une URL vers Internet Explorer : utilisation d'un prototype des un serveur websocket. websockets : websockets prototype pour IE 9 (Lien 136). var socket = new
Websocket("ws://localhost:11345/serveur.php");

Pour Firefox Notre connexion est en place, nous allons donc couter son Pour activer les websockets dans Firefox s'ils ne le sont comportement : pas (comme dans la version 4 par exemple), il suffit de se rendre dans la barre d'adresse et taper la commande socket.onopen = function(e){} /*on "coute" pour savoir si la connexion vers le serveur websocket suivante :
about:config s'est bien faite */ socket.onmessage = function(e){} /*on rcupre les messages provenant du serveur websocket */ socket.onclose = function(e){} /*on est inform lors de la fermeture de la connexion vers le serveur*/ socket.onerror = function(e){} /*on traite les cas d'erreur*/

Une page de confirmation apparat, continuez. Dans le champ filtre, tapez la recherche suivante :
network.websocket

Pour envoyer un message (des donnes) vers le serveur Deux options apparatront, il faut alors changer leurs websocket, il faut utiliser l'instruction suivante : valeurs : network.websocket.enabled : true socket.send('mon message') /*'mon_message' peut network.websocket.override-security-block : true tre du JSON mais il conviendra de le stringifier Pour Opera
via JSON.stringify('{"msg": "message type string"}')*/

Dans la barre d'adresse du navigateur, tapez la commande Enfin, l'API propose de pouvoir clturer une connexion vers le serveur websocket via l'instruction suivante : suivante :
opera:config#Enable%20WebSockets socket.close();

Cliquez sur la checkbox afin d'activer les websockets, puis 3. le serveur websocket cliquez sur "Save". Il existe sur le Web de nombreuses solutions pour chaque type de langage : Dans les deux cas, il faudra redmarrer le navigateur. JAVA : jWebSocket (Lien 137) ; Ruby : web-socket-ruby (Lien 138) ; 2. l'API websocket HTML5 Node JS : Socket.IO-node (Lien 139) ; D'aucuns diront que le websocket a une faille de scurit PHP : phpwebsocket (Lien 140). et qu'il ne faut pas l'utiliser en l'tat actuel des choses. C'est vrai, mais il faut se projeter. Les websockets se Il existe galement d'autres solutions mergentes telles positionnent comme les remplaants de l'AJAX. Ils sont que : rapides, il n'y a que les donnes qui transitent (trs peu de kaazing : Lien 141 ; donnes dans le header de la rponse, voire pas du tout) et wakanda : Lien 142. le fonctionnement est robuste en termes de charge. Dans notre cas, nous utiliserons phpwebsocket. Pour Grce l'arrive du HTML5, nous pouvons donc l'utiliser, tlchargez-le et dzippez-le dans le dossier de
Numro 37 Dcembre - Janvier 2011/2012 Page 62

Developpez Magazine est une publication de developpez.com

votre choix. Ensuite nous allons modifier lgrement le fichier server.php (que j'ai renomm serveur.php dans le package tlcharger). Si toutefois vous rencontrez des problmes lors de l'installation des fichiers de phpwebsocket chez vous, n'hsitez pas tlcharger le package du cours o vous trouverez un serveur websocket tout fait (celui utilis dans cet article).
#!/php -q <?php /* >php -q server.php */ ini_set('default_socket_timeout', 10); include_once('WebSocketHandshake.class.php'); error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $master = WebSocket('localhost',11345); /* le host et le port du serveur websocket */ $sockets = array($master); $users = array(); $debug = true; /* * serveur websocket qui tourne en continu */ while(true){ $changed = $sockets; $expect = $sockets; socket_select($changed,$write=NULL, $expect,0,1000000); foreach($changed as $socket){ if($socket==$master){ $client=socket_accept($master); if($client<0){ console("socket_accept() failed"); continue; }else{ socket_set_option($client,SOL_SOCKET, SO_KEEPALIVE, 1) or die('Can not set keepalive'); connect($client); } }else{ $bytes = @socket_recv($socket, $buffer,2048,0); if($bytes==0){ disconnect($socket); } else{ $user = getuserbysocket($socket); if(!$user->handshake){ dohandshake($user,$buffer); } else{ process($user,$buffer); } } } } } /* * fonction pour savoir quel type d'action est demand - dans notre cas, * il n'y en a qu'un mais s"il y avait plusieurs actions sur ce serveur * en plus du chat, nous aurions d'autres cas dans le switch */ function process($from,$msg){ console("< ".$from->label." (".$from->userId.") : \n\t".$msg);

$msg = unwrap($msg); $msg = json_decode($msg,true); switch($msg['action']){ case "ctrl/chat/out" : onCtrlChatOut($from, $msg['msg']); break; default : onActionError($from, $msg); break; } } /* * rcrit les donnes sur le socket ouvert */ function send($to,$msg){ say('> '.$to->label.' ('.$to->userId.") :\n\t". $msg); $msg = wrap($msg); return socket_write($to->socket, $msg,strlen($msg)); } /* * envoi du message (des donnes) chaque utilisateur connect * sur le serveur de socket (et sur le mme socket) */ function broadcast($msg, $excludeUser=''){ say(">> "); global $users; foreach($users as $user){ send($user, $msg); } } /* *initialisation du socket */ function WebSocket($address,$port){ $master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed"); socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed"); socket_bind($master, $address, $port) or die("socket_bind() failed"); socket_listen($master,20) or die("socket_listen() failed"); echo "Server Started : ".date('Y-m-d H:i:s')."\n"; echo "Master socket : ".$master."\n"; echo "Listening on : ".$address." port ". $port."\n\n"; return $master; } /* * lors de la connexion d'un utilisateur sur le serveur, * il est enregistr pour le broadcast des donnes */ function connect($socket){ global $sockets,$users; $user = new User(); $user->id = uniqid(); $user->socket = $socket; array_push($users,$user); array_push($sockets,$socket); console($socket." CONNECTED!"); } /* * dconnexion de tous les utilisateurs */ Numro 37 Dcembre - Janvier 2011/2012 Page 63

Developpez Magazine est une publication de developpez.com

function disconnect($socket){ global $sockets,$users; $found=null; $n=count($users); for($i=0;$i<$n;$i++){ if($users[$i]->socket==$socket){ $found=$i; break; } } if(!is_null($found)){ array_splice($users,$found,1); } $index = array_search($socket,$sockets); socket_close($socket); console($socket." DISCONNECTED!"); if($index>=0){ array_splice($sockets,$index,1); } } /* * fonction de la persistance de la connexion websocket */ function dohandshake($user,$buffer){ console("\nRequesting handshake..."); console($buffer); list($resource,$host,$origin) = getheaders($buffer); console("Handshaking..."); $handshake = WebSocketHandshake($buffer); socket_write($user->socket, $handshake,strlen($handshake)); $user->handshake=true; console($handshake); console("Done handshaking..."); return true; } function getheaders($req){ $r=$h=$o=null; if(preg_match("/GET (.*) HTTP/" ,$req, $match)){ $r=$match[1]; } if(preg_match("/Host: (.*)\r\n/" ,$req, $match)){ $h=$match[1]; } if(preg_match("/Origin: (.*)\r\n/",$req, $match)){ $o=$match[1]; } return array($r,$h,$o); } /* * identification des utilisateurs dans le socket */ function getuserbysocket($socket){ global $users; $found=null; foreach($users as $user){ if($user->socket==$socket){ $found=$user; break; } } return $found; } /** * fonction permet de formater le message de retour * envoyer vers les navigateurs (les utilisateurs) */ function onCtrlChatOut($from, $msg){ $msg = json_decode($msg); if($msg->message==='demo.stop'){ $msg->message='WebSockets server is going

down...'; broadcast('{"action": "ws/chat/in", "msg":'.json_encode($msg).'}'); die(); } broadcast('{"action": "ws/chat/in", "msg":'.json_encode($msg).'}'); } /** * Usefull functions */ function say($msg=""){ echo $msg."\n"; } function wrap($msg=""){ return chr(0). $msg.chr(255); } function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); } function console($msg=""){ global $debug; if($debug){ echo $msg."\n"; } } class User{ var $id; var $socket; var $handshake; var $userId=null; } ?>

// From GUI

Le code peut paratre un peu obscur si l'on n'est pas familiaris avec les sockets en PHP. Ce qu'il faut comprendre c'est que ce script permet d'instancier un serveur de socket et qu'il gre la connexion des utilisateurs ainsi que l'envoi des messages via les sockets. Bon, nous avons notre serveur websocket mais comment le lancer ? Il faudra s'assurer que l'extension php_sockets est bien charge dans PHP. Pour ce faire, rendez-vous dans le php.ini du PHP que vous utilisez et dcommentez la ligne ncessaire.
... ;extension=php_soap.dll extension=php_sockets.dll ;extension=php_sqlite.dll ;extension=php_sqlite3.dll ...

Dans notre cas, nous n'avons pas besoin de serveur Web. En effet, nous allons utiliser le serveur websocket. J'entends par l que nous pouvons utiliser notre page de chat en local (sans serveur Web, donc pas de http) et c'est notre serveur websocket qui va s'occuper de faire transiter les donnes entre les diffrents clients (navigateurs) connects au serveur websocket. Pour cela, il suffit donc de lancer notre serveur websocket en accdant une console de commande (cmd sous Windows par exemple) et accder au rpertoire o se situe notre serveur websocket. Une fois arriv au dossier ncessaire, on lance la commande suivante :
c:\websocket\serveur\>php -q serveur.php

Si le message suivant apparat, vous avez un serveur de


Numro 37 Dcembre - Janvier 2011/2012 Page 64

Developpez Magazine est une publication de developpez.com

websocket qui fonctionne et qui n'attend plus que les donnes : La variable host permet de donner l'URL du serveur de socket.
Server Started : 2011-06-30 13:59:03 Master socket : Resource id #5 Listening on : localhost port 11345 var WebsocketClass = function(host){ this.socket = new WebSocket(host); this.console = document.getElementsByClassName('console')[0]; };

La console ainsi ouverte vous permettra de voir le comportement du serveur sur la connexion d'utilisateurs et de traitement de message (de donnes).

Dans cette classe, je cre une variable this.socket qui rcupre l'instanciation de WebSocket() ainsi qu'une 4. Le chat variable this.console pour pouvoir retranscrire les actions Jusqu'ici, nous avons notre serveur qui fonctionne, nous du websocket dans ma console affiche sur ma page Web. allons maintenant crer l'interface permettant d'envoyer et de recevoir des messages depuis notre chat. Une fois la classe cre, je vais l'tendre grce au prototypage. Il y aura donc une initialisation du Commenons pour l'IHM que nous allons raliser en websocket, la gestion des vnements soulevs et une HTML. Voici le code : fonction permettant d'envoyer les messages.
<!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <link href="style/style.css" type="text/css" rel="stylesheet"/> <script type="text/javascript" src="script/script.js"></script> <title>Insert title here</title> </head> <body> <div class="sii-chat"> <-- conteneur du chat --> <div>Pseudo : <input type="text" name="siichat-name" /><button class="sii-chatlogin">Valider</button></div> <-- pseudo saisir pour le chat --> <div class="sii-chat-content"> <-- les messages apparaitront ici --> </div> <div> <form class="sii-chat-form" onsubmit="return false;"> <input type="text" value="" name="siichat-message" disabled="disabled"/><-- saisie du message saisir --> <button class="sii-chat-send" disabled="disabled">ok</button> <-- Bouton d'envoi du message saisi --> </form> </div> <div class="console"></div> </div> <script type="text/javascript" src="script/websocket.js"></script> </body> </html>

Nous allons galement placer les variables ncessaires au bon fonctionnement du chat. Voici le code :
var uId = ''; /* pseudo de l'utilisateur*/ var button = document.getElementsByClassName('sii-chat-send') [0]; /* bouton d'envoi du message */ var messageInput = document.getElementsByName('sii-chat-message') [0]; /* message envoyer vers le serveur */ var buttonUser = document.getElementsByClassName('sii-chat-login') [0]; /* bouton de soumission du pseudo */ var contentMessage = document.getElementsByClassName('sii-chatcontent')[0]; /* div contenant les messages reus par le serveur*/ var WebsocketClass = function(host){ this.socket = new WebSocket(host); this.console = document.getElementsByClassName('console')[0]; }; WebsocketClass.prototype = { initWebsocket : function(){ var $this = this; this.socket.onopen = function(){ $this.onOpenEvent(this); }; this.socket.onmessage = function(e){ $this._onMessageEvent(e); }; this.socket.onclose = function(){ $this._onCloseEvent(); }; this.socket.onerror = function(error){ $this._onErrorEvent(error); }; this.console.innerHTML = this.console.innerHTML + 'websocket init <br />'; }, _onErrorEvent :function(err){ console.log(err); this.console.innerHTML = this.console.innerHTML + 'websocket error <br />'; }, onOpenEvent : function(socket){ console.log('socket opened'); Numro 37 Dcembre - Janvier 2011/2012 Page 65

La zone de saisie d'un message et le bouton d'envoi d'un message sont volontairement en "disabled", pour obliger l'utilisateur renseigner un pseudo qui permettra d'identifier chaque intervenant sur le chat. Notre IHM est en place, intressons-nous la partie JavaScript. Dans un premier temps nous allons mettre en place le websocket via un objet JavaScript. Je cre une classe WebsocketClass qui va initialiser la communication avec le serveur et grer tous les vnements lis au websocket.

Developpez Magazine est une publication de developpez.com

this.console.innerHTML = this.console.innerHTML + 'socket opened Welcome status ' + socket.readyState + '<br />'; }, _onMessageEvent : function(e){ e = JSON.parse(e.data); if(e.msg.length > 0) e.msg = JSON.parse(e.msg); contentMessage.innerHTML = contentMessage.innerHTML + '><strong>' + e.msg.from + '</strong> : ' + e.msg.message + '<br />'; contentMessage.scrollTop = contentMessage.scrollHeight; /* permet de scroller automatiquement vers le bas dans la div contenant la rception des messages */ this.console.innerHTML = this.console.innerHTML + 'message event lanched <br />'; }, _onCloseEvent : function(){ console.log('connection closed'); this.console.innerHTML = this.console.innerHTML + 'websocket closed server not running<br />'; uId = ''; document.getElementsByName('sii-chat-name') [0].value = ''; messageInput.disabled = 'disabled'; button.disabled = 'disabled'; }, sendMessage : function(){ var message = '{"from":"' + uId + '", "message":"' + messageInput.value + '"}'; this.socket.send('{"action":"ctrl/chat/out", "msg":' + JSON.stringify(message) + '}'); messageInput.value = ''; this.console.innerHTML = this.console.innerHTML + 'websocket message send <br />'; } };

on coute l'vnement 'click' sur le bouton permettant d'envoyer le message */ e.preventDefault(); socket.sendMessage(); /* on envoie un message vers le serveur*/ return false; }, true); } else{ console.log('votre navigateur n\'accepte pas le addevenlistener'); }

Ajoutons l'IHM un brin de CSS pour amliorer le visuel de celle-ci :


.sii-chat{ width:400px; padding:10px; background:#ccc; margin:20px auto; } .sii-chat-content{ min-height:400px; max-height:400px; overflow:hidden; overflow-y:scroll; background:#fff; box-shadow:0px 0px 5px 0px #000; margin-bottom:10px; } .console{ min-height:50px; max-height:100px; overflow:hidden; overflow-y:scroll; } .sii-chat-form input[name="sii-chat-message"]{ width:300px; box-shadow:inset 0px 0px 5px 0px #000; } .sii-chat-form button{ width:80px; float:right; color:#ffffff; -moz-box-shadow: 0px 0px 5px #343434; -webkit-box-shadow: 0px 0px 5px #343434; -o-box-shadow: 0px 0px 5px #343434; box-shadow: 0px 0px 5px #343434; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; border: 1px solid #656565; filter: progid:DXImageTransform.Microsoft.gradient(startC olorstr="34cdf9", endColorstr="3166ff"); /* Pour IE seulement et mode gradient linear */ background: -webkit-gradient(linear, left top, left bottom, from(#34cdf9), to(#3166ff)); background: -moz-linear-gradient(top center, #34cdf9, #3166ff); } .sii-chat-form button:active{ filter: progid:DXImageTransform.Microsoft.gradient(startC olorstr="3166ff", endColorstr="34cdf9"); /* Pour IE seulement et mode gradient linear */ background: -webkit-gradient(linear, left top, left bottom, from(#3166ff), to(#34cdf9)); background: -moz-linear-gradient(top center, #3166ff, #34cdf9); }

Notre classe est cre, il ne nous suffit plus que de l'utiliser. Nous en profiterons pour galement rajouter des couteurs d'vnements sur les boutons afin de mettre en place le mcanisme suivant : l'utilisateur s'identifie et ensuite il aura accs au chat.
var socket = new WebsocketClass('ws://localhost:11345/serveur.php' ); /* on instancie un objet WebsocketClass avec l'URL en paramtre */ if(button.addEventListener){ buttonUser.addEventListener('click', function(e){ /* on coute l'vnement 'click' sur le bouton permettant de valider son pseudo */ e.preventDefault(); /* on stoppe la propagation */ socket.initWebsocket(); /* initialisation de la connexion vers le serveur de socket */ uId = document.getElementsByName('sii-chatname')[0].value; /* rcupration de la valeur du pseudo de l'utilisateur */ messageInput.disabled = ''; /* on permet l'accs au chat (aux champs permettant d'envoyer des messages) */ button.disabled = ''; return false; /* on vite le rechargement de page */ }, true); button.addEventListener('click',function(e){ /*

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 66

Introduction l'API Google Maps

Et voil, le chat est termin et fonctionnel. Pour bien tester 5. Package la dmonstration, ouvrez deux navigateurs avec la page de Tlcharger le package : Lien 143. chat et conversez entre les deux. Vous verrez que l'un et l'autre se mettent jour en mme temps et rapidement. Retrouvez l'article de Jerome Debray en ligne : Lien 144. Introduction l'API Google Maps

L'API Google Maps fournit une interface intuitive et trs ractive construite en utilisant les technologies AJAX. C'est une API ouverte permettant la personnalisation de la carte y compris la possibilit d'ajouter au sein de l'application des donnes spcifiques la carte (personnalisation des contrles, gestion des vnements, cration des marqueurs avec infobulle...). Encore mieux, Google donne accs ce service gratuitement ! Dans cet article nous allons examiner quelques-unes des fonctionnalits de base fournies par l'API Google Maps.
1. Qu'est-ce qu'une API (Application Programming Interface) ? Une API (Lien 145) est une interface fournie par un programme informatique. Elle permet l'interaction des programmes les uns avec les autres. D'un point de vue technique c'est un ensemble de fonctions, procdures ou classes mises disposition par une bibliothque logicielle, un systme d'exploitation ou un service. Toute application Web peut autoriser ou non des dveloppeurs tiers utiliser une partie de ses fonctionnalits et ce de plusieurs faons : en tlchargeant une bibliothque de fonctions pour l'inclure directement sur son site ; en rcuprant une donne prcise en construisant une URL comme avec Google charts : https://chart.googleapis.com/chart? cht=chart_type&chd=chart_data&chs=cha... ; comme Google Maps, en incluant directement la bibliothque en ligne. 2. Installation de l'API On va inclure la bibliothque Google Maps directement dans le code JavaScript de la page. Cette URL permet d'accder l'ensemble des fonctionnalits de l'API. Exemple d'ajout d'une balise script pour inclure les fonctions de Google Maps dans l'application cible :
<script type="text/javascript" src="http://maps.google.com/maps/api/js"></script >

le calcul scalaire de valeurs gomtriques sur la surface de la Terre ; adsense : permet votre application Maps d'inclure des annonces contextuelles, vous permettant de partager les revenus publicitaires pour les annonces diffuses aux utilisateurs ; panoramio :permet d'ajouter la fonctionnalit Panoramio : quand on clique sur l'icne d'une photo avec Panoramio, on a par dfaut une popup qui s'ouvre avec des informations et la photo en plus grand.

On peut ajouter plusieurs librairies Google Maps dans l'URL, il suffit de les sparer par des virgules.
<script type="text/javascript" src="http://maps.google.com/maps/api/js? libraries=adsense,geometry&sensor=true"></script>

On se retrouve donc avec une dclaration finale de ce type :


<head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="http://maps.google.com/maps/api/js? sensor=true"></script> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% } </style> </head>

On spcifie une taille pour les balises html et body (pour les navigateurs plus anciens il faut prciser la taille des lments parents sinon ceux-ci supposent que la taille est 3. Paramtres de l'URL de 0x0px). Plusieurs dclinaisons de l'API sont disponibles en Ici la balise meta spcifie le mode plein cran et que la ajoutant des paramtres l'URL de base ; en voici carte n'est pas redimensionnable par l'utilisateur. quelques exemples : sensor (true ou false) : utilisation ou non de la 4. Google Maps avec SSL golocalisation ; language : langue des textes afficher sur la carte L'utilisation du SSL (Lien 146) avec Google Maps permet d'viter les avertissements de scurit dans la plupart des ; navigateurs. region : le pays. Ce genre d'utilisation est prvu pour les sites collectant des On peut ajouter d'autres paramtres l'URL pour inclure donnes confidentielles sur des utilisateurs (telles que la localisation personnelle ou professionnelle d'un utilisateur des librairies additionnelles : dans des requtes). geometry : inclut des fonctions ncessaires pour
Developpez Magazine est une publication de developpez.com
Numro 37 Dcembre - Janvier 2011/2012 Page 67

Exemple d'implmentation :
<script type="text/javascript" src="https://mapsapi-ssl.google.com/maps/api/js? v=3.4&sensor=true"></script>

5. Mise en place de la carte Nous allons afficher la carte une fois la page HTML charge. Pour cela nous allons ajouter l'attribut onload la balise body avec en paramtre la fonction d'initialisation de la carte :
<body onload="initialize()"> <script type="text/javascript"> function initialize() { //... } </script>

} var carte = new google.maps.Map(document.getElementById("map_canv as"), mesOptions); } // Cration de la balise script pour inclure les fonctions de Google Maps dans notre application function loadScript() { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "http://maps.google.com/maps/api/js? sensor=false&callback=initialisation"; document.body.appendChild(script); } // Au chargement de la page on appelle la fonction loadScript qui appelle la fonction initialisation() grce au paramtre callback window.onload = loadScript;

7. Gestion des vnements Google Maps un nouvel objet Il est possible de capturer un vnement sur un marqueur ou sur la carte grce la mthode addListener(). Il existe diffrents types d'vnements simples : 'click' ; 'dblclick' ; 'mouseup' ; 'mousedown' ; 'mouseover' ; 'mouseout' ; zoom_changed.

Ensuite il reste instancier google.maps.Map comme ceci :

function initialize() { map = new google.maps.Map(document.getElementById("map_canv as"), { zoom: 19, center: new google.maps.LatLng(48.8695490, 2.3513734), mapTypeId: google.maps.MapTypeId.ROADMAP }); }

Ces vnements ressemblent des vnements DOM standard, mais ils font en ralit partie intgrante de l'API La nouvelle carte sera contenue dans la div "map_canvas", Google Maps. centre sur les coordonnes de latitude 48.8695490 et longitude 2.3513734 (qui reprsentent la position de The var carte; Coding Machine Paris 2e) et avec un niveau de zoom function initialisation(){ // On rentre les coordonnes(latitude, trs prcis. Le paramtre mapTypeId sert dfinir le type de carte que l'on souhaite, il en existe quatre : ROADMAP : affiche le plan classique, sans image satellite ni relief ; SATELLITE : pour les photos satellite ; HYBRID : pour afficher les photos satellite avec le plan superpos (les routes, le nom des villes) ; TERRAIN : affiche les diffrences de reliefs (montagnes, rivires, etc.). 6. Chargement asynchrone de l'API Google Maps Gnralement, l'API est charge au dmarrage de l'application. Cela peut occasionner un ralentissement du temps d'affichage de la page. Il est possible de charger l'API Google Maps en mode asynchrone, c'est--dire en diffr ; on utilise pour cela le paramtre callback dans l'URL qui appellera la fonction d'initialisation de la carte.
function initialisation(){ var maLatlng = new google.maps.LatLng(48.8695490, 2.3513734); var mesOptions = { zoom: 8, center: maLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP longitude) de notre choix dans une variable var maLatlng = new google.maps.LatLng(25.363882,131.044922);

// On tablit les options de notre choix : // la profondeur du zoom, les coordonnes sur lesquelles la carte sera centre, le type de vue (satellite, plan...) var mesOptions = { zoom: 4, center: maLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } // On cre notre carte en lui passant toutes nos options en paramtre carte = new google.maps.Map(document.getElementById("map_canv as"), mesOptions); // On place un listener sur la carte qui contrle une action qui sera dclenche lors de l'vnement 'zoom_changed' // Quand le zoom sera modifi la carte sera recentre sur les coordonnes de The Coding Machine google.maps.event.addListener(carte,'zoom_cha nged', function() { setTimeout(allerChezTCM,3000); });

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 68

// On cre un marqueur que l'on positionne grce au paramtre "position" var marker = new google.maps.Marker ({ position: maLatlng, map: carte, title: "Hello world :) !" }); // On place un listener sur le marqueur qui contrle une action qui sera dclenche lors de l'vnement 'click' // Quand on clique sur le marqueur, le zoom de la carte passera 8 google.maps.event.addListener(marker, 'click', function(){ carte.setZoom(8); }); } function allerChezTCM() { var tcm = new google.maps.Latlng(48.8695490, 2.3513734); map.setCenter(tcm); }

//On tablit une liste droulante pour le contrle MapType et on spcifie que le Zoom control utilise un minizoom function initialize() { var myOptions = { zoom: 4, center: new google.maps.LatLng(-33, 151), mapTypeControl: true, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU }, zoomControl: true, zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL }, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canv as"), myOptions); }

8. Les contrles Google Maps Il est possible d'activer ou de dsactiver un contrle en changeant la valeur de sa proprit true ou false :
{ panControl: boolean, zoomControl: boolean, mapTypeControl: boolean, scaleControl: boolean, streetViewControl: boolean, overviewMapControl: boolean }

Voici toutes les positions possibles d'un contrle sur une carte :

On peut galement modifier les options d'un contrle (position et style)


zoomControl: true, zoomControlOptions: { style: google.maps.ZoomControlStyle.LARGE, position: google.maps.ControlPosition.LEFT_CENTER },

9. Les marqueurs Google Maps Voici comment crer un marqueur simple avec un contenu info bulle HTML :
function initialize() { var maLatlng = new google.maps.LatLng(48.8695490, 2.3513734); var mesOptions = { zoom: 4, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var carte = new google.maps.Map(document.getElementById("map_canv as"), mesOptions); var image = 'beachflag.png'; // Instanciation de notre marqueur var marker = new google.maps.Marker({ position: maLatLng, map: carte, icon: image }); var message = "Vous tes ici !"; var infowindow = new google.maps.InfoWindow({ content: message, size: new google.maps.Size(50,50) });

En voici quelques exemples : ZoomControlStyle.LARGE : zoom standard avec le slider ; ZoomControlStyle.SMALL : affiche un mini zoom avec juste les icnes + et - ; ZoomControlStyle.DEFAULT : choisit le bon format de zoom en fonction de taille de la carte du type d'appareil (mobile ou non) ; MapTypeControlStyle.HORIZONTAL_BAR : affiche une barre horizontale pour la slection du type d'affichage de la carte ; MapTypeControlStyle.DROPDOWN_MENU : permet de choisir le type de carte (plan, satellite, terrain, hybride) via une liste droulante ; MapTypeControlStyle.DEFAULT : comportement par dfaut, dpend de la taille de l'cran. Exemple de configuration d'un contrle :

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 69

google.maps.event.addListener(marker, 'click', function() { infowindow.open(carte,marker); }); }

10. Utiliser la golocalisation


// On teste tout d'abord si le navigateur prend en charge la golocalisation HTML5 if (navigator.geolocation){ var watchId = navigator.geolocation.watchPosition( successCallback, null, {enableHighAccuracy:true} ); } else{ alert("Votre navigateur n'est pas compatible avec la golocalisation HTML 5"); } function successCallback(position){ map.panTo(new google.maps.Latlng(position.coords.latitude, position.coords.longitude)); var marker = new google.maps.Marker({ position: new google.maps.Latlng(position.coords.latitude, position.coords.longitude), map: map }); }

Les marqueurs sont personnalisables l'aide de la proprit icon, il suffit de lui passer une image en paramtre. En bonus, il est possible d'ajouter une animation aux marqueurs en appelant la mthode setAnimation() sur l'objet marker. Deux types sont possibles : DROP : indique que ce marqueur devrait tomber du haut de la carte jusqu' son emplacement dfinitif quand il est affich sur la carte la premire fois. L'animation cesse une fois que le curseur est en place. Ce type d'animation est gnralement spcifi lors de la cration du marqueur ; BOUNCE : indique que le marqueur doit remuer. Un marqueur de ce type va continuer de bouger jusqu' ce que sa proprit soit explicitement dsactive (= null).
var stockholm = new google.maps.LatLng(59.32522, 18.07002); var tcm = new google.maps.LatLng(48.8695490, 2.3513734); var marker; var map; function initialize() { var mapOptions = { zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP, center: stockholm }; map = new google.maps.Map(document.getElementById("map_canv as"), mapOptions); marker = new google.maps.Marker({ map:map, draggable:true, animation: google.maps.Animation.DROP, position: tcm }); google.maps.event.addListener(marker, 'click', toggleBounce); } function toggleBounce() { if (marker.getAnimation() != null) { marker.setAnimation(null); } else { marker.setAnimation(google.maps.Animation. BOUNCE); }

chaque dplacement, un nouveau marqueur est plac ; dans le cas d'une perte de signal le marqueur se positionne au relais 3G le plus proche. Pour contourner le problme on utilise la proprit accuracy :
if(position.coords.accuracy < 100) { //... }

11. Utilisation de la librairie Geometry pour le calcul de distance Tout ce que vous avez faire est d'inclure la librairie Geometry lors de l'intgration de l'API l'application, puis d'appeler la mthode computeDistanceBetween() et lui passer deux objets LatLng en paramtres :
var nyc = new google.maps.LatLng(40.715, -74.002); var london = new google.maps.LatLng(51.506, -0.119); var distance = google.maps.geometry.spherical.computeDistanceBet ween(nyc, london);

Retrouvez l'article de The Coding Machine en ligne : Lien 147

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 70

Liens
Lien 01 : http://eclipse.developpez.com/cours/?page=platform-cat#plugin-dev Lien 02 : http://www.eclipse.org/downloads Lien 03 : http://maven.apache.org/ Lien 04 : http://mbaron.developpez.com/eclipse/introplugin/ Lien 05 : http://keulkeul.blogspot.com/search/label/Tycho Lien 06 : http://www.eclipse.org/tycho/ Lien 07 : ftp://ftp-developpez.com/mbaron/eclipse/tycho.zip Lien 08 : http://mbaron.ftp-developpez.com/eclipse/tycho.zip Lien 09 : http://mbaron.developpez.com/eclipse/introtycho/ Lien 10 : http://www.developpez.net/forums/d998128/systemes/autres-systemes/mobiles/android-detrone-liphone-aux-usa-termes-dabonnes-premiere/ Lien 11 : http://www.developpez.com/actu/38093/Android-Ice-Cream-Sandwich-lance-officiellement-avec-le-telephone-Galaxy-Nexus/ Lien 12 : http://www.developpez.com/actu/28153/Google-devoile-enfin-Android-3-0-Honeycomb-dans-lequel-tout-est-pense-pour-les-tablettes/ Lien 13 : http://linux.developpez.com/actu/30188/Google-retarde-la-diffusion-du-code-source-d-Android-3-une-demarche-qui-commence-a-fairedebat-dans-la-communaute-open-source/ Lien 14 : http://www.developpez.com/actu/27224/Developper-pour-Android-sans-Java-bientot-possible-en-C-grace-a-la-5eme-revision-du-NativeDevelopment-Kit/ Lien 15 : http://source.android.com/source/downloading.html Lien 16 : http://developer.android.com/sdk/ndk/index.html Lien 17 : http://www.developpez.net/forums/d1152665/java/general-java/java-mobiles/android/google-publie-code-source-dandroid-4-kitdeveloppement-natif-los-supporte-nouvelles-api/ Lien 18 : http://code.google.com/p/ksoap2-android/downloads/detail?name=ksoap2-android-assembly-2.4-jar-with-dependencies.jar Lien 19 : http://michel-dirix.developpez.com/tutoriels/android/android-et-webservices/ Lien 20 : http://java.developpez.com/cours/ Lien 21 : http://jmdoudoux.developpez.com/cours/developpons/java/chap-presentation.php#presentation-6 Lien 22 : http://java.developpez.com/outils/edi/?page=advanced#eclipse Lien 23 : http://java.developpez.com/outils/edi/?page=advanced Lien 24 : http://eclipse.developpez.com/cours/ Lien 25 : http://javasearch.developpez.com/j2se/1.6.0/docs/api/java/awt/LayoutManager2.html Lien 26 : http://javasearch.developpez.com/j2se/1.6.0/docs/api/java/util/EventListener.html Lien 27 : http://java.developpez.com/cours/?page=desktop-cat Lien 28 : http://gfx.developpez.com/tutoriel/java/swt/ Lien 29 : http://eclipse.developpez.com/cours/?page=platform-cat#plugin-dev Lien 30 : http://jmdoudoux.developpez.com/cours/developpons/java/chap-ria-rda.php Lien 31 : http://javasearch.developpez.com/j2se/1.6.0/docs/api/java/util/ResourceBundle.html Lien 32 : http://jmdoudoux.developpez.com/cours/developpons/java/chap-i18n.php Lien 33 : http://jmdoudoux.developpez.com/cours/developpons/java/index.php Lien 34 : http://hikage.developpez.com/java/tutoriel/spring/i18n/internationalisation/base-donnees/ Lien 35 : http://javasearch.developpez.com/j2se/1.6.0/docs/api/java/util/PropertyResourceBundle.html Lien 36 : http://uml.developpez.com/cours/ Lien 37 : http://abrillant.developpez.com/tutoriel/java/design/pattern/introduction/ Lien 38 : http://ego.developpez.com/spring/ Lien 39 : http://adiguba.developpez.com/tutoriels/java/tiger/annotations/ Lien 40 : http://smeric.developpez.com/java/astuces/tests/ Lien 41 : http://rpouiller.developpez.com/tutoriels/java/tests-unitaires-junit4/ Lien 42 : http://spalud.developpez.com/tutoriel/java/testng/ Lien 43 : http://baptiste-wicht.developpez.com/tutoriels/java/tests/mocks/easymock/ Lien 44 : http://fchabanois.developpez.com/tutorial/java/jmockit/ Lien 45 : http://dboissier.developpez.com/tutoriels/test-driven-development/?page=authentification#LIII-B-6 Lien 46 : http://beuss.developpez.com/tutoriels/java/jakarta/commons/logging/ Lien 47 : http://beuss.developpez.com/tutoriels/java/jakarta/log4j/ Lien 48 : http://baptiste-wicht.developpez.com/tutoriels/java/slf4j/ Lien 49 : http://www.insideit.fr/post/2009/11/23/SLF4J-LOGBack Lien 50 : http://jguillard.developpez.com/JDBC/ Lien 51 : http://jmdoudoux.developpez.com/cours/developpons/java/chap-jpa.php Lien 52 : http://ippon.developpez.com/articles/java/persistance/solutions/ Lien 53 : http://ippon.developpez.com/articles/java/persistance/ibatis/ Lien 54 : http://java.developpez.com/cours/?page=outils-cat#maven Lien 55 : http://linsolas.developpez.com/articles/java/qualite/sonar/ Lien 56 : http://linsolas.developpez.com/articles/hudson/ Lien 57 : http://loic-mathieu.developpez.com/conception/article/cruise-control/ Lien 58 : http://java.developpez.com/cours/?page=outils-cat#ant Lien 59 : http://linsolas.developpez.com/articles/java/outils/builds/ Lien 60 : http://tahe.developpez.com/java/baseswebmvc/ Lien 61 : http://mbaron.developpez.com/javaee/tomcat/ Lien 62 : http://ego.developpez.com/spring/ Lien 63 : http://valtech.developpez.com/articles/java/javaee/jboss/seam/ Lien 64 : http://mbaron.developpez.com/javaee/jsf/ Lien 65 : http://jmdoudoux.developpez.com/cours/developpons/java/chap-ejb.php Lien 66 : http://x-plode.developpez.com/tutoriels/netbeans/nouvelles-fonctionnalites-dans-jca-1-6/ Lien 67 : http://aldian.developpez.com/cours/introduction-a-l-ecosysteme-java/ Lien 68 : http://argyronet.developpez.com/office/access/setformtoright/ Lien 69 : http://www.developpez.net/forums/d724265/logiciels/microsoft-office/access/contribuez/positionner-formulaire-sous-controle/#post4201158 Lien 70 : http://claudeleloup.developpez.com/tutoriels/access/positionner-formulaire/PositionnerFormulaire.mdb Lien 71 : http://claudeleloup.developpez.com/tutoriels/access/positionner-formulaire/ Lien 72 : http://fauconnier.developpez.com/excel/bases/references Lien 73 : http://fauconnier.developpez.com/videos/excel/excel-comparaison-listes-mise-en-forme-conditionnelle.swf Lien 74 : http://fauconnier.developpez.com/tutoriels/excel/video-excel-2010-comparer-listes-grace-mise-forme-conditionnelle/ Numro 37 Dcembre - Janvier 2011/2012 Page 71

Developpez Magazine est une publication de developpez.com

Lien 75 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/?page=page_1#L2-C-1 Lien 76 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/?page=page_1#L2-C-2 Lien 77 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/?page=page_1#L2-C-3 Lien 78 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/?page=page_1#L2-D-1 Lien 79 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/?page=page_1#L2-D-2 Lien 80 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/?page=page_1#L2-D-3 Lien 81 : http://support.sas.com/kb/40/383.html Lien 82 : http://support.sas.com/kb/14/647.html Lien 83 : http://en.wikipedia.org/wiki/Microsoft_Jet_Database_Engine Lien 84 : http://support.sas.com/documentation/cdl/en/acpcref/63184/HTML/default/viewer.htm Lien 85 : http://support.sas.com/documentation/cdl/en/acpcref/63184/HTML/default/viewer.htm Lien 86 : http://support.sas.com/kb/41/060.html Lien 87 : http://support.sas.com/kb/41/060.html Lien 88 : http://support.sas.com/kb/33/228.html Lien 89 : http://support.sas.com/kb/40/383.html Lien 90 : http://support.sas.com/kb/40/409.html Lien 91 : http://support.sas.com/kb/37/479.html Lien 92 : http://support.sas.com/kb/40/597.html Lien 93 : http://support.sas.com/kb/36/967.html Lien 94 : http://datametric.developpez.com/tutoriels/sas/import_export_sas92_x64/ Lien 95 : http://qt.developpez.com/actu/40074/Sortie-de-Qt-4-8-le-framework-C-ameliore-son-architecture-pour-faciliter-le-portage-vers-denouvelles-plateformes/ Lien 96 : http://qt-devnet.developpez.com/tutoriels/python/pyside/installer/ Lien 97 : http://developer.qt.nokia.com/wiki/Category:LanguageBindings::PySide::Downloads Lien 98 : http://pyqt.developpez.com/actu/36457/PySide-le-binding-Python-de-Qt-en-danger-suite-a-l-arret-des-subsides-de-Nokia/ Lien 99 : http://www.developpez.net/forums/d1171611/autres-langages/python-zope/gui/pyside-pyqt/sortie-pyside-1-1-0-a/ Lien 100 : http://qt.developpez.com/actu/38218/Le-Qt-Project-est-la-le-projet-d-open-gouvernance-pour-le-framework-C-est-arrive-a-terme/ Lien 101 : http://mesa3d.org/ Lien 102 : http://www.developpez.net/forums/d1145082/c-cpp/bibliotheques/qt/ouverture-qt-dev-days-2011-munich/#post6311498 Lien 103 : http://www.developpez.net/forums/d1144709/c-cpp/bibliotheques/qt/vivats-qt-project/ Lien 104 : http://www.developpez.net/forums/d1145082/c-cpp/bibliotheques/qt/reportage-direct-deuxieme-jour-qt-dev-days-2011munich/#post6311702 Lien 105 : http://www.developpez.net/forums/d1145082/c-cpp/bibliotheques/qt/reportage-direct-deuxieme-jour-qt-dev-days-2011-munich/ Lien 106 : http://qt.developpez.com/doc/4.7/qpainter Lien 107 : http://qt.developpez.com/doc/4.7/vue-graphique-graphics-view/ Lien 108 : http://qt.developpez.com/doc/4.7/QtOpenGL/ Lien 109 : http://qt.developpez.com/doc/4.7/Qtmultimedia/ Lien 110 : http://qt.developpez.com/doc/4.7/qtsvg/ Lien 111 : http://qt.developpez.com/doc/4.7/phonon-overview/ Lien 112 : http://qt.developpez.com/doc/4.7/model-view-programming/ Lien 113 : http://qt.developpez.com/doc/4.7/exemples/ Lien 114 : http://qt.developpez.com/doc/4.7/qt4-scribe/ Lien 115 : http://qt.developpez.com/doc/4.7/richtext/ Lien 116 : http://qt.developpez.com/doc/4.7/qtextdocumentwriter/ Lien 117 : http://qt.developpez.com/doc/4.7/qtwebkit/ Lien 118 : http://qt.developpez.com/doc/4.7/demos-browser/ Lien 119 : http://qt.developpez.com/tutoriels/integrer-gadgets-logiciels-webkit/ Lien 120 : http://qt-devnet.developpez.com/tutoriels/qt/livre-blanc/ Lien 121 : http://vincent-vande-vyvre.developpez.com/tutoriels/pyqt/manipulation-images/ Lien 122 : http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qgraphicsitem.html#GraphicsItemFlag-enum Lien 123 : http://www.pyside.org/docs/pyside/PySide/QtGui/QGraphicsItem.html#PySide.QtGui.PySide.QtGui.QGraphicsItem.GraphicsItemFlag Lien 124 : http://vincent-vande-vyvre.developpez.com/tutoriels/pyqt/qgraphicsitem/ Lien 125 : http://www.nih.at/libzip/ Lien 126 : http://www.nih.at/libzip/libzip.html Lien 127 : http://slash.developpez.com/tutoriels/c/utilisation-libzip/#L2-E-2 Lien 128 : http://slash.ftp-developpez.com/tutoriels/c/utilisation-libzip/fichiers/zipzap.c Lien 129 : http://slash.developpez.com/tutoriels/c/utilisation-libzip/ Lien 130 : http://vb.developpez.com/telecharger/detail/id/1238/MSDN-VB6-Fr Lien 131 : http://vb.developpez.com/telecharger/detail/id/1249/MZ-Tools Lien 132 : http://darkvader.developpez.com/tutoriels/vb/debogage-visual-basic-6/ Lien 133 : http://www.developpez.net/forums/d1075435/webmasters-developpement-web/contribuez/php-javascript-methode/#post6338448 Lien 134 : http://www.developpez.net/forums/d1151380/webmasters-developpement-web/javascript/publications-javascript-ajax/pourquoi-generercode-javascript-fausse-bonne-idee/ Lien 135 : http://blog.developpez.com/web/p10401/web/javascript/le-core-javascript-s-enrichit-de-nouvell/ Lien 136 : http://html5labs.interoperabilitybridges.com/html5labs/prototypes/websockets/websockets/info/ Lien 137 : http://jwebsocket.org/ Lien 138 : https://github.com/gimite/web-socket-ruby Lien 139 : https://github.com/LearnBoost/Socket.IO-node Lien 140 : http://code.google.com/p/phpwebsocket/ Lien 141 : http://www.kaazing.com/download Lien 142 : http://www.wakanda.org/download/ Lien 143 : http://sii-rennes.developpez.com/telechargements/websockets.zip Lien 144 : http://sii-rennes.developpez.com/articles/un-chat-en-html5-avec-les-websockets/ Lien 145 : http://dico.developpez.com/html/1453-Langages-API-Application-Programming-Interface.php Lien 146 : http://dico.developpez.com/html/1589-Securite-SSL-Secure-Sockets-Layer.php Lien 147 : http://thecodingmachine.developpez.com/tutoriels/javascript/introduction-api-google-maps/

Developpez Magazine est une publication de developpez.com

Numro 37 Dcembre - Janvier 2011/2012 Page 72

S-ar putea să vă placă și