Microsoft Agent is widely used. We can add it to common applications for use by local systems, or embed it into HTML documents for Internet/Intranet use. Microsoft Agent supports C/C ++, Visual Basic, Java, JScript, VBScript, and other programming languages. It also provides programmers with two programming methods: OLE Automation server and ActiveX control, essentially, both programming methods belong to the scope of OLE technology and are built on the basis of COM (Component Object Model, Component Object Model. ActiveX control can be easily called using VC ++'s MFC class library or VB and other programming tools that support ActiveX. However, ActiveX Control hides the details of many OLE technologies, if we want to deepen our understanding of a COM object, we should directly use its COM interface for programming. Starting from this point, this article describes the basic programming methods for the COM interface of Microsoft Agent, hoping to play a role in attracting others.
Basic OLE programming knowledge
Early OLE (now known as OLE 1) appeared in Windows 3.1 for the first time. Its main purpose is to generate compound documents, this allows documents of an application to include data (objects) of other applications through link or embedding ). As software component technology becomes increasingly important, Microsoft has designed OLE 2 based on OLE 1, which can be used to implement reusable software components at the binary level, in addition, it is quite easy to control the version of these components and expand their functions. The architecture of OLE 2 is designed to be open and scalable, so OLE 3 or 4 will not appear in the future. After years of development, today's OLE has included OLE Automation, COM, COM +, DCOM, ActiveX, and many other technologies. They are ActiveDirectory (a key technology that will be used for NT 5.0) OLE Messaging, DirectX, Active Controls, ActiveX Scripting, and Task Scheduler. OLE is no longer an abbreviation of Object Linking and Embedding. It becomes an independent word, software Component Integration Technology specifically used to represent Microsoft.
COM is the foundation of OLE technology. It specifies how objects communicate with each other. objects that comply with the COM specifications are also called COM objects. According to COM, objects can be written in any language and communicate with the outside world through interfaces. An interface refers to a group of specific function calls (methods) provided by an object. Each object can have multiple interfaces, and different objects can implement the same interface, the client calls the object function through the interface pointer of the object. OLE specifies that components can be reused at the binary level. Therefore, the client program cannot directly access the internal data of the object, and the interface must be used to read or set the attributes of the object. Each interface is inherited from an IUnknown interface. You must re-implement the IUnknown Methods: QueryInterface, AddRef, and Release, the customer program calls QueryInterface to obtain other interface pointers of the object. AddRef and Release respectively add and subtract one reference count of the object. When the reference count is zero, the object will be released. The general procedure for a client program to call a COM object is to first create an object, then obtain the required interface pointer, call the corresponding function, and finally release the interface pointer and object.
Basic Method for C ++ program to call Microsoft Agent
Based on the basic knowledge described above, let's take a look at how to call Microsoft Agent in the C ++ program.
1. settings and options
The programming tool used in this article is Visual C ++ 5.0. The program is a general Win32 application. To enable the program to correctly compile the connection and run, you must first have AgtSvr. h and AgtSvr-i.c are two files that define the COM interface for Microsoft Agent, they can be at Microsoft's MS Agent Site (http://www.microsoft.com/workshop/
Prog/agent/), or download Microsoft's latest Internet Client SDK or Platform SDK. Then, add the following libraries to the Project/Settings/Link menu: ole32.lib, oleaut32.lib, uuid. lib, odbc32.lib odbccp32.lib. Make sure that Microsoft Agent and animated character data are installed in the system.
2. Create a Microsoft Agent object
You need to initialize OLE before creating an OLE object. This is done by the OleInitialize () function. If OLE initialization fails, you cannot continue to execute the subsequent code. The created object is created by CoCreateInstance () function to complete:
If (FAILED (OleInitialize (NULL) return-1; // initialize OLE
HRes = CoCreateInstance (CLSID-AgentServer, NULL, CLSCTX-SERVER, IID-IAgent, (LPVOID *) & pAgent); // create an instance of Microsoft Agent Server
If (FAILED (hRes) return-1;
The first parameter of CoCreateInstance () is the CLSID (Class Code) of the object, and the CLSID of the Microsoft Agent Server is the CLSID-AgentServer defined in the AgtSvr-i.c file, the 128-bit encoding uniquely identifies the Agent server. information such as the server path and running parameters are stored in the system registry. The second parameter is generally set to NULL; the third parameter is used to indicate the runtime environment of the object, such as remote or local, which is set to CLSCTX-SERVER here; the fourth parameter specifies the ID of the interface used to communicate with the object, this is also a 128-bit code. The Agent Interface ID is IID-IAgent. The fifth parameter is used to receive the IAgent interface pointer.
If the Microsoft Agent Server is not running in memory, CoCreateInstance () starts it and creates an Agent object. If the Server is already running, CoCreateInstance () connect to it and create an Agent object. When all Agent objects are released, the server automatically exits.
3. Load animated character data
The following code calls the IAgent: Load () method to Load the data of an animated character. Because the Agent server runs in its own memory space, the transmitted string variable must use SysAllocString () to allocate memory:
VariantInit (& vPath); // initialize the OLE variable
VPath. vt = VT-BSTR; // specifies a string whose variable type is Unicode
VPath. bstrVal = SysAllocString (kpwszCharacter );
// KpwszCharacter is the path for storing animated character data
HRes = pAgent-> Load (vPath, & lCharID, & lRequestID );
// Load data. The character ID is returned in lCharID.
HRes = pAgent-> GetCharacter (lCharID, & pdCharacter );
// Obtain the lCharID IDispatch interface pointer. Call the IDispatch: QueryInterface () method to obtain the IAgentCharacter interface pointer:
HRes = pdCharacter-> QueryInterface (IID-IAgentCharacter, (LPVOID *) & pCharacter );
PdCharacter-> Release (); // Release the IDispath
You can use the IAgentCharacter interface to call various methods supported by animated characters:
HRes = pCharacter-> Show (FALSE, & lRequestID); // display animated characters
HRes = pCharacter-> MoveTo (320,240,100, & lRequestID); // move the animated character to the center of the screen
BszSpeak = SysAllocString (L "Hello World! "); // Assign a string
HRes = pCharacter-> Speak (bszSpeak, NULL, & lRequestID); // Let the animated character Speak
SysFreeString (bszSpeak); // release the memory occupied by the string
4. Release objects
Before exiting, the program needs to release the created Agent object:
If (pCharacter ){
PCharacter-> Release (); // Release the IAgentCharacter Interface
PAgent-> Unload (lCharID); // Unload animated character data
}
PAgent-> Release (); // Release the Agent object
VariantClear (& vPath); // clear the OLE variable
Further programming highlights
The above describes the most basic steps for calling the Microsoft Agent server. To complete more practical tasks, the customer program should also consider the following programming points based on their own circumstances.
1. Check the Agent Server version
OLE requires that components or objects have backward compatibility. Objects of higher versions support all interfaces and attributes of objects of lower versions, so that you can easily upgrade components. Generally, the client program should check the object version. Only when the version number of the object installed in the system is higher than or equal to the expected version number can the object be called. The following IsValidAgentVersion () function checks the Microsoft Agent Version Number and compares it with the version number defined in the AgtSvr. h file:
BOOL IsValidAgentVersion (IAgent * pAgent ){
IDispatch * pdAgent = NULL;
ITypeInfo * pTypeInfo = NULL;
ITypeLib * pTypeLib = NULL;
TLIBATTR * pTypeLibAttr = NULL;
BOOL bValid = FALSE;
UINT uiIndex;
PAgent-> QueryInterface (IID-IDispatch, (LPVOID *) & pdAgent );
PdAgent-> GetTypeInfo (0, 0, & pTypeInfo); // obtain the type information
PTypeInfo-> GetContainingTypeLib (& pTypeLib, & uiIndex); // obtain the Type Library
PTypeLib-> GetLibAttr (& pTypeLibAttr); // get the attributes in the Type Library
If (pTypeLibAttr-> wMajorVerNum> AGENT-VERSION-MAJOR) | (pTypeLibAttr-> wMajorVerNum = AGENT-VERSION-MAJOR) & (pTypeLibAttr-> wMinorVerNum> = AGENT-VERSION-MINOR )))
BValid = TRUE; // The expected version number is defined in the AgtSvr. h file.
If (pTypeLib ){
If (pTypeLibAttr) pTypeLib-> ReleaseTLibAttr (pTypeLibAttr );
PTypeLib-> Release ();}
If (pTypeInfo) pTypeInfo-> Release ();
If (pdAgent) pdAgent-> Release ();
Return bValid ;}
2. Implement the iagentpolicysink Interface
To be able to process user input and understand the Agent object status, the customer program should implement the iagentpolicysink interface to receive events of the Agent object. The description and default Implementation of iagentpolicysink can be found in Notify. h and Notify. cpp in Platform SDK or Internet Clinet SDK. The client program should modify the processing functions of certain events as needed.
. The following code registers the iagentpolicysink interface with the Agent object, where agentpolicysink is inherited from the iagentpolicysink:
PSink = new agentpolicysink;
PSink-> AddRef (); // Add reference count
HRes = pAgent-> Register (IUnknown *) pSink, & lpolicysinkid); // Register
...
If (pSink ){
P