HOWTO: Use an OLE Control as an Automation Server
ID: Q146120
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), used with:
-
Microsoft Visual C++, 32-bit Editions, versions 4.0, 4.1, 4.2, 4.2b, 5.0, 6.0
SUMMARY
In situations where an OLE container doesn't support control containment,
you may want to use an OLE control as an automation server to gain access
to its properties and methods. This article explains the necessary
modifications you need to make in order for an OLE control to function as a
normal automation server.
MORE INFORMATION
Prior to Visual C++ 4.0, an OLE Control could be used as an automation
server without any modification. However, in MFC 4.0, the framework's
implementation of IDispatch::Invoke calls the virtual function
IsInvokeAllowed to determine if an automation server is in the appropriate
state to handle automation calls. The default implementation in
CCmdTarget::IsInvokeAllowed returns TRUE, implying that a server can handle
automation calls.
In the case of an OLE control, COleControl::IsInvokeAllowed checks to see
if the control has been either initialized or loaded properly through the
persistent storage interfaces. If the control has the appropriate state
information, then this function returns TRUE. When an OLE control is
created as a normal automation server, it is not created as an embedding in
the client. Hence, none of the persistent state initialization will take
place, which thereby causes IsInvokeAllowed to return FALSE. The effect of
this is that a call to an automation object method generates a run-time
error of (8000ffff) : "Catastrophic failure".
In order to use an OLE control only as an automation server, you need to
override COleControl::IsInvokeAllowed() and return TRUE. If any of the
control's properties and methods should not be accessed when invoked as a
normal automation server, then that automation function could be bypassed
and/or an error code can be returned when COleControl::m_bInitialized is
FALSE.
To override COleControl::IsInvokeAllowed(), you may follow these steps:
- In ClassView, right-click the C<name>Ctrl class for your control, where <name> is the base name of your control.
- Choose Add Member Function from the Context menu.
- In the Function Type field, type: BOOL
- In the Function Declaration field, type: IsInvokeAllowed( DISPID ).
- Leave Access set at Public, and the check boxes cleared. Click OK.
- Inside the new function (which should appear automatically under the cursor), between the curly braces, type: return TRUE;
- Build the control.
For example, the default OLE control behavior may pose a problem when an
automation client calls CreateDispatch to create the OLE control as an
automation server. Prior to making the above modification, CreateDispatch
may succeed; however, any automation calls on the OLE control would fail.
Sample Code
BOOL CMyOleControl::IsInvokeAllowed (DISPID)
{
// You can check to see if COleControl::m_bInitialized is FALSE
// in your automation functions to limit access.
return TRUE;
}
Additional query words:
ocx OLE Automation error
Keywords : kbcode kbole kbAutomation kbCtrl kbMFC kbVC400 kbVC410 kbVC420 kbVC500 kbVC600 kbocx
Version : winnt:4.0,4.1,4.2,4.2b,5.0,6.0
Platform : winnt
Issue type : kbhowto
|