Microsoft Agent sous Delphi

Ze Waren

Ce tutoriel va vous décrire et vous apprendre à utiliser Microsoft Agent sous Delphi.

- Titre : Microsoft Agent sous Delphi

- Auteur : Ze Waren

- Parution : 15 août 2004

- Mise à jour : 26 décembre 2019

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. PREMIÈRE PARTIE : DESCRIPTION

- II. DEUXIÈME PARTIE : TÉLÉCHARGEMENT ET INSTALLATION DE MS AGENT

- II-A. Télécharger les fichiers nécessaires

- II-B. Installer L'ActiveX dans Delphi

- III. TROISIÈME PARTIE : FONCTIONNEMENT DE BASE

- III-A. Charger des agents

- III-B. Faire parler l'agent

- III-C. Les tags pour changer les caractéristiques de la voix

- III-D. Les requêtes pour synchroniser les actions

- III-E. Interrompre des requêtes

- IV. QUATRIÈME PARTIE : FONCTIONS AVANCÉES

- IV-A. Connaitre dynamiquement la liste des animations d'un agent

- IV-B. Connaitre dynamiquement la liste des noms des agents chargés dans un TAgent

- V. CINQUIÈME PARTIE : PRATIQUE

- V-A. Lire simplement un texte

- V-B. Lire un TStrings

- V-C. Mettre en pause ou arrêter la lecture d'un TStrings

- VI. SIXIÈME PARTIE : LA RECONNAISSANCE VOCALE

- VI-A. Théorie

- VI-B. Pratique

- VII. SEPTIÈME PARTIE : COMPLÉMENTS

- VII-A. Diffuser MS Agent dans ses propres applications

- VII-B. Liens

- CRÉDITS \ LICENCE

I - PREMIÈRE PARTIE : DESCRIPTION

Pour ceux qui auraient téléchargé ce tutoriel sans savoir ce qu'est Microsoft Agent, voici la réponse : Microsoft Agent est un ActiveX, permettant principalement la synthèse vocale. Concrètement, vous entrez quelque chose dans un TEdit, et MS Agent se charge de convertir cela en une phrase, que vous pouvez entendre (si vous avez une carte son et des enceintes, bien sûr…).

Pour plus de confort vis-à-vis de l'utilisateur, MS Agent se matérialise par des personnages, apparaissant sur votre écran, tous avec un certain nombre d'animations : ce sont les agents.
Microsoft en fournit quatre sur son site, les voici :

,,,

Mais il existe divers sites sur Internet proposant gratuitement des dizaines d'agents, plus variés les uns que les autres. Voir à la fin de ce tutoriel pour des liens.

II - DEUXIÈME PARTIE : TÉLÉCHARGEMENT ET INSTALLATION DE MS AGENT

II-A - Télécharger les fichiers nécessaires

Microsoft fournit sur son site les fichiers nécessaires à l'installation de l'ActiveX.
Rendez-vous donc sur http://www.microsoft.com/msagent, et récupérez :

- The Microsoft Agent core components. 395 Ko ;

- le ou les langages qui vous intéressent. 129 Ko par langage ;

- un ou plusieurs des quatre personnages (il est conseillé de tous les prendre) tailles différentes selon les personnages ;

- un text-to-speech engine, pourquoi pas le français… 2300 Ko pour le français ;

- The Speech Control Panel. 927 Ko.

II-B - Installer L'ActiveX dans Delphi

Vous avez téléchargé un tas de fichiers, c'est bien beau, mais maintenant il faut installer l'ActiveX sur votre système, et tant qu'à faire dans Delphi. Pour cela, exécutez tous les exécutables récupérés précédemment : un tas de copies de fichiers apparaissent puis disparaissent. C'est tout !

Maintenant, ouvrez Delphi, et ouvrez la boite de dialogue d'importation d'ActiveX, située dans le menu Composant.

Choisissez Microsoft Agent Control 2.0 (Version 2.0), et cliquez sur Installer, pour ajouter l'unité dans un paquet de votre choix, que vous recompilerez ensuite.

Si tout se passe bien, vous disposez alors d'un nouveau composant :
TAgent

III - TROISIÈME PARTIE : FONCTIONNEMENT DE BASE

Voilà, vous avez fraichement installé un bel ActiveX dans votre Delphi, préféré. Vous allez maintenant pouvoir apprendre à vous en servir.

