Un album photos en Visual Basic .NET pour votre Pocket PC
Auteur
Stéphane Sibué
Date Dimanche 5 novembre 2006

Jusqu'à maintenant la fonction caméra des Pocket PC n'était pas prise en charge par le système d'exploitation mais directement par le constructeur. Ceci se traduisait par une manière différente pour accéder à cette fonctionnalité d'un appareil à l'autre. La version 5 de Windows Mobile standardise la manière d'accéder aux fonctions liées à la caméra, et cerise sur le gâteau, vous pouvez en plus l'utiliser directement depuis du code .NET managé.

Vous pouvez télécharger les sources de cet article ici.

Que les choses soient bien claires, en .NET, seules les programmes écrits pour la plate-forme Windows Mobile 5 peuvent utiliser les fonctions liées à la caméra car c'est uniquement depuis Windows CE 5, le cœur de Windows Mobile 5, que le système d'exploitation fournit une architecture pour accéder de manière standardisée à ce type de périphérique. Microsoft a eu la bonne idée de proposer avec le SDK Windows Mobile 5 pour Pocket PC et Smartphone, l'accès en code managé (donc en .NET) à ces nouvelles fonctions de gestion de la caméra.

Une nouvelle assembly pour Windows Mobile 5

L'accès aux fonctions de gestion de la caméra est possible grâce à une nouvelle assembly incluse dans le SDK Windows Mobile 5. Cette assembly, qu'il faut ajouter aux références de vos projets Smart Device, est Microsoft.WindowsMobile.Forms.dll.

Elle est accessible dans vos projets depuis l'espace de nom Microsoft.WindowsMobile.Forms. Cette assembly regroupe de nouvelles classes permettant d'accéder à certaines fonctionnalités du système Windows Mobile jusqu'alors non accessibles en code managé ou non présentes dans les versions précédentes de l'OS.

Parmi les classes proposées, on retrouve la classe CameraCaptureDialog qui permet d'utiliser le dialogue standard de capture caméra (nouvelle fonction présente uniquement dans Windows Mobile 5). Ce dialogue, aussi simple à utiliser qu'un simple dialogue de choix de fichier, permet de paramétrer la capture (type de capture photo ou vidéo, avec ou sans son, de qualité normale ou supérieure, etc..) ainsi que le nom du fichier qui servira à enregistrer le résultat de la capture.

Le principe ne peut être plus simple. Il suffit de créer une occurrence de la classe CameraCaptureDialog, de donner à certaines de ses propriétés (nous verrons lesquelles plus loin) les bonnes valeurs et d'activer le dialogue par un classique ShowDialog. Si la méthode ShowDialog retourne la valeur DialogResult.OK c'est que la capture s'est bien passée et que le fichier a été correctement créé, il n'y a plus qu'à le récupérer.

Le projet AlbumPhoto

Pour illustrer l'utilisation de cette nouvelle classe, nous allons créer un album photos pour Pocket PC. Cet album vous permettra de prendre vos photos et de les ranger au sein d'une arborescence que vous aurez vous-même paramétrée. Il vous sera alors possible, sans manipulation particulière, de ranger vos photos personnelles dans le dossier Perso, ou les photos liées au projet X45 dans le dossier Boulot\Projets\X45.

Actuellement, toutes les photos prises avec votre Pocket PC sont rangées dans le dossier \My Documents, àvous ensuite de copier la photo au bon endroit, sans oublier le fait de devoir la renommer pour savoir ce qu'elle est vraiment. Grâce à cet l'album photos vous n'aurez plus à effectuer toutes ces manipulations fastidieuses.

Note : Ce projet utilise les services de la bibliothèqueCodePPC dans sa version 2. Cette bibliothèque .NET, gratuite, simplifie le développement d'applications mobilité en proposant des fonctions supplémentaires au Compact Framework. La Librairie CodePPC est fournie dans les sources de cet article. Pour plus d'infos : http://www.codeppc.com/ressources/LibrairieCodePPC/index.htm

Pré requis

Pour pouvoir créer un projet mobilité, vous devez installer pour chaque plate-forme ciblée le kit de développement correspondant. Le terme de plate-forme désigne dans ce cas le matériel et sa version. Par exemple, aujourd'hui, avec Visual Studio 2005, vous pouvez développer des applications pour les plates-formes Pocket PC 2003, Smartphone 2003, Windows CE 5.0, Windows Mobile 5.0 pour Pocket PC et Windows Mobile 5.0 pour Smartphone et aussi pour toutes les plates-formes disposant d'un SDK destiné à Visual Studio.

Pour notre projet, nous allons cibler la plate-forme Windows Mobile 5.0 pour Pocket PC, il faut donc que son SDK soit installé sur votre PC de développement. Si vous ne l'avez pas vous pouvez le télécharger à cette adresse : http://www.microsoft.com/downloads/details.aspx?FamilyID=83A52AF2-F524-4EC5-9155-717CBE5D25ED&displaylang=en

Création du projet

