|
|
||||||||||||||||||
|
Le développement .NET pour Pocket PC et Smartphone est globalement très sympa. Mais il y a parfois des limitations qui font un peu grincer des dents. Si par exemple vous souhaitez utiliser les objets de gestion de temps pour gérer le temps qui passe, vous allez très vite vous rendre compte que la résolution est égale à la seconde ! Alors pour faire un chrono au 1/1000ème de seconde c'est pas gagné !
J'ai eu beau faire le tour de tous les objets proposés par le Compact Framework, rien ne permet de récupérer le temps passé avec une résolution correcte. Avec des machines à 400 Mhz, se limiter à la seconde me semble un gros foutage de gueule ! Bon, espérons qu'avec la version 2 du CF on aura droit à quelque chose de plus pro (on peut rêver non ?). Donc, j'ai ressorti ma documentations sur les API de Windows CE à la recherche d'une fonction qui me retourne le temps passé, avec au moins une résolution au 1/1000ème de seconde. Je n'ai pas cherché longtemps et j'ai trouvé l'API GetTickCount qui semble réponde toute à fait à mes besoins. Voici d'ailleur le texte de l'aide (eVC++) que j'ai trouvé :
Cette fonction nous retourne le nombre de millisecondes écoulées depuis le démarrage de Windows CE. La résolution réelle dépend en fait du constructeur, et enfin, vue que la valeur est codée dans un DWORD, elle retombe à zéro tous les 49.7 jours. Bon, et bien nous allons utiliser cette API pour réaliser notre chronomètre au 1/1000ème de seconde faute de mieux.
Plus simple tu meurs ! Pas de paramètre, juste une valeur de retour. Un DWORD correspond à un Int32 en VB.NET, donc ça nous donne :
Lorsque nous allons mettre en marche notre chrono nous allons prendre note du point de départ, c'est à dire la valeur retounée par GetTickCount à ce moment précis. Dans le programme c'est la variable CheckPoint de type Int32 qui stocke cette valeur. Lorsqu'on arrête le chrono il faut noter le temps qui s'écoule avant la prochaine remise en marche pour être capable de reprendre le comptage à la bonne valeur. Dans le programme c'est la variable TempsInter de type Int32 qui stocke cette valeur. A la mise en marche du chrono nous avons donc la mémorisation du point de départ et la mise en route du timer chargé d'afficher à intervalles réguliers la valeur du chronomètre (le timer s'appelle tout simplement TimerChrono) :
A l'arrêt du chrono il faut arrêter le timer d'affichage et mémoriser le temps intermédiaire :
En ce qui concerne l'affichage du temps passé par lui même je suis passé par les services d'un objet de type TimeSpan. Ce type d'objet permet d'effectuer des opérations sur les durée. Idéal pour notre affaire. La première étape consiste à récupérer le nombre de millisecondes écoulées. En utilisant notre API GetTickCount et nos variables CheckPoint et TempsInter il est simple de le récupérer :
Puis il faut donner cette valeur à un objet de type TimeSpan qui va se charger d'en faire une durée compréhensible. Pour cela on "charge" un objet de type TimeSpan avec la valeur retournée par la méthode "FromMilliseconds" de l'objet "global" TimeSpan (je sais, il ne faut pas confondre de type TimeSpan et l'objet automatiquement mis à disposition par le Framework TimeSpan, mais avec un peu d'habitude on y arrive, je vous assure) :
Voici le code pour créer nos deux chaines :
Si pour l'affichage vous voulez utiliser les services de 2 labels vous ne serez pas du tout satisfait du résultat à cause de très désagréables clignotements lors de leur raffraichissement. Pour éviter cela il est préférable d'afficher les 2 chaînes dans un bitmap (donc en mémoire hors écran) et de "coller" ce bitmap sur le fond de la fenêtre. Cette méthode évite les clignotements. Nos chaînes vont être affichées dans 2 polices de taille différentes. Il convient de préparer ces polices. Pour plus d'efficacités ces polices sont stockées dans des variables globales et elles ne sont créées qu'une seul fois au démarrage de l'application. Il en est de même pour le bitmap de travail et la brosse (le trait) utilisée pour dessiner sur lui. Voici leurs déclarations (au niveau de la fenêtre) :
Et voici leur initialisation depuis l'événement Load de la fenêtre :
Vous pouvez constater que la grande fonte est de type "Tahoma", de taille 36 en gras, que la petite fonte (pour les millisecondes) est aussi de type "Tahoma", de taille 12 et en gras. Le bitmap de travail fait 240x80 pixels et la brosse est noire. Cette initialisation une bonne fois pour toute nous évite de tout refaire à chaque affichage, ce qui pourrait pénaliser pour rien notre chrono (non mais). Pour afficher nos chaînes dans le bitmap de travail nous devons récupérer son contexte graphique et utiliser la méthode "DrawText" aux bonnes coordonnées :
Vous voyez, ce n'est pas très compliqué. Le mieux est de placer ce code dans une fonction, par exemple "AfficherChrono" qui sera appellée depuis l'événement "Tick" du timer chargé de l'affichage. Ne pas oublié aussi d'appeller cette fonction depuis l'événement "Paint" de la fenêtre pour que quoi qu'il arrive l'affichage soit persistant.
Vous pouvez effectuer toutes ces opérations depuis votre PC avec votre Smartphone connecté par ActiveSync. Une fois toutes ces opérations réalisées, vous aurez un accès à Chrono depuis le dossier accessoire de votre téléphone.
Il y a tout de même un problème. J'ai au préalable développé Chrono pour mon Smartphone. Le comportement du Smartphone est différent de celui d'un pocket PC dans le sens où quand il se place en veille il fonctionne encore tout de même et l'OS ne se considère pas comme "arrêté". Avec Pocket PC, lorsqu'on l'arrête, GetTickCount ne décompte plus le temps qui passe et de fait notre chrono s'arrête aussi. Il existe une solution à ce problème. Je me ferai un plaisir de vous en faire part dans un prochain article, ce qui me permettra de mettre en ligne la version 2 de Chrono, celle qui continue à "tourner" même le Pocket PC éteint. A bientôt donc. |
||||||||||||||||||
|
Copyright 2001-2004 - Tous droits réservés Toutes les autres marques et produits présents dans ces pages sont la propriété exclusive de leurs sociétés respectives. |