III-A - Charger des agents

Le contrôle TAgent que vous avez installé sert à créer une liaison avec le serveur Microsoft Agent, qui, lui, s'occupera de tout. La toute première chose à faire est de connecter l'agent à ce serveur, en passant sa propriété Connected à true.

property TAgent.Connected : WordBool;

Exemple :

Agent1.Connected := true;

Une fois l'ActiveX connecté, il faut charger un ou plusieurs personnages, en utilisant la fonction Load de la propriété Characters :

function IAgentCtlCharacter.Load(const CharacterID : WideString ; LoadKey : OleVariant ) : IAgentCtlRequest;

En effet, la propriété Characters du TAgent permet la gestion des différents personnages, dont le chargement.
Dans cette fonction :

- CharacterID correspond au nom que le serveur doit attribuer au personnage. C'est ce nom qui permettra d'identifier plus tard l'agent chargé ;

- LoadKey correspond au nom de fichier de l'agent à charger. Pour connaitre la liste des agents installés sur votre système, allez dans le menu démarrer\exécuter et tapez : %WinDir%\msagent\chars\

Vous pouvez entrer des strings comme valeurs pour ces deux paramètres :

Agent1.Characters.Load('Peedy', 'Peedy.acs');

Pour accéder ensuite aux agents chargés, il faut passer par la fonction :

function IAgentCtlCharacter.Character(const CharacterID : WideString) : IAgentCtlCharacterEx;

Mais pour plus de simplicité, la meilleure solution reste encore de créer une variable IAgentCtlCharacterEx et de l'assigner à la fonction précédente.

var
MonAgent : IAgentCtlCharacterEx;
...
MonAgent := Agent1.Characters.Character('Peedy');

Enfin, pour que votre agent se montre, utilisez la méthode Show :

function IAgentCtlCharacterEx.Show(Fast : OleVariant) : IAgentCtlRequest;

Fast indique si l'agent doit apparaitre instantanément ou en utilisant son animation. Mettez false pour avoir l'animation.
Note : la fonction Hide fonctionne de la même façon, mais sert à cacher l'agent.

MonAgent.Show(false);

III-B - Faire parler l'agent

Une fois l'agent chargé, le plus gros du travail est fait. Pour faire parler votre personnage, utilisez la fonction speak :

function IAgentCtlCharacterEx.Speak(Text, Url : OleVariant) : IAgentCtlRequest;

Text spécifie le texte que l'agent doit dire et URL, indique un fichier wav à utiliser à la place de la synthèse vocale (facultatif). Ces deux paramètres sont aussi des strings.

MonAgent.Speak('Bonjour à tous','');

Vous pouvez aussi faire penser l'agent, en utilisant la fonction Think :

function IAgentCtlCharacterEx.Think(const Text : OleVariant) : IAgentCtlRequest;

Text spécifie le texte que l'agent doit penser. L'agent ne dit pas le texte, mais l'affiche juste dans une bulle adéquate.

MonAgent.Think('J''ai faim !','');

Mais les agents ne sont pas que des images fixes, ils incluent tous des animations, plus ou moins nombreuses selon les personnages.

Pour invoquer une animation, utilisez la fonction Play :

function IAgentCtlCharacterEx.Play(const Animation : WideString) : IAgentCtlRequest;

Animation spécifie le nom de l'animation que l'agent doit jouer. Ce paramètre est aussi un string. (Voir plus bas dans ce tutoriel comment récupérer dynamiquement la liste des animations.)

MonAgent.Play('read');

III-C - Les tags pour changer les caractéristiques de la voix

Pour faire varier la voix de l'agent ou pour différentes choses, Microsoft a conçu une série de paramètres à inclure dans le texte de l'agent : les tags.
Les tags sont à mettre entre des « \ », sous la forme :
\parametre=valeur\Texte Normal

Exemple : texte chuchoté

MonAgent.Speak('\Chr="Whisper"\Chut, merlin fait la sieste !','');

Les différents tags

Chr : indique comment l'agent doit prononcer le texte :

MonAgent.Speak('\Chr="Whisper"\Chut, merlin fait la sieste !','');

- « Normal » : le texte est prononcé normalement. ;

- « Whisper » : le texte est chuchoté ;

- « Monotone » : le texte est plat, monotone.

Ctx : prévient l'agent qu'il va prononcer une adresse mail ou une adresse simple :

