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

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


Removing an MFC COM interface in a derived class

Carl Gunther -- cgunther@ix.netcom.com
Tuesday, February 25, 1997

Environment:  VC++ 4.1, Win 95


I'm creating a set of OCX controls based upon MFC's
COleControl class.  These controls come in both 16 and
32-bit flavors which are intended to be completely compatible.
Specifically, this means that a 16-bit VB 4.0 project created 
using the 16-bit version
of these controls must be loadable by 32-bit VB (using the
32-bit version of the controls) and vice-versa.

I've run into a compatibility problem with the serialized data.
Specifically, this problem occurs with a BLOB that is 
serialized using the standard PX_Blob() function from
CMyControl::DoPropExchange().  The BLOB created by the 16-bit
version cannot be read by the 32-bit version, and returns
NULL.

I've traced this problem to the fact that MFC 4.1 (which I'm
using for my 32-bit version) implements
an optional interface for persistence that is not implemented
by MFC 1.52c (which I'm using for my 16-bit version).
This interface is called IPersistPropertyBag.  There are other
interfaces that could also be used, but when IPersistPropertyBag
is available, 32-bit VB 4.0 uses it because it is more efficient
for certain operations.  I suspect that if it were not available
then VB would probably use IPersistStreamInit, which is also
available to the MFC 1.52c version of the controls.  Hopefully,
this would solve my compatibility problem.

I have not been able to figure out how to declare 
IPersistPropertyBag as E_NOINTERFACE (not available) in my 
32-bit controls.  I can *override* the interface, but I can't
seem to get RID of it.  The CCmdTarget class (from which 
COleControl is derived) implements QueryInterface() for the
control using a data-driven approach that searches upward from
the most-derived class to CCmdTarget itself, looking for
a requested interface (in this case, IPersistPropertyBag).
While this allows me to add NEW interfaces, and even to 
override an existing one, I can't find a way to tell this 
function that the interface should be returned as NOT implemented.

Overriding the interface and replacing its functionality with
that of IPersistStreamInit would probably be breaking a 
fundamental OLE contract, and VB might be unpleasantly surprised
by the changed behavior in any case.

I'd like to know how to remove the IPersistPropertyBag interface
that is defined in COleControl from my COleControl-derived
control object, so that a container requesting it via QueryInterface()
will receive E_NOINTERFACE as a return value and a NULL pointer back.
However, other suggestions on how to approach the more
general problem would also be very welcome.
Thanks in advance.





Regis NICOLAS -- regis.nicolas@smartcode.fr
Thursday, February 27, 1997

At 02:08 PM 2/25/97 -0800, you wrote:
>Environment:  VC++ 4.1, Win 95
>
>
>I'm creating a set of OCX controls based upon MFC's
>COleControl class.  These controls come in both 16 and
>32-bit flavors which are intended to be completely compatible.
>Specifically, this means that a 16-bit VB 4.0 project created 
>using the 16-bit version
>of these controls must be loadable by 32-bit VB (using the
>32-bit version of the controls) and vice-versa.
>
>I've run into a compatibility problem with the serialized data.
>Specifically, this problem occurs with a BLOB that is 
>serialized using the standard PX_Blob() function from
>CMyControl::DoPropExchange().  The BLOB created by the 16-bit
>version cannot be read by the 32-bit version, and returns
>NULL.
>
>I've traced this problem to the fact that MFC 4.1 (which I'm
>using for my 32-bit version) implements
>an optional interface for persistence that is not implemented
>by MFC 1.52c (which I'm using for my 16-bit version).
>This interface is called IPersistPropertyBag.  There are other
>interfaces that could also be used, but when IPersistPropertyBag
>is available, 32-bit VB 4.0 uses it because it is more efficient
>for certain operations.  I suspect that if it were not available
>then VB would probably use IPersistStreamInit, which is also
>available to the MFC 1.52c version of the controls.  Hopefully,
>this would solve my compatibility problem.
>
>I have not been able to figure out how to declare 
>IPersistPropertyBag as E_NOINTERFACE (not available) in my 
>32-bit controls.  I can *override* the interface, but I can't
>seem to get RID of it.  The CCmdTarget class (from which 
>COleControl is derived) implements QueryInterface() for the
>control using a data-driven approach that searches upward from
>the most-derived class to CCmdTarget itself, looking for
>a requested interface (in this case, IPersistPropertyBag).
>While this allows me to add NEW interfaces, and even to 
>override an existing one, I can't find a way to tell this 
>function that the interface should be returned as NOT implemented.
>
>Overriding the interface and replacing its functionality with
>that of IPersistStreamInit would probably be breaking a 
>fundamental OLE contract, and VB might be unpleasantly surprised
>by the changed behavior in any case.
>
>I'd like to know how to remove the IPersistPropertyBag interface
>that is defined in COleControl from my COleControl-derived
>control object, so that a container requesting it via QueryInterface()
>will receive E_NOINTERFACE as a return value and a NULL pointer back.
>However, other suggestions on how to approach the more
>general problem would also be very welcome.
>Thanks in advance.
>
>
>
May be you could subclass the QueryInterface itself and return E_NOINTERFACE
or some other appropriate error code when the riid requested is
IID_IPersistPropertyBag ?

Hope this helps...

------------------------------
Regis NICOLAS -    R&D Windows
Smartcode Technologie

mailto:nicolas@smartcode.fr
http://www.smartcode.fr/
http://www.smartcodesoft.com/
Tel.: (33) (0)4 67 59 30 16





Become an MFC-L member | Вернуться в корень Архива |