Developpez.com - Delphi
X

Choisissez d'abord la catégorieensuite la rubrique :



Des screenmates aux agents microsoft

Le 11 décembre 2000

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és et on les trouve aujourd'hui sous différentes formes, allant du compagnon office aux tamagoshis...

Evolution / 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 :

      var pp1 : PPoint;
    hd : HDC;
    begin
        hd := getDc(0);
        movetoex(hd, 0, 0, pp1);
        lineto(hd, screen.width, screen.height);
        releasedc(0, hd);
    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 ou 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 couteux 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 :

    var pp1 : PPoint;
    hd : HDC;
    begin
        hd := getDc(0);
        setrop2(hd, R2_NOT);
        movetoex(hd, 0, 0, pp1);
        lineto(hd, screen.width, screen.height);
        releasedc(0, hd);
    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 contours 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 un zone écran, que lorsqu'il se déplace, les positions statiques (ex le mouton dort) se traduisent par une erreur du 'trompe l'oeil' 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').

  

A 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 parlé des screenmates, mais plutôt des messagemates, dans la mesure ou 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 apparu 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. 

A 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 dessinne sur la fenêtre 0, une zone noir ou le personnage va être animé. Le personnage va alors effacer la zone et on aura un premier renseignement sur sa méthode d'affichage

var pp1 : PPoint;
hd : HDC;
i : integer;
begin
    for i := 900 to 1024 do
    begin
        hd := getDc(0);
        movetoex(hd, i, 0, pp1);
        lineto(hd, i, screen.height);
        releasedc(0, hd);
    end;
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. A première vue, ce programme utilise une fonctionnalité de Windows, apparu 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 VisualStudio. 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ésultat et est d'ailleurs utilisée par les agents Microsoft.

 

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écialisites de l'animation, leur mouvement 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ère. Ils intègrent un moteur de reconnaissance de parole, et savent répondre à une demande prononcé 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 manquent 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.

 

Les fenêtres non rectangulaires

Les screenmates les plus aboutis travaillent avec des fenêtres non rectangulaires... Pour utiliser cette fonctionnalité apparu 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 desous 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.

//---------------------------------------------
//--      Programme gruyère
//---------------------------------------------
//-- © 2000-2001 NetSwiPE
//-- htpp://www.netswipe.ch
//---------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    ediHandle: TEdit;
    butGo: TButton;
    procedure FormCreate(Sender: TObject);
    procedure butGoClick(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ediHandle.text := inttostr(self.handle);
end;

procedure TForm1.butGoClick(Sender: TObject);
var i, j, x, y : integer;
    region1, region2 : hRgn;
    rect : TRect;
begin
  getwindowrect(strtoint(ediHandle.text), rect);
  region2 := createRectRgn(0,0, rect.Right - rect.Left, rect.Bottom - rect.top);
  i := (rect.Right - rect.Left) div 20;
  for j := 1 to i do
  begin
    x := random(rect.right - rect.left);
    y := random(rect.bottom - rect.top);
    region1 := createEllipticRgn(x, y, x+50, y+50);
    combineRgn(region2, region2, region1, RGN_DIFF);
  end;
  setWindowRgn(strtoint(ediHandle.text), region2, true);
end;

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 font 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 :

Démarrer Chemin
    Pour chaque point de merlin
        si couleur du point <> couleur transparente alors dessiner point
Arreter Chemin
Convertir Chemin en Region
Affecter Region à Fenêtre
Dessiner Merlin dans Fenêtre

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.

 

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

Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -