Des screenmates aux agents Microsoft

NetSwiPE

Les screenmates, personnages animés interactifs habitant sur le bureau de votre ordinateur, sont de simples programmes basés principalement sur la fenêtre écran (0) de Windows. Totalement futiles dans leurs premières versions, ils ont évolué et on les trouve aujourd'hui sous différentes formes, allant du compagnon Office aux tamagoshis…

- Titre : Des screenmates aux agents Microsoft

- Auteur : NetSwiPE

- Parution : 11 décembre 2000

- Mise à jour : 5 janvier 2020

- Licence : © 2000 - 2001 NetSwiPE http://www.netswipe.ch

Sommaire

- I. Évolution/Historique

- II. Les agents Microsofts

- III. Les fenêtres non rectangulaires

- IV. Le programme 'truc'

I - Évolution/Historique

- Le premier screenmate est apparu sous Unix. Inclus dans les environnements graphiques d'Unix (X-Windows), le programme Xeyes (toujours présent dans les distributions actuelles, ex. : depuis une fenêtre console sous Linux + kde ou gnome… démarrez xeyes), affiche à l'écran deux yeux qui suivent les déplacements du pointeur de souris.

- Sous Windows 3.1, le screenmate le plus répandu a sans nul doute été le programme topcat. Toujours fonctionnel sous Windows 9.x, il affiche à l'écran un chat qui s'amuse à courir après le pointeur de la souris.

La technique utilisée par topCat pour afficher le chat, consiste à dessiner sur la fenêtre 0 de Windows. Cette fenêtre est une fenêtre particulière, qui est constituée de l'écran complet. C'est par exemple cette fenêtre qui est utilisée lorsque l'on appuie sur la touche PrintScreen. Pour tracer une ligne sur la diagonale de l'écran, par-dessus toutes les fenêtres, on écrirait :

1. var pp1 : PPoint;

2. hd : HDC;

3. begin

4. hd := getDc(0);

5. movetoex(hd, 0, 0, pp1);

6. lineto(hd, screen.width, screen.height);

7. releasedc(0, hd);

8. end;

Si Topcat est dessiné en mode filaire (seules les lignes de contour sont dessinées), c'est parce qu'il utilise le mode XOR (ou NOT = XOR 255) pour ne pas avoir à sauvegarder l'image de fond (afin de la restituer lorsqu'il se déplace). La séquence d'actions d'une animation traditionnelle (cf. évolution suivante) est : restituer la zone précédente ; sauvegarder la nouvelle zone d'écran où l'on va s'afficher ; combiner notre dessin et la zone ; afficher le résultat. Cette séquence de traitement oblige d'une part à sauvegarder la zone d'écran où l'on va s'afficher, et d'autre part à combiner notre dessin avec la zone d'affichage. Ce processus était à l'époque des cartes graphiques de Windows 3.1 trop coûteux en temps, et générait du flicking (scintillement de la zone qui se réaffichait), c'est pourquoi les programmes ne redessinaient que les contours des objets à déplacer (ex. : déplacement d'une fenêtre), et utilisaient le mode d'affichage XOR présent dans tous les environnements graphiques. Ce mode d'affichage, inverse la couleur du pixel que l'on dessine (le blanc va passer au noir, le noir au blanc…), et comme la fonction XOR est réversible (A XOR B XOR B = A), il suffit de redessiner le chat au même endroit (toujours dans le mode XOR) pour retrouver l'image initiale.

Pour choisir le mode d'affichage dans Windows, on utilise le ROP (Raster Operation Processing) à travers la fonction SetRop2. Le même exemple que précédemment donnerait :

1. var pp1 : PPoint;

2. hd : HDC;

3. begin

4. hd := getDc(0);

5. setrop2(hd, R2_NOT);

6. movetoex(hd, 0, 0, pp1);

7. lineto(hd, screen.width, screen.height);

8. releasedc(0, hd);

9. end;

Un premier appel à cette fonction dessine la diagonale, tandis qu'un deuxième appel l'efface et restitue l'image initiale sans que l'on ait eu besoin de la sauvegarder.

Depuis Delphi, c'est la propriété copymode du TCanvas qui modifie le ROP.

Mais les possibilités des cartes graphiques d'aujourd'hui ont très nettement évolué, et un utilisateur ne saurait se contenter d'une animation filaire. L'augmentation de performances a apporté la possibilité de ne plus afficher que le contour des fenêtres lorsqu'on les déplace, mais tout leur contenu.

Les programmes comme topcat, qui ne restituent pas assez souvent (et pas au bon moment) l'image modifiée, laissent alors une marque sur l'écran.

- Sous Windows 9.x, le premier screenmate à s'être vraiment répandu est sans nul doute esheep. Ce petit programme affiche un mouton réalisant différentes actions humoristiques.

