Flylib.com

Books Software

 
 
 

Getting Started

Getting Started

You need to be aware of a few things before you use the Microsoft Agent components . The first is that the core components must be installed on the client computer before a speech-enabled Web site will work properly. The second thing you must make sure of is that the agent characters have been installed on the computer. And the third thing you must be sure about is that the speech module, which lets the Microsoft Agent components speak through your sound system, is installed.

A page on www.ASPNET-Solutions.com has links to the Microsoft Agent components that must be installed on client computers for speech enabled web applications. You can see this page in Figure 21.1. If you need to install anything, you can go to this page (www.ASPNET-Solutions.com/Chapter_21.htm) and download the components.

Figure 21.1. Links to the Agent Downloads Are on www.ASPNET-Solutions.com.

graphics/21fig01.jpg

Note that Windows 2000 and Windows XP already have the Microsoft Agent and its components installed. Also note that if the Microsoft Agent core components and the speech components are not installed before a user goes to a Web page that is speech-enabled with Microsoft Agent, then an automatic download will start (after the user is prompted for permission—that is, if the browser security settings specify a prompt) that will install the needed components.

NOTE: Many Microsoft Agent characters are available, and many more are being created. Now that you have the Microsoft Agent components installed on your computer, you have only to download additional characters (files with .ACS extensions) as they become available and save them to your C:\WINDOWS\MSAGENT\CHARS or C:\WINNT\MSAGENT\CHARS folder, depending on your operating system. (The installation programs save the characters to the correct directory without any intervention on your part.) You can look for other characters by going to www.MSAgentRing.org. You'll find dozens of additional agent characters that you can download and install.


The SpeechVB Application

I've written a class that encapsulates Microsoft Agent's functionality. I named it the Agent class, and for the purposes of this chapter I have used this class in a demo program called SpeechVB. Of course, there was a C# version on the Web site at www.ASPNET-Solutions.com. You can view the code online or just simply download the source code.

The Agent class works by emitting Java script code into the HTML stream. Essentially, the Microsoft Agent features are controlled within a Web page by either VBScript or JavaScript. Because I find JavaScript easier to work with, I opted for emitting JavaScript code rather than VBScript code, but the entire class could have been constructed so that it output VBScript code instead of JavaScript code. In this case, though, I followed Microsoft's lead because Microsoft emits JavaScript code for many of its server-side controls, such as the for-validation controls.

Using the SpeechVB Application

The SpeechVB application is available at www.UsingASP-Solutions.com Web site. To find it, simply click the chapter examples from the main page, go to Chapter 21, and then find the link that says "Run the SpeechVB Application."

When the application runs, it doesn't do much except display the genie in the upper-left corner of the client's computer screen. You can see this demonstrated in Figure 21.2.

Figure 21.2. This Application Makes Use of the Agent Class. When It First Runs, the Agent Is in the Upper-Left Corner.

graphics/21fig02.jpg

It's important to note that the Agent operates on screen coordinates, and not on window coordinates. What I mean by that is if you use the x and y position for the overall screen, starting at 0,0 in the upper-left corner, then those are the coordinate positions you will use when you move the genie around. A window, however, has its own coordinate system, which is relative to its own upper-left corner. This means that the window has a number of systems, and it starts at 0,0, which is relative to its own upper-left corner. But that starting position is almost always going to be somewhere to the right and to the bottom of the main screen's origin. Microsoft Agent does not operate based on window coordinates that are relative the screen. It operates on literal and absolute screen coordinates.

You can have the agent characters speak. All you must do is enter a phrase that you want the character to speak, and then click the Make Him Speak button, as shown in Figure 21.3.

Figure 21.3. You Can Have the Agent Character Say Any Text That You Enter in the Speech Field.

graphics/21fig03.jpg

Two fields in the Web Form let users enter screen coordinates to which the Agent character will go. For instance, you can type in an x value of 100 to the y value of 400, and the Agent character will go to that exact screen coordinate. Remember, these are screen coordinates and not relative window coordinates. You can see the Agent character moved to a different location in Figure 21.4.

