I. Brève définition▲
Tout le monde connait le bon vieux TTimer qui permet d'exécuter des commandes après un temps donné en millisecondes ? Eh Bien, j'ai le plaisir de vous annoncer que celui-ci n'est pas le meilleur outil quand il est question de rapidité. Le problème avec le TTimer traditionnel c'est qu'il calcule le temps nécessaire en millisecondes avant d'effectuer sa tâche, mais il doit aussi attendre l'ordre du système d'exploitation (Windows) avant de s'exécuter. Si votre processeur est assez occupé et que vous avez demandé au TTimer d'exécuter une commande à chaque 30 millisecondes alors il est très probable qu'il dépasse ce délai avant de s'exécuter parce que Windows l'aura ralenti avec ses tas d'autres processus en file d'attente (Threads). Ce que je vous propose en échange, c'est un simple processus qui permet de créer son propre Timer et par conséquent, son propre Thread (File d'attente). Donc plus besoin d'attendre que Windows exécute ses tas d'autres processus plus importants que Dieu…
II. Explication▲
Le fonctionnement est un jeu d'enfant, je dirais même que c'est similaire à celui du TTimer. Tout d'abord, nous avons besoin de l'aide du Unit MMSystem qui contient la fonction nécessaire à la création de notre Timer alors vous devez inclure la clause Uses MMSystem;. Ensuite, nous aurons besoin d'une variable de type DWord qui représentera le ID de notre Timer. Pour créer le Timer, il suffit d'appeler la fonction suivante :
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution,
LPTIMECALLBACK lpTimeProc, DWORD dwUser, UINT fuEvent);
- uDelay : spécifie le temps à calculer avant de s'exécuter (en millisecondes).
- uResolution : spécifie un temps additionnel si nécessaire (si la valeur est 0 alors le Timer s'exécute le plus rapidement possible).
- lpTimeProc : un pointeur sur une procédure qui sera exécutée chaque fois que le Timer aura atteint le nombre de millisecondes donné. Le pointeur pointe sur une procédure de cette syntaxe-ci :
void (CALLBACK)(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
Donc en Delphi celle-ci se résume à :
Procedure FctTimeCallBack( uTimerID, uMessage: UINT; DwUser, Dw1, Dw2: DWord) StdCall;
Pourquoi StdCall à la fin? C'est une fonction extraite d'une DLL (MMSystem.Dll). - dwUser : données supplémentaires…
- fuEvent : Type de Timer : une fois ou périodique. Ces deux valeurs sont possibles : TIME_ONESHOT ou TIME_PERIODIC.
Pour détruire ce Timer ou plutôt l'arrêter, il suffit d'appeler la procédure suivante : TimeKillEvent( ID_Du_Timer ).
Je vous laisse un programme qui vous démontre la rapidité de ce Timer comparé au TTimer habituel. Pour démontrer cette rapidité, j'utilise un TTimer qui incrémente une variable jusqu'à tant qu'elle atteigne 100 avec un intervalle de une milliseconde. En théorie, cela prendrait exactement 100 millisecondes, mais vous constaterez que le TTimer est loin de prendre ce petit délai, mais en revanche notre Timer personnalisé est très près et assez pour dire qu'il se situe dans les 2-3 millisecondes près de la théorie.
III. Capture d'écran▲
Le bouton démarrer étant caché.
IV. Programme relié▲
Je n'ai rien d'autre à ajouter à part que j'ai envie de vous faire travailler un peu. Servez-vous du TTimer pour dessiner des cercles pendant 1 seconde (1000 millisecondes) et ensuite faites la même chose avec votre nouveau Timer et regardez la différence. Cela démontre vraiment l'intérêt à utiliser ce genre de Timer en graphisme.
Source du composant (miroir)