Platform SDK: Agent |
You can also access Microsoft Agent services from a Java applet. Many of the functions accessible through the Microsoft Agent interfaces return values through parameters passed by reference. In order to pass these parameters from Java, it is necessary to create single-element arrays in your code and pass them as parameters to the appropriate function. If you're using Microsoft Visual J++™ and have run the Java Type Library Wizard on the Microsoft Agent server, refer to the summary.txt file to review which functions require array arguments. The procedure is similar to that in C; you use the IAgentEx interface to create an instance of the server, then load the character:
private IAgentEx m_AgentEx = null; private IAgentCharacterEx m_Merlin[] = {null}; private int m_MerlinID[] = {-1}; private int m_RequestID[] = {0}; private final String m_CharacterPath = "merlin.acs"; public void start() { // Start the Microsoft Agent Server m_AgentEx = (IAgentEx) new AgentServer(); try { Variant characterPath = new Variant(); characterPath.putString(m_CharacterPath); // Load the character m_AgentEx.Load(characterPath, m_MerlinID, m_RequestID); }
The procedure is slightly different when loading characters from a HTTP remote location such as a Web site. In this case the Load method is asynchronous and will raise a COM exception of E_PENDING (0x8000000a). You will need to catch this exception and handle it correctly as is done in the following functions:
// Constants used in asynchronous character loads private final int E_PENDING = 0x8000000a; private final int NOERROR = 0; // This function loads a character from the specified path. // It correctly handles the loading of characters from // remote sites. // This sample doesn't care about the request id returned // from the Load call. Real production code might use the // request id and the RequestComplete callback to check for // a successful character load before proceeding. public int LoadCharacter(Variant path, int[] id) { int requestid[] = {-1}; int hRes = 0; try { // Load the character m_AgentEx.Load(path, id, requestid); } catch(com.ms.com.ComException e) { // Get the HRESULT hRes = e.getHResult(); // If the error code is E_PENDING, we return NOERROR if (hRes == E_PENDING) hRes = NOERROR; } return hRes; } public void start() { if (LoadCharacter(characterPath, m_MerlinID) != NOERROR) { stop(); return; } // Other initialization code here . . . }
Then get the IAgentCharacterEx interface that enables you to access its methods:
// Get the IAgentCharacterEx interface for the loaded // character by passing its ID to the Agent server. m_AgentEx.GetCharacterEx(m_MerlinID[0], m_Merlin); // Show the character m_Merlin[0].Show(FALSE, m_RequestID); // And speak hello m_Merlin[0].Speak("Hello World!", "", m_RequestID);
Similarly, to be notified of events, you must implement either the IAgentNotifySink or the IAgentNotifySinkEx interface, creating and registering an object of that type:
... // Declare an Agent Notify Sink so that we can get // notification callbacks from the Agent server. private AgentNotifySinkEx m_SinkEx = null; private int m_SinkID[] = {-1}; public void start() { ... // Create and register a notify sink m_SinkEx = new AgentNotifySinkEx(); m_AgentEx.Register(m_SinkEx, m_SinkID); … // Give our notify sink access to the character m_SinkEx.SetCharacter(m_Merlin[0]); ... }
In order to access Microsoft Agent from a Java applet, you must generate Java classes that you install with the applet. You can use the Visual J++ Java Type Library Wizard, for example, to generate these files. If you plan to host the applet on a Web page, you will need to build a signed Java CAB inclusive of the generated class files that download with the page. The class files are necessary to access the Microsoft Agent Server since it is a COM object, that executes outside of the Java sandbox. To learn more about Trust-Based Security for Java, see http://www.microsoft.com/java/security.