Lancez Visual Studio 2005, et créez un nouveau projet de type Smart Device. Vous devez sélectionner la plate-forme Windows Mobile 5.0 pour Pocket PC. Choissez ensuite le template Device Application permettant de créer un projet pour une application disposant d'une interface graphique. Pour terminer il ne reste plus qu'à saisir le nom du projet AlbumPhoto et à valider la boîte de dialogue de création de projet.

Positionnement des contrôles

L'interface est composée de 3 parties. L'arborescence des différents dossiers qui composeront l'album sera affichée dans un contrôle TreeView, la liste des photos dans un ListView et la photo en cours de visualisation dans un PictureBox. Nous allons aussi permettre à l'utilisateur de modifier la taille des différents contrôles en utilisant des contrôles Splitter. Il n'y aura qu'un seul menu, celui pour quitter l'application.

Les contrôles sont placés les uns par rapport aux autres en utilisant la propriété Dock. Cette propriété permet de docker (coller contre un bord) les contrôles de cinq manières différentes. Vous pouvez docker à gauche (Left), à droite (Right), en haut (Top), en bas (Bottom) ou encore utiliser toute la place disponible (All). Lorsque le conteneur d'un contrôle docké change de taille, il adapte sa taille et sa position pour être toujours en phase avec le type de docking qui lui est imposé.

Le TreeView et le ListView sont placés dans un Panel car leur positionnement est lié. Dans l'ordre, on place le TreeView dans le Panel en le dockant à gauche, puis le Splitter, lui-même docké à gauche et enfin le ListView docké sur la totalité de la place restante. Le Panel conteneur du TreeView et du ListView doit être pour sa part docké en haut. Les contrôles ainsi placés utilisent toute la place du Panel qui leur sert de conteneur et le Splitter permet de changer la largeur du TreeView et du ListView dans aucune ligne de code supplémentaire.

Après avoir placé le Panel conteneur du TreeView et du ListView il suffit de placer un autre Splitter docké en haut. Il va donc tout naturellement se coller au Panel et marquer la séparation avec le PictureBox qu'il faut ajouter en dernier, docké sur la totalité de la place restante. Si vous placez les contrôles dans cet ordre, et avec ces valeurs pour leur propriété Dock, vous obtiendrez une interface dynamique sans aucune ligne de code !

Le fait d'avoir créé l'interface en utilisant la propriété Dock permet aussi à la fenêtre de se tailler correctement si l'orientation de l'écran change. Les contrôles garderont le même positionnement les uns par rapport aux autres.

Utilisation des menus contextuels

Le Treeview doit permettre à l'utilisateur de gérer les dossiers de son album photo. Il faut donc pouvoir créer des sous-dossiers, en renommer et aussi en supprimer. Chacune de ces opérations est liée à un dossier. Le plus simple est de créer un menu contextuel lié au TreeView. Les commandes disponibles seront Nouveau, Renommer et Supprimer. La création d'un menu contextuel se passe exactement comme celle d'un menu classique. Il faut ajouter à la fenêtre un contrôle de type ContextMenu, le remplir avec ses éléments et ensuite en faire le menu contextuel du TreeView. Pour lier un menu contextuel à un contrôle il suffit de renseigner la propriété ContextMenu de ce dernier en lui donnant le nom logique du menu contextuel à utiliser. Dans notre exemple, le menu contextuel du TreeView s'appelle CTX_Dossiers.

Lorsque l'utilisateur effectuera un clic long sur l'un des dossiers du TreeView, le menu contextuel sera affiché. Il ne restera plus qu'à exécuter la commande demandée en rapport avec le dossier sélectionné.

Pour le ListView, les commandes à implémenter sont : Prendre une photo, Renommer, Supprimer, Copier, Couper et Coller (pour déplacer ou dupliquer une photo d'un dossier à un autre). Là aussi nous allons utiliser un menu contextuel pour proposer ces fonctions à l'utilisateur. Comme pour le TreeView, le menu contextuel de ces commandes sera lié au ListView grâce à sa propriété ContextMenu.

Il faudra juste rendre indisponible (Enabled=False) les éléments du menu contextuel qui ne doivent pas l'être suivant ce qui est sélectionné dans le ListView (il est possible de faire apparaître le menu contextuel d'un ListView sans avoir pour autant sélectionné un élément de la liste). Si l'utilisateur fait apparaître le menu contextuel sans sélectionner une ligne dans la liste, le seul élément à rester valide sera Prendre une photo. Si l'utilisateur active le menu contextuel alors que rien n'a été copié dans le presse-papier il ne faut pasque la commande Coller puisse être utilisée. Pour déterminer les éléments à activer et ceux à interdire il suffit de placer du code dans l'événement Popup du menu contextuel car cet événement est déclenché juste avant l'affichage du menu, et c'est donc le meilleur moment pour faire ce travail.

A titre d'exemple, le code placé dans l'événement Popup du menu contextuel du ListView est le suivant :