MonAgent.Speak('\Ctx="E-Mail"\fzwte@free.fr','');

- « Unknown » : texte par défaut : pas de changement ;

- « E-Mail » : prépare l'agent à prononcer une adresse Mail ;

- « Address » : prépare l'agent à prononcer une adresse ou un numéro de téléphone.

Emp : le mot qui suit ce tag est accentué.

MonAgent.Speak('\Emp\QuelqueChose','');

Lst : ce tag doit être employé seul, sans aucun paramètre ni aucun texte : l’agent répète alors son dernier texte lu, en incluant les tags de celui-ci.

MonAgent.Speak('\Lst\','');

Map : ce tag permet de faire dire quelque chose à l'agent en affichant autre chose dans sa bulle :
\Map="exteParlé"="TexteDeLaBulle"\

MonAgent.Speak('\Map="Ma bulle n''affiche pas ça !"="Ecoutez bien"\','');

Mrk : ajoute un BookMark (marque-page), dans le texte. Cela ne change rien à la voix, mais génère un événement OnBookMark du TAgent associé au personnage. Ce tag prend en paramètre un integer de votre choix, mais plus grand que 0 et non égal à 2147483647 ou à 2147483646. Ce nombre est passé en paramètre de l'événement du TAgent.

MonAgent.Speak('\Mrk=123455678\Ce tutoriel est vraiment génial ! ','');

Pau : indique à l'agent de faire une pause. Ce tag prend un integer en paramètre égal au nombre de millisecondes à attendre.

MonAgent.Speak('Bonjour, attendez 2 secondes\Pau=2000\ Voilà, merci.','');

Rst : remet tous les tags à leurs valeurs par défaut.

MonAgent.Speak('\Rst\','');

Spd : indique à l'agent sa vitesse de parole. Ce tag prend un nombre en paramètre indiquant le nombre de mots par minute de l'agent.

MonAgent.Speak('\Spd=300\ Je parle à 300 mots par minutes !','');

Vol : indique le volume du son de l'agent. Ce tag prend un nombre en paramètre correspondant au volume. 0 = silence et 65535 = volume maximum.

MonAgent.Speak('\Vol=65530\ Le volume est presque au maximum !','');

À vous d'utiliser ces tags selon vos envies, vous pouvez faire autant de mélanges que vous voulez (sauf pour le tag Lst).

III-D - Les requêtes pour synchroniser les actions

Comme les actions des agents ne s'exécutent pas dans le thread de notre application, mais dans celui du serveur, il est impossible d'écrire ces deux lignes :

procedure TForm1.Button1Click(Sender: TObject);
begin
MonAgent.Speak('Je parle pour ne rien dire','');
ShowMessage('Fin des paroles de l''agent');
end;

En effet, le message s'afficherait alors que l'agent commencerait à peine à lire son texte.

C'est pour cela que Microsoft a ajouté l'événement OnRequestComplete dans la classe TAgent. Cet événement s'exécute chaque fois qu'une requête est terminée.

TAgentRequestComplete = procedure(Sender : TObject; const Request: IDispatch) of object;

Sender correspond à l'objet qui appelle la procédure et Request indique quelle requête vient d'être terminée.

Il faut donc d'abord identifier les requêtes, en utilisant le type IAgentCtlRequest :

var
Request1 : IAgentCtlRequest;

Vous avez déjà vu ce type : c'est ce que renvoient les fonctions d'animations et de paroles. Il suffira donc de l'assigner à une de ces opérations.

Exemple :

Request1 := MonAgent.Play('read');

Ainsi, en utilisant le code suivant, le message n'arrive qu'après l'action terminée.

procedure TForm1.Agent1RequestComplete(Sender: TObject;
const Request: IDispatch);
begin
if Request = Request1 then
ShowMessage('Fin des paroles de l''agent');
end;

Attention : l'événement OnRequestComplete s'exécute uniquement si vous avez déclaré et affecté une variable de requête. Si vous mettez juste MonAgent.speak('tralalala',''); , il n'y aura aucun appel à l'événement.

III-E - Interrompre des requêtes

Il est tout à fait possible d'interrompre ou d'annuler des requêtes, qu'elles soient en cours d'exécution ou encore dans la liste de la queue.
Pour cela, la première procédure à utiliser s'appelle Stop.

procedure IAgentCtlCharacterEx.Stop(Request : OleVariant);

Request correspond à la requête à stopper ou à annuler.

Vous pouvez aussi annuler toutes les requêtes d'un certain type, en utilisant la procédure StopAll.

procedure IAgentCtlCharacterEx.StopAll(Types : OleVariant);

Types spécifie quel type d'action doit être annulé :

- 'Move' annule tous les déplacements de l'agent ;

- 'Speak' annule toutes les paroles de l'agent ;

- 'Play' annule toutes les animations de l'agent.

Attention : la méthode Stop ne permet d'annuler que les requêtes de l'agent qui la possède. Pour qu'un agent annule les requêtes d'un autre, utilisez la méthode Interrupt :

function IAgentCtlCharacterEx.Interrupt(const InterruptRequest : IDispatch) : IAgentCtlRequest;

InteruptRequest correspond à la requête à annuler. Cette fonction peut annuler les requêtes de n'importe quel agent.

IV - QUATRIÈME PARTIE : FONCTIONS AVANCÉES

IV-A - Connaitre dynamiquement la liste des animations d'un agent

Comme chaque agent possède ses propres animations, il devient nécessaire de pouvoir en connaitre la liste en exécution.
Voici une fonction capable de réaliser cette opération :

uses ActiveX;

function GetAgentAnimationNames(Agent : IAgentCtlCharacterEx; SL: TStrings) : Boolean;
const
IID_IEnumVariant: TGUID = (D1:$00020404;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));
var
IEnumVar : IEnumVariant;
BufferAnimationName : OLEVariant;
Retrieved : Cardinal;
hRes : HResult;
begin
Result := False;
if not Assigned(Agent) then Exit;

if Agent.AnimationNames.Enum.QueryInterface(IID_IEnumVariant, IEnumVar) = S_OK then
begin
Result := True;
repeat
hRes := IEnumVar.Next(1, BufferAnimationName, Retrieved);
if Retrieved = 1 then
SL.Add(BufferAnimationName);
until hRes <> S_OK;
end;
end;

Je ne vais pas tenter de vous expliquer comment marche cette fonction : c'est un tutoriel sur MS Agent, pas sur les interfaces.
Agent spécifie l'agent dont on doit lister les animations et SL correspond à un TSrings qui accueillera la liste (comme un bête « memo1.lines »). La fonction renvoie true si elle a réussi à lister les animations et false dans le cas contraire.

IV-B - Connaitre dynamiquement la liste des noms des agents chargés dans un TAgent

Si vous ne souhaitez pas utiliser de variables pour garder en mémoire la liste des agents chargés, vous pouvez utiliser cette fonction :

uses ActiveX;

function GetAgentNames(Agent : TAgent; SL: TStrings): Boolean;
const
IID_IEnumVariant: TGUID = (D1:$00020404;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));
var
IEnumVar : IEnumVariant;
ID : IDispatch;
BufferAnimationName : OLEVariant;
Retrieved : Cardinal;
hRes : HResult;
begin
Result := False;
if Not Assigned(Agent) then Exit;

if Agent.Characters.Enum.QueryInterface(IID_IEnumVariant, IEnumVar) = S_OK then
begin
Result := True;
repeat
hRes := IEnumVar.Next(1, BufferAnimationName, Retrieved);
if Retrieved = 1 then
begin
ID := BufferAnimationName;
SL.Add(IAgentCtlCharacter(ID).Name);
end;
until hRes <> S_OK;
SL.Delete(SL.Count-1);
end;
end;

Vous remarquerez l'étrange ressemblance entre cette fonction et celle du dessus. C'est le même principe.
Agent spécifie le TAgent dont on doit lister les agents et SL correspond à un TSrings qui accueillera la liste. La fonction renvoie true si elle a réussi à lister les agents et false dans le cas contraire.

V - CINQUIÈME PARTIE : PRATIQUE

V-A - Lire simplement un texte

Si vous avez suivi les parties précédentes de ce tutoriel, le code suivant ne vous posera pas de problème :

var
MonAgent : IAgentCtlCharacterEx;

procedure TForm1.FormCreate(Sender: TObject);
begin
Agent1.Connected := true;
Agent1.Characters.Load('Peedy', 'Peedy.acs'); //Ou un autre
MonAgent := Agent1.Characters.Character('Peedy');
MonAgent.Show(false);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
MonAgent.Speak(Edit1.Text, '');
end;

Exécutez l'application, Peedy vient se placer en haut à gauche de votre écran. Entrez quelque chose dans l'édit et cliquez sur le bouton : Peedy lit ce que vous avez entré. Si vous ne mettez rien, une magnifique exception se produira.

V-B - Lire un TStrings

Faire lire un TEdit à un agent, c'est bien joli, mais la plupart des utilisateurs ont pour ambition de faire lire un TStrings à leur agent ; que ce soit un memo ou une autre variable.
Beaucoup sont alors tentés d'utiliser un simple :

procedure TForm1.Button1Click(Sender: TObject);
var
i : word;
begin
for i := 0 to Memo1.Lines.Count - 1 do
if Memo1.Lines.Strings[i] <> '' then
begin
MonAgent.Speak(Memo1.Lines.Strings[i], '');
end;
end;

Cette solution fonctionne, mais pose un gros problème : l'agent fait une pause après chaque fin de ligne, ce qui donne un effet disgracieux à la lecture.
La solution consiste alors à séparer la lecture en groupes de mots et non plus en fonction des lignes du TStrings. De ce fait, l'agent ne fera plus de pause à chaque fin de ligne, mais dès qu'il rencontrera un signe de ponctuation (point, virgule, etc.).
Voici une fonction capable d'effectuer cette opération :

function ExtractSentences(Sl : TStrings; SentenceList : TStrings): boolean;
var
MaxiString : WideString;
BS : string;
Count : word;
i : word;
Phrases : array of string;
begin
MaxiString := '';
for i := 0 to SL.Count - 1 do
MaxiString := MaxiString + SL.Strings[i]+' ';
MaxiString := Trim(MaxiString);

if MaxiString = '' then
begin
result := false;
Exit;
end;

result := true;
repeat
Count := 1;
SetLength(Phrases, length(Phrases)+1);
Phrases[Length(Phrases)-1] := '';
repeat
BS := MaxiString[Count];
Phrases[Length(Phrases)-1] := Phrases[Length(Phrases)-1] + BS;
inc(Count);
until ( BS = '.' ) or ( BS = '!' ) or ( BS = '?' ) or ( BS = ',' ) or ( BS = ';' )
or ( (Count > 150) and (BS = ' ') ) or (Count-1 = Length(MaxiString));
MaxiString := copy(MaxiString, Count, length(MaxiString)-(Count-1));
if Phrases[Length(Phrases)-1][1] = ' ' then
Phrases[Length(Phrases)-1] := copy(Phrases[Length(Phrases)-1], 2, Length(Phrases[Length(Phrases)-1])-1);
until Length(MaxiString) = 0;

SentenceList.Clear;
for i := 0 to Length(Phrases) - 1 do
SentenceList.Add(Phrases[i]);
end;

SL spécifie le TStrings contenant le texte, et SentenceList correspond au TStrings qui accueillera le texte à faire lire par l'agent.
Pour ceux qui n'auraient toujours pas compris, voici un exemple d'utilisation de cette fonction :

procedure TForm1.Button1Click(Sender: TObject);
var
i : word;
BufferStringList : TStrings;
begin
BufferStringList := TStringList.Create;
ExtractSentences(Memo1.Lines, BufferStringList);
for i := 0 to BufferStringList.count - 1 do
if BufferStringList.Strings[i] <> '' then
begin
MonAgent.Speak(BufferStringList.Strings[i], '');
end;
BufferStringList.Free;
end;

Remarque : si vous avez téléchargé le zip complet de ce tutoriel, vous pouvez ouvrir la démo numéro deux, qui comporte un éditeur de texte complet permettant la lecture du texte.

V-C - Mettre en pause ou arrêter la lecture d'un TStrings

Faites bien la différence entre l'arrêt et la mise en pause d'une lecture.

Pour arrêter une lecture, rien de plus simple : il suffit d'interrompre une requête (voir plus haut).

Pour mettre en pause une lecture, ça se corse un peu : MS Agent n'inclut aucune fonction ! La seule solution reste alors de faire lire le texte morceau par morceau, en utilisant les requêtes.

Exemple : on fait lire la première ligne d'un TStrings en créant par la même occasion une requête. Ensuite, on fait lire les autres lignes à partir de l'événement OnRequestComplete (en utilisant une variable pour savoir où on en est). Pour mettre en pause, il suffit d'interrompre la requête en cours, et comme le numéro de la ligne en cours est toujours dans une variable, on peut reprendre la lecture d'où en était.

Cette section n'est pas plus détaillée pour l'instant. Intégrer un exemple complet dans cette page s'avérerait trop complexe. Vous pouvez néanmoins consulter la démo numéro 2, intégrant parfaitement ce concept.

VI - SIXIÈME PARTIE : LA RECONNAISSANCE VOCALE

Encore une (bonne) surprise de Microsoft : les agents peuvent utiliser des moteurs de reconnaissance vocale, et ainsi permettre l'exécution de commandes en interaction avec la voix. Bien que cette partie aurait pu faire à elle seule un tutoriel complet, elle sera un peu expliquée ici, sans trop trop de détails.

VI-A - Théorie

Si vous n'êtes pas sûr d'avoir installé un moteur de reconnaissance vocale, rendez-vous dans votre panneau de configuration, et double-cliquez sur l'icône Speech (si vous ne l'avez pas, allez télécharger le Speech Control Panel (SpchCpl.exe) sur le site de Microsoft).
Vérifiez ensuite que vous avez bien au moins un Speech Input. Si vous n'en avez pas, direction le site de Microsoft pour charger the Microsoft® Speech Recognition (attention : 6 Mo !). Durant l'installation de ce dernier, un assistant vous permet de vérifier que votre microphone fonctionne.
Voilà, vous êtes paré pour intégrer la reconnaissance vocale dans vos applications !