Figure 21.4. You Can Make the Agent Component Go to Any Screen Coordinates by Entering Values into the X and Y Fields.

graphics/21fig04.jpg

Microsoft Agent characters can have any number of animations built in. The Genie, for instance, can use binocular search, blow a trumpet , and spin like a tornado . In all, this animation can add to the enjoyment of the Agent characters, and can enhance a presentation significantly. In Figure 21.5, you can see one of the Agent's animations.

Figure 21.5. This Simulation Uses One of the Agent's Effective Animations.

graphics/21fig05.jpg

The SpeechVB Program is pretty simple. But as you can see from this section, it is very effective in showing what these Microsoft Agent technologies are capable of.

The SpeechVB Program Code

The SpeechVB Program has two major parts . The first part is the Agent class, which encapsulates the Agent functionality. The second part is a relatively simple work form that uses the Agent class.

For your convenience, I have collected all the methods in Table 21.1. This table shows you method names , what code module they're in, what listing number you can see them in, and a short description. This table will help you as you study the program code, and modify it to suit your own needs, and it will help you to understand the code in general.

Table 21.1. The SpeechVB Application Methods

Method Name

Code Module

Listing

Description

Hide()

Agent.vb

21.1

Causes the Agent character to hide from view.

Show()

Agent.vb

21.1

Causes the Agent character to show itself.

MoveToSpecial()

Agent.vb

21.1

Uses special values such as AgentCenterX and AgentBottomY to move to screen-relative locations.

Speak()

Agent.vb

21.1

Causes the Agent character to speak.

Gesture()

Agent.vb

21.1

Causes the Agent character to gesture from some predefined gestures.

Think()

Agent.vb

21.1

Causes the Agent character to go through thinking motions .

Whisper()

Agent.vb

21.1

Causes the Agent character to whisper some text.

Play()

Agent.vb

21.1

Causes the Agent character to play an animation.

Character()

Agent.vb

21.2

This is a property. It allows the selection of the Agent character, such as Genie or Merlin.

Render()

Agent.vb

21.3

This causes the Agent class to render the JavaScript to the HttpResponse .

OutputObjects()

Agent.vb

21.4

This method calls OutputAgentControl() and OutputSpeechControl() so that the objects are emitted into the HTML stream.

OutputAgentControl()

Agent.vb

21.4

This method outputs the Agent control object into the HTML stream.

OutputSpeechControl()

Agent.vb

21.4

This method outputs the speech control object into the HTML stream.

OutputScript()

Agent.vb

21.5

This method calls a number of methods, which in turn emit the JavaScript code for the agent control.

StartScript()

Agent.vb

21.5

This method emits the script start tag.

OutputVariables()

Agent.vb

21.5

This method emits the JavaScript variables .

OutputGetPositions()

Agent.vb

21.5

This method emits the method that gets the special screen positions that can be used to center the Agent character.

OutputOnLoad()

Agent.vb

21.5

This method emits the method that is called when the window loads.

OutputLoadAgent()

Agent.vb

21.5

This method emits the method that loads the Agent character.

OutputSetCharObj()

Agent.vb

21.5

This method emits the method that sets the character.

OutputCheckLoadStatus()

Agent.vb

21.5

This method emits the method that checks the load status.

OutputLoadError()

Agent.vb

21.5

This method emits the method that shows a load error.

OutputCommands()

Agent.vb

21.5

This method outputs the method that contains all of the Agent commands.

EndScript()

Agent.vb

21.5

This method emits the script end tag.

DoAgentStuff()

Default.aspx.vb

21.6

This method creates an Agent method, adds the appropriate commands (based on the user interface), and then renders into the HTML stream.

ShowAnimation()

Default.aspx.vb

21.7

This method responds to a button click and generates a random number that determines which of the four predefined animations will play.

There are a number of methods that a consumer of the Agent class will make. These methods do things such as make the Agent character hide itself, make the Agent character show itself, and move the Agent character around on the screen. Essentially, what happens when these methods are called is that the appropriate Agent JavaScript command is added to the list of commands. The list of commands is contained in a class member variable named m_ScriptList . This object is a StringCollection that is iterated through during the Render process, when the JavaScript is emitted into the HTML stream.

