
Using OLE Servers in Visual C++
Introduction
For this tutorial, we'll use theIDSMail OLE Server as an example. IDSMail is a component that allows programmers to easily send and receive E-mail through a variety of E-mail systems.
Declaration & Initialization
The code snippets below show how to declare and instantiate an OLE Server in Visual C++. The server is declared publicly. The string IDSMailInterface.Server is the class name (or programmatic ID) of the server.
//Declarations Section
public:
_Server* idsMail;
// ---------------------------
// create dispatch object
idsMail = new _Server();
// The following line is equivalant to CreatObject in VB
// It create an interface object with the OLE Server.
if (!idsMail->CreateDispatch(_T("IDSMailInterface.Server")))
{
AfxMessageBox("Fail to create mail server !");
return -1; // fail
}
Setting and Getting Property Values
OLE Servers expose their attributes as properties. For example, the IDSMail OLE Server has a MailSystem property to specify the type of mail system. The property has a short integer value ranging from 1 to 20.
In Visual Basic, you can assign this property a value with the following code:
idsmail.MailSystem = 1
Or, you can retrieve the property value like this:
currentSystem = idsmail.MailSystem
where currentSystem is an integer variable.
In C++, things are not quite this easy. C++ does not have the concept of properties. The acts of assigning a property value and retrieving a property value are separate and distinct, and must be done via two different interface functions. These functions are prefixed with Set (assignment) and Get (retrieving the value).
The actual function names are derived directly from the OLE Server's property names as shown in the following examples:
VARIANT _Server::GetMailSystem()
void _Server::SetMailSystem(VARIANT* newValue)
Generating the Functions Automatically
If you were to peer inside one of these Set/Get functions, you would see code like this:
VARIANT _Server::GetMailSystem()
{
VARIANT result;
InvokeHelper(0x6803001c, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&result, NULL);
return result;
}
We don't need to worry about what exactly the InvokeHelper call does, or where the 0x6803001c literal came from. Why? Because the Visual C++ Class Wizard will generate all of these interface functions for us automatically, using the information in the OLE Server's type library as a guide.
OLE Servers always come with a type library. That type library may be a separate file with an extension such as .TLB, or the type library may be embedded in the OLE Server itself. This is the case for IDSMail: the type library is contained within the IDSMAIL.EXE file.
To generate the interface functions for an OLE Server, here are the steps to take:
- Create your project.
- From the Browse menu, choose Class Wizard.
- Select the OLE Automation tab. Create a new class, accepting the default entries.
- Click "Read Type Library" and select the type library in the dialog. In the example of IDSMail, select the IDSMAIL.EXE file which has the type library embedded within it.
- New header files will be generated. If header files of the same name already existed, Visual C++ will append to the file instead. If this is the case, you may need to manually delete the older code.
The Magical Variant
I'm sure you noticed in the examples above that a VARIANT data type is declared. Variants are the standard data type for passing information to and from OLE Servers.
But what IS a variant? A variant is a class that can represent data of many different fundamental types. There are separate data members for each fundamental data type, and a designator that states which of these fundamental data types is actually in use.
If you are working in Visual C++ v2.0 above, the MFC libraries provide you with a pre-written variant class called COleVariant. If you are working in older versions of Visual C++, you will either need to develop your own variant class, or use this one that we have developed.
Invoking Methods
Invoking a method in an OLE Server is analagous to calling a function in C++. The method may or may not return a value, and can have any number of parameters (including no parameters). We'll look at some examples in the section below.
Real Code Examples
Here are some actual code examples using the methods and properties of the IDSMail OLE Server. The syntax will be similar for other OLE Servers you may need to work with.
Setting an Integer Property Value
Here's how to set the MailSystem (short integer) property:
COleVariant vtMailSystem;
vtMailSystem = 4;
idsMail->SetMailSystem(&vtMailSystem);
Getting an Integer Property Value
Here's how to get the MailSystem (short integer) property:
COleVariant vtMailSystem;
vtMailSystem = idsMail->GetMailSystem();
short mailSystem = vtMailSystem.iVal
Setting a String Property Value
Here's how to set the ObjectKey (string) property:
COleVariant vtKey;
vtKey = "abcdef123456";
idsMail->SetObjectKey(&vtKey);
Invoking a Method with No Parameters, no Return Value
Here's how to invoke the LoadMessageHeaders method:
idsMail->LoadMessageHeaders();
Invoking a Method with Parameters and a Return Value
The IDSMail GetHeaderItemString method accepts a short integer parameter which designates the desired header element. That header element is returned as a string. Here's how to invoke it:
// IDSM_ITM_SUBJECT is a short integer constant
CString szSubject;
short nSubject = IDSM_ITM_SUBJECT;
szSubject = idsMail->GetHeaderItemString(&nSubject);
Conclusion and Resources
As you can see, utilizing OLE Servers from Visual C++ is not difficult. It's just different if you have not been exposed to this technology before. This brief tutorial along with the references listed below should allow you to begin harnessing the power of these software components immediately!
|