La technique de programmation de ce mouton n'est finalement pas très différente de celle de TopCat. Elle est également basée sur la fenêtre 0 (écran de Windows) qui est utilisée pour capturer l'image de la zone où le mouton va s'afficher (exactement comme pour un programme de capture d'écran). Le mouton n'est pas dessiné directement sur l'écran, mais dans la fenêtre principale du programme esheep, où l'image du fond précédemment capturée a été copiée. Ce qui donne l'impression de dessiner sur l'écran (la fenêtre du mouton n'a pas de bord), et présente l'avantage de bénéficier du mécanisme automatique (clipping) de Windows, pour ce qui est de la restitution du fond lorsque le mouton se déplace (en réalité la fenêtre contenant le mouton). Cette technique fonctionne pour la plupart des utilisations, mais sachant que le mouton ne ressaisit une zone écran, que lorsqu'il se déplace, les positions statiques (ex. : le mouton dort) se traduisent par une erreur du 'trompe l'œil' lorsque le fond ou le mouton est placé est modifié (ex. : déplacement d'une fenêtre sur la zone avec Windows en mode 'affichage du contenu de la fenêtre lors du glissement').

À noter également le site Internet des auteurs de esheep : http://www.geocities.com/siennaj/Esheep2/ avec une galerie d'images où l'on retrouve le style graphique attachant de ces petites bestioles qui a sans nul doute largement contribué au succès de esheep, au-delà de son côté technique.

- L'autre grande famille de screenMates sous Windows 9.x s'est largement propagée au moment des fêtes de Noël. Chacun a reçu et transmis ces petites animations, où l'on voyait une fille habillée en père Noël sortir d'un paquet cadeau. Ces programmes ne sont pas à proprement parler des screenmates, mais plutôt des messagemates, dans la mesure où ils jouent une petite animation et se terminent. La technique de programmation est cependant exactement la même que celle employée dans esheep, pour ce qui est de l'animation. Mais dans la mesure où elle ne se déroule qu'une seule fois, et capture donc l'attention de l'utilisateur, l'animation peut travailler sur de plus grosses images (il y a moins de chances que l'utilisateur vienne la perturber en déplaçant une fenêtre).

- La plupart des autres screenmates sont basés sur la même technique de programmation (simpsons, brucelee…)

- L'évolution suivante est apparue dans un tout autre registre de compagnons, les virtualgirls. Ce programme affiche une 'playmate' miniature dans un coin de l'écran. Au-delà de son contenu, ce programme constitue une évolution dans sa manière de gérer l'affichage des personnages, il n'est jamais pris en défaut lorsqu'on modifie le fond (en déplaçant une fenêtre par exemple) sur lequel il joue l'animation.

À première vue, on pourrait penser que le personnage est dessiné sur la fenêtre 0, comme dans le cas de topcat. Mais l'utilisation d'un programme tel que le programme catch, nous indique que le personnage est dessiné dans une nouvelle fenêtre du programme virtualGirl. Pour étudier le mode de fonctionnement du programme, on réalise alors un programme minimal qui dessine sur la fenêtre 0, une zone noire où le personnage va être animé. Le personnage va alors effacer la zone et on aura un premier renseignement sur sa méthode d'affichage

1. var pp1 : PPoint;

2. hd : HDC;

3. i : integer;

4. begin

5. for i := 900 to 1024 do

6. begin

7. hd := getDc(0);

8. movetoex(hd, i, 0, pp1);

9. lineto(hd, i, screen.height);

10. releasedc(0, hd);

11. end;

12. end;

On s'aperçoit que la zone qui est affectée n'est pas rectangulaire, et correspond en réalité à la somme des différents affichages. Nous avons donc une fenêtre, qui ne modifie pas une zone rectangulaire, mais un contour. À première vue, ce programme utilise une fonctionnalité de Windows, apparue avec Windows 9.x, les fenêtres non rectangulaires. Pour le vérifier, on utilise en premier lieu le programme spy++ de Microsoft, fourni avec l'environnement de développement Visual Studio. Ce programme permet de dessiner le contour d'une fenêtre sélectionnée.