Just to show you how easy it is to use the Agent class to create an Agent script, let's take a look at a simple code snippet. The following example shows how to substantiate an Agent class, make the Agent character show itself, and have the Agent character say something:

C#
Agent ag = new Agent();
ag.Show();
ag.Speak( "Hi there!" );
VB
Dim ag as new Agent()
ag.Show()
ag.Speak("Hi there!")

It's important to note that you perform this code from your .aspx source code. Further, you must not call this code within a form. The following .aspx code shows the correct and incorrect places to instantiate and use Agent objects:


Correct

<%@ Page Language="vb" AutoEventWireup="false"
  Codebehind="Default.aspx.vb"
  Inherits="SpeechVB.WebForm1"%>
<HTML>
  <HEAD>
    <title>Agent Page</title>
    <%
      Dim ag as new Agent()
      ag.Show()
      ag.Speak("Hi there!")
    %>
  </HEAD>
  <body>
      <FORM id="Form1" method="post" runat="server">
      </FORM>
  </body>
</HTML>

Incorrect

<%@ Page Language="vb" AutoEventWireup="false"
  Codebehind="Default.aspx.vb"
  Inherits="SpeechVB.WebForm1"%>
<HTML>
  <HEAD>
    <title>Agent Page</title>
  </HEAD>
  <body>
      <FORM id="Form1" method="post" runat="server">
       <%
        Dim ag as new Agent()
        ag.Show()
        ag.Speak("Hi there!")
      %>
      </FORM>
  </body>
</HTML>

If you take a look at some of the methods in Listing 21.1, you'll see that they're simple. But others are a bit more arcane. The Whisper() method, for instance, outputs a Speak command with some embedded special text that the Agent character will interpret as a whisper. Essentially, if you start any Agent speaking command with CHR=\whisper , then the Agent character will whisper whatever you tell it to say. And that's what the Whisper() method is doing. Another one of these methods that should be noted as requiring special explanation is the MoveToSpecial() method. The JavaScript code contains a number of special variables. These are variables that calculate the center of the screen, the bottom of the screen, the right of the screen, and so forth. Table 21.2 shows the special variables and their meanings.

To use the MoveToSpecial() method, you simply give the method a string that specifies one of these special variable names. For instance, if you want to move the very center of the screen along both the x- and y-axis, you can use the following code:

ag.MoveToSpecial("AgentCenterX", "AgentCenterY")
Table 21.2. The Java Script Variables Containing Screen Coordinate Values

Variable

Description

AgentLeftX

This contains the x value for the left of the screen.

AgentCenterX

This contains the x value for the center of the screen.

AgentRightX

This contains the x value for the right of the screen.

AgentTopY

This contains the y value for the top of the screen.

AgentCenterY

This contains the y value for the center of the screen.

AgentBottomY

This contains the y value for the bottom of the screen.

Listing 21.1 The List of Commands, and the Methods That Make It Easy to Add the Commands
Dim m_ScriptList As New StringCollection()

Public Sub Hide()
    m_ScriptList.Add("Hide();")
End Sub

Public Sub Show()
    m_ScriptList.Add("Show();")
End Sub

Public Sub Move(ByVal x As Integer, ByVal y As Integer)
    m_ScriptList.Add("MoveTo(" + Convert.ToString(x) + "," + _
      Convert.ToString(y) + ");")
End Sub

Public Sub MoveToSpecial(ByVal strX As String, ByVal strY As String)
    m_ScriptList.Add("MoveTo(" + strX + "," + strY + ");")
End Sub

Public Sub Speak(ByVal strText As String)
    m_ScriptList.Add("Speak(" + Chr(34) + strText + Chr(34) + ");")
End Sub

Public Sub Gesture(ByVal x As Integer, ByVal y As Integer)
    m_ScriptList.Add("Gesture(" + Convert.ToString(x) + "," + _
      Convert.ToString(y) + ");")
End Sub

Public Sub Think()
    m_ScriptList.Add("Think();")
End Sub

