15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CCmdTarget subclasses and OLE Automation

Dan L. Pierson -- dan@cthulhu.control.com
Wednesday, April 17, 1996

VC++/MFC 4.1 / NT 4.0b1

I'm a bit confused about the interaction of CCmdTarget support for OLE =
automation and C++ derivation.  Given a class hierarchy like the =
following:

class ParseTreeNode : CCmdTarget
{
   // Dispatch map, etc.  Maybe Interface map as well.
   // EnableAutomation() called in constructor
   virtual void SomeMethod();
   SCODE DispDoSomeMethod();
}

SCODE ParseTreeNode::DispDoSomeMethod()
{
   SomeMethod();
   return S_OK;
}

class FirstLevelNode : ParseTreeNode
{
   ...
}

class SecondLevelNode : FirstLevelNode
{
   ...
   virtual something SomeMethod();
}

For this example, no class but ParseTreeNode explicitly implements any =
OLE automation support.  In my real hierarchy there is one direct child =
of ParseTreeNode that needs to implement an additional dispatch =
interface (or additional methods but I think an additional interface may =
be cleaner).  The actual hierarchy is about four levels deep and =
ParseTreeNode is an abstract base class.

I'd like to pass an instance of SecondLevelNode as an LPDISPATCH by
passing the result of ParseTreeNode::GetIDispatch(), i.e. it's inherited =
IDispatch*. =20

I'd like all calls on the passed IDispatch to wind up calling virtual =
functions in the SecondLevelNode.

Is this reasonable?  Do I have to implement empty dispatch maps, etc. in =
all descendant classes?

Dan Pierson, Control Technology Corporation	




William Cook -- wcook@msn.com
Saturday, April 20, 1996

>I'd like all calls on the passed IDispatch to wind up calling virtual
>functions in the SecondLevelNode.
>Is this reasonable?  Do I have to implement empty dispatch maps, etc. in
>all descendant classes?

This is reasonable, and it works without a great deal of hassle. There are, 
however, a few things you should be aware of.

First, you will have some problems creating an abstract base class, because of 
the constraints of IMPLEMENT_DYNCREATE, so you will need to look at the MFC 
FAQ to find out how to do this. 

Second, the DISPIDs of your derived classes will differ from those of their 
base classes. For example, if class CMyAbstractBaseClass has a property 
"MyProp" with a dispid of 0x00000001, then the derived class 
CMyFirstLevelDerivedClass will inherit a property "MyProp" with a dispid of 
0x00010001, and a further derived class CMySecondLevelDerivedClass will 
inherit a property "MyProp" with a dispid of 0x00020001, etc. This behavior is 
described in Tech Note TN039, and it is very annoying when trying to provide a 
set of COleDispatchDriver-derived classes for a C++ client. You cannot have a 
corresponding class hierarchy there unless you do some funcky things to make 
sure you're using the right DISPIDs for the current object or call 
GetDispIDsOfNames each time you want to invoke a property.

Third, the type library that classwizard generates will not be entirely 
correct, in that the derived classes will not have their inherited methods in 
the type lib. You will therefore need to edit the type lib yourself to 
maintain the inherited methods and properties, which is just as well given 
that the DISPIDs are all messed up anyway.

Good luck,
Bill Cook _/)_




| Вернуться в корень Архива |