Dans lequel pClipboard pointe sur le presse-papier (objet maison) de l'application, et où les variables commençant par CMEN_... correspondent aux différents éléments du menu contextuel. La variable locale booléenne wActif est vraie s'il y a une ligne dans le ListView de sélectionnée. Suivant l'état de cette variable, les commandes Supprimer, Renommer, Copier et Couper sont actives ou non. Si le presse-papier maison n'est pas défini (ce qui signifie dans la logique de cette application qu'il est vide), la commande Coller est désactivée (la propriété Enabled de la commande Coller est directement affectée avec le résultat du test sur pClipboard, ce qui évite une variable booléenne intermédiaire).

Gestion des dossiers de l'album

Le programme utilise les fonctions de gestion de fichiers et de dossiers pour stocker les photos de l'album. Par défaut il crée un dossier AlbumPhoto à la racine du système de fichiers du Pocket PC lors de son premier démarrage. Ce dossier est la racine de l'album. Le TreeView liste les dossiers physiquement présents dans ce dossier racine pour composer l'arborescence. Pour gagner du temps, seul les dossiers de premier niveau sont créés. S'ils contiennent eux-même des sous-dossiers, un faux nœud est ajouté permettant d'ouvrir par la suite le dossier pour y lister ses sous-dossiers. Si lors de l'ouverture du dossier (événement BeforeExpand du TreeView) on se rend compte que des sous-dossiers existent il sont ajoutés à ce moment là. Ce système permet de composer l'arborescence au fur et à mesure de la navigation de l'utilisateur et non de tout scanner dès le début. Le gain de temps est très important.

Classiquement les nœuds utilisés dans un TreeView sont de type TreeNode. Pour nous simplifier la vie, une classe TreeNodeDirectory a été créée, héritant de TreeNode. Ce nouveau type de nœud porte le chemin complet le concernant (propriété Path). Lors de sa création, on passe en paramètre au constructeur le chemin du dossier. Le constructeur stocke dans la propriété Path ce chemin et compose automatiquement le nom du nœud avec le nom du dossier passé en paramètre. En une seule opération, le chemin est stocké et le nœud affecte sa propre propriété Text.

C'est la fonction ChargerArborescence qui prépare le TreeView. Elle commence par créer le dossier racine puis charge sous le dossier racine les sous-dossiers qui le composent :

La fonction ComposerArborescenceDossier prend en paramètre un nœud du TreeView et lui ajoute comme nœuds enfants tous les dossiers qui le composent. Cette fonction ajoute à chaque nœud un enfant si nécessaire :

C'est dans l'événement BeforeExpand que le nœud est chargé avec ses véritables enfants :

Prise de la photo (capture)

Tout le code de capture est regroupé dans une seule méthode dont le nom est PrendrePhoto. Cette méthode est appelée depuis le menu contextuel du ListView CMEN_PrendrePhoto. Voici comment elle fonctionne :

Important : Une directive a été ajoutée à la fenêtre FormMain pour éviter d'avoir à écrire des noms d'objets et de méthodes à rallonge concernant la capture :

Imports Microsoft.WindowsMobile.Forms

Pour commencer, il faut impérativement qu'un dossier soit sélectionné dans le TreeView pour lancer cette fonction. Un simple test permet de vérifier cela :

Il faut ensuite récupérer le noeud sélectionné dans le TreeView car c'est lui qui nous dira où copier le fichier résultant de la capture :

Le temps est venu de lancer le dialogue de capture. Dans cette application, le fichier de capture sera toujours placé dans le dossier \My Documents dans le fichier AlbumPhoto. Les propriétés DefaultDirectory et DefaultFilename permettent de déterminer cette information. L'extension de ce fichier dépendra des réglages que vous aurez fait au niveau de l'application Caméra (fichier .jpg ou .bmp) c'est pourquoi on ne donne pas l'extension à ce moment là. La propriété Mode détermine le mode de capture (photo, vidéo, vidéo avec son), alors que StillQuality détermine la qualité de la capture :

Si tout c'est bien passé, la variable r est égale à DialogResult.OK. L'opération suivante consiste à demander à l'utilisateur un nom pour cette nouvelle photo, ainsi la photo sera copiée dans son dossier avec le bon nom directement. La saisie du nom a été confiée à une boîte de dialogue maison. Je vous laisse regarder directement dans les sources comment elle est construite.

Une fois le nom de la photo saisi, la capture est copiée dans le bon dossier avec le bon nom. Le ListView est ensuite mis à jour pour prendre en compte la nouvelle entrée. A la fin, la méthode Dispose du dialogue de capture est invoquée pour libérer tout de suite la mémoire.

Conclusion

Grâce à la nouvelle assembly Microsoft.WindowsMobile.Forms.dll fournie en standard avec le SDK Windows Mobile 5, il devient extrêmement simple de lancer des captures par programme. Cette fonctionnalité va permettre de créer très simplement et en full .NET des applications qui seront capables de proposer la capture de photos et/ou de vidéos depuis leur propre interface sans que l'utilisateur ait besoin d'effectuer la moindre opération d'intendance sur les fichiers. Il n'y a plus qu'à imaginer maintenant…

Stéphane Sibué


Développez pour Windows Mobile
Copyright 2001-2006 - Tous droits réservés
Toutes les marques et produits présents dans ces pages sont la propriété exclusive de leurs sociétés respectives.