Article ID: 143432
Article Last Modified on 11/21/2006
138414 FromIDispatch returns NULL for OLE control
// The header file of the control-derived class must be included in
// the same source file.
#include "myctrl.h"
// This code is for versions prior to Visual C++ 2005. Comment out this code
// when you are using the Visual C++ 2005 code.
CMyCtrl* CMyPropPage::GetControlClass()
{
CMyCtrl *pMyCtrl;
ULONG Ulong;
// Get the array of IDispatch pointers that is stored in the property page.
LPDISPATCH FAR *m_lpDispatch = GetObjectArray(&Ulong);
// Get the CCmdTarget object that is associated with any one of the previous
// array elements.
pMyCtrl = (CMyCtrl*) CCmdTarget::FromIDispatch(m_lpDispatch[0]);
// Cleanup
return pMyCtrl;
}
// This is the end of the code that is used for versions other than Visual C++ 2005.
// The following code applies only to Visual C++ 2005. Uncomment this code for Visual C++ 2005.
CMyCtrl* CMyPropPage::GetControlClass()
{
CMyCtrl *pMyCtrl;
ULONG Ulong;
// Get the array of IDispatch pointers that is stored in the property page.
LPDISPATCH FAR *m_lpDispatch = GetObjectArray(&Ulong);
// Get the CCmdTarget object that is associated with any one of the previous
// array elements.
pMyCtrl = (CMyCtrl*) CCmdTarget::FromIDispatch(m_lpDispatch[0]);
if(NULL == pMyCtrl)
{
LPDISPATCH pDisp;
HRESULT hr = lpDispatch[0]->QueryInterface(IID_DTestActix,(void**)&pDisp);
ASSERT(SUCCEEDED(hr));
pMyCtrl = (CTestActixCtrl *) CCmdTarget::FromIDispatch(pDisp);
pDisp->Release();
}
// Clean up.
return pMyCtrl;
}
// This is the end of the Visual C++ 2005-specific code.
// If your control has a public member variable, you can manipulate that variable
// as follows. (This code uses m_direct_control.)
void CMyPropPage::OnLButtonDown(UINT nFlags, CPoint point)
{
// Directly modify a member variable of the Control class.
CMyCtrl *pMyCtrl = GetControlClass();
if (pMyCtrl)
{
pMyCtrl->m_direct_control++;
// Display the new value of the variable in a message box.
char buf[100];
AfxMessageBox (_itoa (pMyCtrl->m_direct_control, buf, 10));
}
COlePropertyPage::OnLButtonDown(nFlags, point);
}
In this code, it is assumed that the array of IDispatch pointers that is returned from
GetObjectArray holds the same IDispatch pointer because, in a default
ControlWizard-generated application, each property page manipulates a
particular ActiveX control.
CPropPageAccessCtrl::CPropPageAccessCtrl()
{
InitializeIIDs(&IID_DPropPageAccess, &IID_DPropPageAccessEvents);
// New code.
// No aggregation, please!
m_xInnerUnknown = 0; //Base class COleControl. Set this by using a call to EnableAggregation().
//End of new code.
}
Although this workaround will work for Visual C++ 6.0 ActiveX Test Container, this workaround is not an option for containers that only support such
aggregatable controls as Excel 97 and Excel 2000. Disabling aggregation would
prevent end users from adding the control to an Excel spreadsheet. You could
add a long property to the control and then set the long property to the "this" pointer of the
control. Then, you could retrieve this property from the page, do a cast on the
value to the control's type, and use it.
For more information about this method, click the following article number to view the article in the Microsoft Knowledge Base:
205670 How to obtain access to an ActiveX control from its property page
Additional query words: ocx visualc
Keywords: kbproperties kbarchitecture kbctrl kbhowto KB143432