Public Sub Whisper(ByVal strText As String)
    m_ScriptList.Add("Speak(" + Chr(34) + "\Chr=\" + _
      Chr(34) + "Whisper\" + Chr(34) + "\" + strText + Chr(34) + ");")
End Sub

Public Sub Play(ByVal strText As String)
    m_ScriptList.Add("Play(" + Chr(34) + strText + Chr(34) + ");")
End Sub

Listing 21.2 shows the Character property. This property lets you set a character before the Agent class. The demo program that's on www.ASPNET-Solutions.com has two characters in its drop-down list: Genie and Merlin. You can offer your users many other options if they have the characters installed and/or if you make the characters available for download from your Web application. Once again, you can find dozens of additional Agent characters at www.MSAgentRing.org.

Listing 21.2 The Character Property
Dim _character As String = "Genie"
Public Property Character() As String
    Get
        Return _character
    End Get
    Set(ByVal Value As String)
        _character = Value
    End Set
End Property

Listing 21.3 shows the Render() method. This is a very simple method that calls two other methods. One is the OutputObjects() method, and the other is the OutputScript() method. By calling the other two methods, the Render() method stays simple and understandable.

Listing 21.3 The Render() Method Must Be Called to Output the Script into the HTML Document.
Public Sub Render(ByVal Response As System.Web.HttpResponse)
    Response.Write(vbCrLf)
    OutputObjects(Response)
    OutputScript(Response)
End Sub

Listing 21.4 shows the OutputObjects() method and the two methods that it calls: the OuputAgentControl() method and the OutputSpeechControl() method.

The OutputAgentControl() method simply emits the HTML code that embeds the Agent control ActiveX into the HTML document. Listing 21.4 shows the AgentOutputControl() method, but right above that, in gray, it shows the actual HTML that this method emits.

You can also see the OutputSpeechControl() method; directly above this method, in gray, is the speech object that is emitted into the HTML document that embeds the speech ActiveX controls.

Listing 21.4 The Methods That Output the Agent and Speech Objects, and the HTML Code They Emit
Private Sub OutputObjects(ByVal Response As System.Web.HttpResponse)
    OutputAgentControl(Response)
    OutputSpeechControl(Response)
End Sub


This code is emitted by the OutputAgentControl() method.



<Object ID="AgentControl" Width=0 Height=0


ClassID="CLSID:D45FD31B-5C6E-11D1-9EC1-00C04FD7081F"


CodeBase="#VERSION=2,0,0,0">


</Object>

Private Sub OutputAgentControl(ByVal Response As _
   System.Web.HttpResponse)
    Response.Write("<Object ID=" + Chr(34) + "AgentControl" + _
      Chr(34) + " Width=0 Height=0" + vbCrLf)
    Response.Write("  ClassID=" + Chr(34) + _
      "CLSID:D45FD31B-5C6E-11D1-9EC1-00C04FD7081F" + Chr(34) + vbCrLf)
    Response.Write("  CodeBase=" + Chr(34) + _
      "#VERSION=2,0,0,0" + Chr(34) + ">" + vbCrLf)
    Response.Write("</Object>" + vbCrLf)
End Sub


This code is emitted by the OutputSpeechControl() method.



<Object ID="L&HTruVoice" Width=0 Height=0


ClassID="CLSID:B8F2846E-CE36-11D0-AC83-00C04FD97575"


CodeBase="#VERSION=6,0,0,0">


</Object>

Private Sub OutputSpeechControl(ByVal Response As _
  System.Web.HttpResponse)
    Response.Write("<Object ID=" + Chr(34) + "L&HTruVoice" + Chr(34) + _
      " Width=0 Height=0" + vbCrLf)
    Response.Write("  ClassID=" + Chr(34) + _
      "CLSID:B8F2846E-CE36-11D0-AC83-00C04FD97575" + Chr(34) + vbCrLf)
    Response.Write("  CodeBase=" + Chr(34) + _
      "#VERSION=6,0,0,0" + Chr(34) + ">" + vbCrLf)
    Response.Write("</Object>" + vbCrLf)
End Sub