Voici les principes de base :

- on peut associer des commandes aux agents. Exemple : Peedy peut avoir une commande et merlin une autre ;

- un ou plusieurs mots peuvent être assignés à une commande, qui sera exécutée lorsque l'agent les entendra ;

- il faut dire à l'agent d'écouter, sinon rien ne se passera ! ;

- on peut supprimer ou modifier des commandes déjà existantes.

Malheureusement, Microsoft ne fournit pas de reconnaissance vocale en français. Il faudra donc adopter un accent anglais, et ne pas oublier de changer la langue de l'agent :

MonAgent.LanguageID:=$409;

L'interface IAgentCtlCharacterEx contient une propriété Commands, qui contient tout ce qui est relatif aux commandes :

property IAgentCtlCharacterEx.Commands : IAgentCtlCommandsEx;

Pour ajouter une commande à un agent, il suffit d'utiliser la fonction Add de ce magnifique objet :

function IAgentCtlCommandsEx.Add(const Name: WideString; Caption: OleVariant; Voice: OleVariant;
Enabled: OleVariant; Visible: OleVariant): IAgentCtlCommand;

Ici, name spécifie le nom de la commande, qui servira ensuite à l'identifier au niveau du serveur. Caption est le texte qui doit apparaitre dans le popup menu de l'agent. Voice spécifie les mots à utiliser par la reconnaissance vocale (voir plus bas comment formater ce paramètre). Enabled spécifie si la commande doit être active ou non. Pour finir, Visible définit si la commande doit apparaitre dans le popup menu de l'agent.

