Programming with Microsoft Visual C++.NET 6ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming with Microsoft Visual C++.NET 6ed [Electronic resources] - نسخه متنی

George Shepherd, David Kruglinski

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید








An MFC Automation Client Program


Let's move on to the client's end of the Automation conversation. How does an MFC Automation client program call Invoke? The MFC library provides a base class COleDispatchDriver for this purpose. This class has a data member, m_lpDispatch, that contains the corresponding component's IDispatch pointer. To shield you from the complexities of the Invoke parameter sequence, COleDispatchDriver has several member functions, including InvokeHelper, GetProperty, and SetProperty. These three functions call Invoke for an IDispatch pointer that links to the component. The COleDispatchDriver object incorporates the IDispatch pointer.

Suppose our client program has a class CClockDriver that's derived from COleDispatchDriver and that drives CClock objects in an Automation component. The functions that get and set the Time property are shown here:

 DATE CClockDriver::GetTime()
{
DATE result;
GetProperty(1, VT_DATE, (void*)&result);
return result;
}
void CClockDriver::SetTime(DATE propVal)
{
SetProperty(1, VT_DATE, propVal);
}

Here are the functions for the indexed Figure property:

VARIANT CClockDriver::GetFigure(short i)
{
VARIANT result;
static BYTE parms[] = VTS_I2;
InvokeHelper(2, DISPATCH_PROPERTYGET, VT_VARIANT,
(void*)&result, parms, i);
return result;
}
void CClockDriver::SetFigure(short i, const VARIANT& propVal)
{
static BYTE parms[] = VTS_I2 VTS_VARIANT;
InvokeHelper(2, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL,
parms, i, &propVal);
}

And here are the functions that access the component's methods:

void CClockDriver::RefreshWin()
{
InvokeHelper(3, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}
BOOL CClockDriver::ShowWin(short i)
{
BOOL result;
static BYTE parms[] = VTS_I2;
InvokeHelper(4, DISPATCH_METHOD, VT_BOOL,
(void*)&result, parms, i);
return result;
}

The function parameters identify the property or method, its return value, and its parameters. You'll learn about dispatch function parameters later, but for now take special note of the first parameter for the InvokeHelper, GetProperty, and SetProperty functions. This is the unique integer index, or dispatch ID (DISPID), for the property or method. Because you're using compiled C++, you can establish these IDs at compile time. If you're using an MFC Automation component with a dispatch map, the indexes will be determined by the map sequence, beginning with 1. If you don't know a component's dispatch indexes, you can call the IDispatch member function GetIDsOfNames to convert the symbolic property or method names to integers.

The following illustration shows the interactions between the client (or controller) and the component.



The solid lines show the actual connections through the MFC base classes and the Invoke function. The dotted lines represent the resulting logical connections between client class members and component class members.

Most Automation components have a binary type library file with a TLB extension. The Add Class Wizard can access this type library file to generate a class derived from COleDispatchDriver. (Choose Add Class from the Project menu and select MFC Class From TypeLib.) This generated controller class contains member functions for all the component's methods and properties with hard-coded DISPIDs. Sometimes you need to do some surgery on this generated code, but that's better than writing the functions from scratch.

After you have generated your driver class, you embed an object of this class in your client application's view class (or in another class), like this:

CClockDriver m_clock;

You then ask COM to create a clock component object using this statement:

m_clock.CreateDispatch("Ex23c.Document");

Now you're ready to call the dispatch driver functions:

m_clock.SetTime(COleDateTime::GetCurrentTime());
m_clock.RefreshWin();

When the m_clock object goes out of scope, its destructor releases the IDispatch pointer.


/ 319