Listing 21.5 contains a number of methods that generate and emit JavaScript into the HTML document. The first method you can see in Listing 21.5 is the OutputScript() method. This method simply calls all the methods that in turn emit JavaScript as the HTML document. The first method you will want to take a look at is the StartScript() method. This method simply emits the StartOfScript tag, as seen in the gray above the StartScript() method.

The next method you will want to take a look at is the OutputVariables() method. This method emits the JavaScript variables that maintain the state of the Agent character. Above the OutputVariables() method, in gray, you can see the actual JavaScript code that is emitted into the HTML document.

To make the MoveToSpecial() method work, a number of variables must be initialized. They are all the variables that can be seen in Table 21.2. These variables are all initialized based on the screen width and height. They contain the left, middle, and right x -coordinates, and the top, middle, and bottom y -coordinates. The actual code that is emitted into the JavaScript can be seen in gray above the OutputGetPositions() method. There is a Window_Onload() method for the JavaScript. This method actually loads the Agent character and checks its status. The Window_Onload() method is output by the OutputOnLoad() method.

Listing 21.5 The Methods That Output the JavaScript Code and the JavaScript Code That They Emit
Private Sub OutputScript(ByVal Response As System.Web.HttpResponse)
    StartScript(Response)
    OutputVariables(Response)
    OutputOnLoad(Response)
    OutputLoadAgent(Response)
    OutputSetCharObj(Response)
    OutputCheckLoadStatus(Response)
    OutputLoadError(Response)
    OutputGetPositions(Response)
    OutputCommands(Response)
    EndScript(Response)
End Sub


This code is emitted by the StartScript() method.



<Script Language="JavaScript">

Private Sub StartScript(ByVal Response As System.Web.HttpResponse)
    Response.Write("<Script Language=" + Chr(34) + "JavaScript" + _
      Chr(34) + ">" + vbCrLf)
End Sub


This code is emitted by the OutputVariables() method.



var Agent;


var UsedChars;


var AgentID;


var AgentACS;


var AgentLoaded;


var LoadReq;


var HideReq;


var AgentLeftX, AgentCenterX, AgentRightX;


var AgentTopY, AgentCenterY, AgentBottomY;


UsedChars = "Genie";


AgentID = "Genie";


AgentACS = "Genie.acs";


AgentLoaded = false;

Private Sub OutputVariables(ByVal Response As System.Web.HttpResponse)
    Response.Write("var Agent;" + vbCrLf)
    Response.Write("var UsedChars;" + vbCrLf)
    Response.Write("var AgentID;" + vbCrLf)
    Response.Write("var AgentACS;" + vbCrLf)
    Response.Write("var AgentLoaded;" + vbCrLf)
    Response.Write("var LoadReq;" + vbCrLf)
    Response.Write("var HideReq;" + vbCrLf)
    Response.Write("var AgentLeftX, AgentCenterX, AgentRightX;" + _
      vbCrLf)
    Response.Write("var AgentTopY, AgentCenterY, AgentBottomY;" + _
      vbCrLf)
    Response.Write("UsedChars = " + Chr(34) + _character + Chr(34) + _
      ";" + vbCrLf)
    Response.Write("AgentID = " + Chr(34) + _character + Chr(34) + _
      ";" + vbCrLf)
    Response.Write("AgentACS = " + Chr(34) + _character + ".acs" + _
      Chr(34) + ";" + vbCrLf)
    Response.Write("AgentLoaded = false;" + vbCrLf)
End Sub


This code is emitted by the OutputGetPositions() method.



function GetScreenPositions()


{


var ScreenWidth = window.screen.width;


var ScreenHeight = window.screen.height;


if ((ScreenWidth == 0)  (ScreenHeight == 0))


{


ScreenWidth = 800;


ScreenHeight = 600;


}


AgentCenterX =


(parseInt(ScreenWidth / 2) - parseInt(Agent.Width / 2));


AgentRightX = (ScreenWidth - Agent.Width);


AgentCenterY =


(parseInt(ScreenHeight / 2) - parseInt(Agent.Height / 2));


AgentBottomY = (ScreenHeight - Agent.Height);


}