Le paramètre voice doit être formaté selon le modèle suivant :
'(QuelqueChose)' pour un seul mot, ou '(Mot1 | Mot2 | … | Motx)' pour plusieurs mots.

Voici quelques exemples d'utilisation de cette fonction :

Add('mailbox', 'Lancer Outlook Express', '(courriel)', true, true);
Add('notepad', 'Lancer le bloc-notes', '(bloc-notes | papier),', true, true);
Add('rien', '', '(fantome),', false, false);

Le dernier exemple ne sert à rien, puisque sa commande n'est pas activée.

Vous pouvez toujours accéder aux commandes déjà chargées, en utilisant la fonction Command :

function IAgentCtlCommandsEx.Command(const Name : WideString): IAgentCtlCommandEx;

Name spécifie le nom de la commande à récupérer (le premier paramètre de la fonction add).
La fonction renvoie l'objet correspondant à la commande demandée. Cet objet possède les propriétés Voice, Caption, Visible, ou encore Enabled, qui servent à redéfinir ou accéder aux données de la commande.

Les autres fonctions de gestion des commandes sont : Remove, pour en supprimer, RemoveAll pour toutes les supprimer, Count pour en obtenir le nombre et Insert pour en ajouter une à un endroit précis dans la liste (dans cette dernière fonction, RefName correspond au nom de la commande qui doit précéder ou suivre celle à ajouter; et Before est un booléen spécifiant si la commande doit être ajoutée avant ou après la commande « RefName »).