Le résultat se confirme. Le programme virtualGirl crée donc une fenêtre ayant la forme du personnage qu'il affiche. On peut également vérifier cela avec un désassembleur. Sans étudier complètement le code assembleur du programme (ce qui représenterait une tâche énorme quasiment irréalisable), on peut utiliser le désassembleur pour vérifier la présence d'un appel à la fonction setWindowRgn de Windows (fonction permettant de modifier la zone de dessin d'une fenêtre, traditionnellement peu présente dans les programmes Windows).

La technique utilisée par ce screenmate consiste donc à dessiner le personnage dans une fenêtre ayant sa forme. Le mécanisme de clipping de Windows s'occupe alors automatiquement du reste, et il n'est plus nécessaire d'aller recopier l'image écran… Tout se passe exactement comme pour une fenêtre rectangulaire…

Cette technique est celle qui donne les meilleurs résultats et est d'ailleurs utilisée par les agents Microsoft.

II - Les agents Microsofts

Les agents Microsoft sont les plus aboutis et les plus réussis en matière de screenmate. Apparus dans Office sous la forme de 'compagnons',

ils sont installés dans Windows 2000 et disponibles en téléchargement depuis le site de Microsoft : http://msdn.microsoft.com/msagent/

Une fois installés dans Windows, les agents Microsoft sont accessibles depuis delphi via un contrôle ActiveX.

Pour les installer dans Delphi, il faut passer par le menu habituel : component / import activeX control

Le composant TAgent est alors placé dans l'onglet activeX de la palette de composants.

On trouve de nombreux sites traitant de la programmation des agents Microsoft ainsi qu'un kit de développement (sur le site de Microsoft) permettant de créer ses propres agents.

Le principe d'animation des agents est très similaire à celui utilisé par le programme virtualGirl ; le programme dessine dans une fenêtre ayant la forme du personnage, ce qui apporte une qualité d'animation très supérieure aux autres screenmates. Les personnages fournis en exemple (merlin, peedy, robby et genie) ont été dessinés en trois dimensions par des images de synthèse, ce qui leur apporte un jeu d'ombres dans leur mouvement de grande qualité. Réalisés par des spécialistes de l'animation, leurs mouvements sont également très bien rendus. Enfin, les agents intègrent l'utilisation de la dll SAPI (Speakink API) et peuvent donc parler à partir d'un texte fourni sous forme de chaine de caractères. Ils intègrent un moteur de reconnaissance de parole, et savent répondre à une demande prononcée dans le micro du PC.

Les agents Microsofts semblent alors être l'aboutissement en matière de screenmate dans l'environnement Windows. Il reste cependant une large place pour des programmes tels que esheep auquel il ne manque peut-être que quelques fonctionnalités logicielles pour en faire un programme réellement utile dans un PC, au-delà de son côté sympathique.

III - Les fenêtres non rectangulaires

Les screenmates les plus aboutis travaillent avec des fenêtres non rectangulaires… Pour utiliser cette fonctionnalité apparue sous Windows 95, on passe par la fonction setWindowRgn qui affecte une région à une fenêtre. Une région peut être un rectangle dans le cas standard des fenêtres, mais également un cercle, une ellipse… et une combinaison de régions. Le programme ci-dessous crée des trous dans une fenêtre, identifiée à partir de son handle que l'on récupère par exemple à l'aide du programme catch.

1. //---------------------------------------------

2. //--      Programme gruyère

3. //---------------------------------------------

4. //-- © 2000-2001 NetSwiPE

5. //-- htpp://www.netswipe.ch

6. //---------------------------------------------

7. unit Unit1;

9. interface

11. uses

12. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

13. StdCtrls;

15. type

16. TForm1 = class(TForm)

17. ediHandle: TEdit;

18. butGo: TButton;

19. procedure FormCreate(Sender: TObject);

20. procedure butGoClick(Sender: TObject);

21. private

22. public

23. end;

25. var

26. Form1: TForm1;

28. implementation

30. {$R *.DFM}

32. procedure TForm1.FormCreate(Sender: TObject);

33. begin

34. ediHandle.text := inttostr(self.handle);

35. end;

37. procedure TForm1.butGoClick(Sender: TObject);

38. var i, j, x, y : integer;

39. region1, region2 : hRgn;

40. rect : TRect;

41. begin

42. getwindowrect(strtoint(ediHandle.text), rect);

43. region2 := createRectRgn(0,0, rect.Right - rect.Left, rect.Bottom - rect.top);

44. i := (rect.Right - rect.Left) div 20;

45. for j := 1 to i do

46. begin

47. x := random(rect.right - rect.left);

48. y := random(rect.bottom - rect.top);

49. region1 := createEllipticRgn(x, y, x+50, y+50);

50. combineRgn(region2, region2, region1, RGN_DIFF);

51. end;

52. setWindowRgn(strtoint(ediHandle.text), region2, true);

53. end;

55. end.

Le programme complet avec le code source est disponible dans la partie DownLoad.

Mais les agents Microsoft ont un niveau de précision de découpage bien supérieur à un simple assemblage de zones géométriques, la précision va jusqu'au niveau du pixel. Ils utilisent les 'paths'. Sous Windows, il est possible de regrouper une série de commandes de dessin dans un 'path'. L'exemple le plus courant d'utilisation des 'paths' est le format graphique vectoriel des fichiers (ex. : cliparts) portant l'extension WMF (Windows Meta File). Ces fichiers contiennent une suite de commandes graphiques, qui sont envoyées au device (ex. : écran ou imprimante) pour les redessiner… Ainsi, la zone d'affichage pourra être définie au moyen d'un regroupement de commandes graphiques allant du simple point à l'affichage d'un texte dans une fonte particulière.
On utilise ensuite la fonction PathToRegion pour convertir le path en région que l'on affecte ensuite à la fenêtre au moyen de la fonction setWindowRgn.

Dans le cas d'une des images du personnage de merlin l'algorithme serait alors :

1. Démarrer Chemin

2. Pour chaque point de merlin

3. si couleur du point <> couleur transparente alors dessiner point

4. Arreter Chemin

5. Convertir Chemin en Region

6. Affecter Region à Fenêtre

7. Dessiner Merlin dans Fenêtre

IV - Le programme 'truc'

Le programme 'truc', première version du projet 'truc' et 'astuce' est constitué d'un simple personnage se déplaçant sur l'écran, basé sur les techniques de programmation décrites ci-dessus.

'truc' est disponible dans la page download.