Private Sub OutputGetPositions(ByVal Response As _
  System.Web.HttpResponse)
    Response.Write("function GetScreenPositions()" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  var ScreenWidth = window.screen.width;" + vbCrLf)
    Response.Write("  var ScreenHeight = window.screen.height;" + _
      vbCrLf)
    Response.Write("  if ((ScreenWidth == 0)  " + _
      "(ScreenHeight == 0))" + vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    ScreenWidth = 800;" + vbCrLf)
    Response.Write("    ScreenHeight = 600;" + vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  AgentCenterX = (parseInt(ScreenWidth / 2) " + _
      "- parseInt(Agent.Width / 2));" + vbCrLf)
    Response.Write("  AgentRightX = (ScreenWidth - Agent.Width);" + _
      vbCrLf)
    Response.Write("  AgentCenterY = (parseInt(ScreenHeight / 2) - " + _
      "parseInt(Agent.Height / 2));" + vbCrLf)
    Response.Write("  AgentBottomY = (ScreenHeight - Agent.Height);" + _
      vbCrLf)
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the OutputOnLoad() method.



Window_OnLoad();


function Window_OnLoad()


{


AgentControl.Connected = true;


AgentLoaded = LoadLocalAgent(AgentID, AgentACS);


if( !AgentLoaded )


{


AgentLoaded = LoadLocalAgent(AgentID, "");


}


if (AgentLoaded)


{


SetCharObj();


}


CheckLoadStatus();


}

Private Sub OutputOnLoad(ByVal Response As System.Web.HttpResponse)
    Response.Write("Window_OnLoad();" + vbCrLf)
    Response.Write("function Window_OnLoad()" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  AgentControl.Connected = true;" + vbCrLf)
    Response.Write("  AgentLoaded=LoadLocalAgent(AgentID,AgentACS);" + _
      vbCrLf)
    Response.Write("  if( !AgentLoaded )" + vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    AgentLoaded = LoadLocalAgent(AgentID, " + _
      Chr(34) + Chr(34) + ");" + vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  if (AgentLoaded)" + vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    SetCharObj();" + vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  CheckLoadStatus();" + vbCrLf)
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the OutputLoadAgent() method.



function LoadLocalAgent(CharID, CharACS)


{


AgentControl.RaiseRequestErrors = false;


if (CharACS == "")


{


LoadReq = AgentControl.Characters.Load(CharID);


}


else


{


LoadReq = AgentControl.Characters.Load(CharID, CharACS);


}


AgentControl.RaiseRequestErrors = true;


if (LoadReq.Status != 1)


{


return(true);


}


return(false);


}

Private Sub OutputLoadAgent(ByVal Response As System.Web.HttpResponse)
    Response.Write("function LoadLocalAgent(CharID, CharACS)" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  AgentControl.RaiseRequestErrors = false;" + _
      vbCrLf)
    Response.Write("  if (CharACS == " + Chr(34) + Chr(34) + ")" + _
      vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    LoadReq=AgentControl.Characters.Load(CharID);"+_
      vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  else" + vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    LoadReq = AgentControl.Characters.Load(" + _
      "CharID, CharACS);" + vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  AgentControl.RaiseRequestErrors = true;" + vbCrLf)
    Response.Write("  if (LoadReq.Status != 1)" + vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    return(true);" + vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  return(false);" + vbCrLf)
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the OutputSetCharObj() method.



function SetCharObj()


{


Agent = AgentControl.Characters.Character(AgentID);


Agent.LanguageID = 0x409;


}

Private Sub OutputSetCharObj(ByVal Response As System.Web.HttpResponse)
    Response.Write("function SetCharObj()" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  Agent = " + _
      "AgentControl.Characters.Character(AgentID);" + vbCrLf)
    Response.Write("  Agent.LanguageID = 0x409;" + vbCrLf)
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the OutputCheckLoadStatus() method.



function CheckLoadStatus()


{


if (!AgentLoaded)


{


LoadError();


return(false);


}


window.status = "";


AgentScript();


return(true);


}

Private Sub OutputCheckLoadStatus(ByVal Response As _
  System.Web.HttpResponse)
    Response.Write("function CheckLoadStatus()" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  if (!AgentLoaded)" + vbCrLf)
    Response.Write("  {" + vbCrLf)
    Response.Write("    LoadError();" + vbCrLf)
    Response.Write("    return(false);" + vbCrLf)
    Response.Write("  }" + vbCrLf)
    Response.Write("  window.status = " + Chr(34) + Chr(34) + ";" + _
      vbCrLf)
    Response.Write("  AgentScript();" + vbCrLf)
    Response.Write("  return(true);" + vbCrLf)
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the OutputLoadError() method.



function LoadError()


{


var strMsg;


window.status = "";


strMsg = "Error Loading Character: "+ AgentID + "\n";


strMsg = strMsg +


"This Microsoft Agent Script requires the character(s):\n";


strMsg = strMsg + UsedChars;


alert(strMsg);


}

Private Sub OutputLoadError(ByVal Response As System.Web.HttpResponse)
    Response.Write("function LoadError()" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  var strMsg;" + vbCrLf)
    Response.Write("  window.status = " + Chr(34) + Chr(34) + ";" + _
      vbCrLf)
    Response.Write("  strMsg = " + Chr(34) + _
      "Error Loading Character: " + Chr(34) + "+ AgentID + " + _
      Chr(34) + "\n" + Chr(34) + ";" + vbCrLf)
    Response.Write("  strMsg = strMsg + " + Chr(34) + _
      "This Microsoft Agent Script requires the character(s):\n" + _
      Chr(34) + ";" + vbCrLf)
    Response.Write("  strMsg = strMsg + UsedChars;" + vbCrLf)
    Response.Write("  alert(strMsg);" + vbCrLf)
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the OutputCommands() method.



function AgentScript()


{


GetScreenPositions();


Agent.Show();


}

Private Sub OutputCommands(ByVal Response As System.Web.HttpResponse)
    Response.Write("function AgentScript()" + vbCrLf)
    Response.Write("{" + vbCrLf)
    Response.Write("  GetScreenPositions();" + vbCrLf)
    Dim i As Integer
    For i = 0 To m_ScriptList.Count - 1
        Response.Write("  Agent." + _
          Convert.ToString(m_ScriptList(i)) + vbCrLf)
    Next
    Response.Write("}" + vbCrLf)
End Sub


This code is emitted by the EndScript() method.



</Script>

Private Sub EndScript(ByVal Response As System.Web.HttpResponse)
    Response.Write("</Script>" + vbCrLf)
End Sub

Listing 21.6 shows the method named DoAgentStuff() . This method is called from the default .aspx code. The method can be seen, however, in the default aspx.cs code module.

The first thing that happens in the DoAgentStuff() method is that the Hide user interface object (which is a CheckBox) is checked to see whether the Agent must be hidden or shown. If the Agent character must be shown, then an Agent class is substantiated and the Agent class's character is set to the value found in the drop-down list that contains the available Agent characters.

Four animations can be selected that put the Agent character through its paces. These animations are contained within four case statements in the DoAgentStuff() method. The actual randomly selected animation that will be performed is contained in a session variable named AnimationNumber .

Below the four animations is code that is called if an animation has not been selected. If coordinates have been entered into the editable X and Y test field then the Agent character will be moved. The Show() method is called to make the Agent character visible. Then, any speech is in the speech text box, the SpeakMethod() will be called, thus making the Agent character say the phrase. The last thing that is done is the Render() method is called, which actually outputs all the JavaScript code into the HTML document.

Listing 21.6 The DoAgentStuff() method responds to the user interface and creates the appropriate commands.
Public Sub DoAgentStuff()
    If Not Hide.Checked Then
      Dim ag As New Agent()
      ag.Character = Convert.ToString(Character.SelectedItem.Text)

      If Not Session("AnimationNumber") Is Nothing Then
        Select Case Convert.ToInt32(Session("AnimationNumber"))
          Case 0
            ag.MoveToSpecial("AgentCenterX", "AgentCenterY")
            ag.Show()
            ag.Speak("This is animation one.")
            ag.Play("Congratulate")
            ag.Speak("You now have the power to speech-enable your " + _
              Web applications.")
            ag.MoveToSpecial("AgentLeftX", "AgentCenterY")
            ag.Speak("I can go to the left of the screen.")
            ag.Play("LookLeft")
            ag.MoveToSpecial("AgentRightX", "AgentBottomY")
            ag.Speak("I can go to the bottom right of the screen.")
            ag.Play("Wave")
            ag.MoveToSpecial("AgentCenterX", "AgentCenterY")
            ag.Speak("I am magic.")
            ag.Play("DoMagic2")
          Case 1
            ag.Show()
            ag.Speak("This is animation two.")
            ag.Speak("Imagine being able to provide online " + _
              "training that has speech and animation.")
            ag.Move(50, 50)
            ag.Speak("Your training would be far more interesting " + _
              "to users.")
            ag.Move(100, 100)
            ag.Speak("You would hold the attention of those whom " + _
              "you are training.")
            ag.Move(150, 150)
            ag.Speak("This would increase the return on your " + _
              "training investment.")
            ag.Play("Congratulate_2")
            ag.Move(200, 200)
            ag.Speak("Many people learn better when they hear and " + _
              "read, rather than when they simply read.")
            ag.Move(250, 250)
            ag.Play("Explain")
            ag.Speak("Why not consider using the Microsoft Agents " + _
              "for your online training?")
            ag.MoveToSpecial("AgentCenterX", "AgentCenterY")
          Case 2
            ag.MoveToSpecial("AgentRightX", "AgentTopY")
            ag.Show()
            ag.Speak("This is animation three.")
            ag.Play("Greet")
            ag.Speak("What if you had students with reading " + _
              "disabilities?")
            ag.MoveToSpecial("AgentLeftX", "AgentBottomY")
            ag.Speak("What if you had students who were blind?")
            ag.Play("Explain")
            ag.MoveToSpecial("AgentCenterX", "AgentCenterY")
            ag.Speak("The Microsoft Agent technology would be " + _
              "the perfect way to deliver Web based content.")
            ag.Play("Process")
          Case 3
            ag.Show()
           ag.Speak("This is animation four.")
            ag.Play("Search")
            ag.Speak("I see there is lots of space on this screen " + _
              "for moving around.")
            ag.MoveToSpecial("AgentLeftX", "AgentBottomY")
            ag.Speak("Here I am down here.")
            ag.MoveToSpecial("AgentRightX", "AgentBottomY")
            ag.Speak("Here I am over here.")
            ag.MoveToSpecial("AgentRightX", "AgentTopY")
            ag.Speak("Wow, now I am here.")
            ag.MoveToSpecial("AgentLeftX", "AgentTopY")
            ag.Speak("Back to where I started.")
            ag.MoveToSpecial("AgentCenterX", "AgentCenterY")
            ag.Play("Surprised")
            ag.Speak("Now I am the center of attention!")
        End Select
        Session("AnimationNumber") = Nothing
    Else
      Try
        ag.Move(Convert.ToInt32(X.Text), Convert.ToInt32(Y.Text))
      Catch
      End Try
      ag.Show()
      If Speech.Text.Length > 0 Then
        ag.Speak(Speech.Text)
        Speech.Text = ""
      End If
    End If
    ag.Render(Response)
  End If
End Sub

When users click the Show Animation button, the ShowAnimation_Click() method is fired , as shown in Listing 21.7. This method simply selects a random number from 0 to 3 and then stores that number in a session variable named Animation Number .

Listing 21.7 This Method Responds to the Show Animation Button. It Generates a Random Number from 0 to 3 That Will Be Used to Select the Animation to Run.
Private Sub ShowAnimation_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles ShowAnimation.Click
    Dim rnd As New Random()
    Dim nRandom As Integer
    nRandom = rnd.Next(4)
    If nRandom > 3 Then
        nRandom = 3
    End If
    Session("AnimationNumber") = nRandom
End Sub

Although using the Agent class is simple and straightforward, doing so will add immensely to your Web applications. And you could easily enhance the SpeechVB application to do much, much more.