C'est là que vous vous dites : c'est bien, mais où est-ce qu'on met le code à exécuter des commandes ?

La solution est simple : lorsqu’une commande est déclenchée (soit par reconnaissance vocale soit par le popup menu de l'agent), l'événement OnCommand du TAgent s'agite. Cet événement contient en paramètre une variable de type IAgentCtlUserInput, qui contient les informations relatives à la commande responsable de l'appel. La propriété Name de ce paramètre contient le nom de la commande invoquée. Il ne reste plus qu'à affecter du code source en fonction de cette propriété.

Une fois que les commandes sont prêtes, il faut dire à l'agent d'écouter (pour la reconnaissance vocale). Pour ce faire, on peut utiliser la fonction Listen des agents :

function IAgentCtlCharacterEx.Listen(Listen: WordBool): WordBool;

Vous pouvez aussi utiliser la touche Arrêt Défil de votre clavier pour dire à votre agent d'écouter (maintenez-la enfoncée et parlez, ou appuyez dessus brièvement et parlez pendant deux secondes).

Note : vous pouvez aussi faire cacher un agent en disant « hide », et en appeler un autre par son nom.

VI-B - Pratique

Vu que la partie théorie n'est pas très claire, voici un petit exemple d'utilisation des commandes :

procedure TForm1.Button1Click(Sender: TObject);
begin
MonAgent.LanguageID:=$409;
MonAgent.Commands.Add('mailbox', 'Lancer Outlook Express', '(courriel),', true, true);
MonAgent.Commands.Add('notepad', 'Lancer le bloc-notes', '(notepad)', true, true);
end;

Ajoutez simplement deux commandes à l'agent.

uses ShellAPI;

procedure TForm1.Agent1Command(Sender: TObject; const UserInput: IDispatch);
var
CommandName : string;
begin
CommandName := IAgentCtlUserInput(UserInput).Name;
if CommandName = 'notepad' then
ShellExecute(handle, 'open', 'notepad', nil, nil, SW_NORMAL)
else if CommandName = 'mailbox' then
ShellExecute(handle, 'open', 'msimn', nil, nil, SW_NORMAL);
end;

Agit en fonction de la commande reconnue (lance soit un bloc note, soit Outlook Express).

Cette section n'est pas plus détaillée pour l'instant. Intégrer un exemple complet dans cette page s'avérerait trop complexe. Vous pouvez néanmoins consulter la démo numéro 3, intégrant parfaitement ce concept.

VII - SEPTIÈME PARTIE : COMPLÉMENTS

VII-A - Diffuser MS Agent dans ses propres applications

Du fait que Microsoft Agent n'est pas fourni par défaut dans toutes les versions de Windows, il faut le distribuer avec ses applications.
Voici la liste des fichiers à distribuer et à exécuter lors de l'installation de votre application :

- MSagent.exe ;

- SPCHAPI.EXE ;

- un ou plusieurs agents ;

- agtX040C.exe | ou un autre langage ;

- LHTTSFRF.EXE | ou un autre TTS.

Total (sans agents et compressé) : environ 3,5 Mo. Rien ne vous empêche bien sûr d'ajouter d'autres fichiers, tels des langages.

Attention ! Si vous souhaitez distribuer MS Agent dans vos applications, vous devez d'abord obtenir une licence sur le site de Microsoft (gratuit).

VII-B - Liens

Site officiel de MSAgent : http://www.microsoft.com/msagent
The Microsoft Agent WebRing : http://www.msagentring.org/
Pour plus d'informations détaillées, allez télécharger le fichier d'aide sur le site de Microsoft.

Où trouver des agents :

- The Agentry (en anglais) : 500 agents à télécharger gratuitement. http://www.agentry.net/

- Sur les nombreux sites de The Microsoft Agent WebRing.

CRÉDITS \ LICENCE

Ce tutoriel a été écrit par Ze Waren.
Contact : fzwte@free.fr.
Ce tutoriel est disponible en téléchargement sur le site de l'auteur : http://fzwte.free.fr/
Copyright Ze Waren juillet 2004.

L'auteur espère que vous avez apprécié son tutoriel, et encore plus qu'il vous a servi à quelque chose.