Article ID: 141414
Article Last Modified on 3/14/2005
IOleClientSite
IOleContainer
IEnumUnknown
IUnknown
IOleObject
IOleClientSite
IOleControlSite
OLECONTF_EMBEDDINGS: is used to retrieve OLE Controls.
OLECONTF_OTHERS : is used to retrieve other objects such as Visual
Basic internal controls.
hr = lpContainer->EnumObjects(OLECONTF_EMBEDDINGS | OLECONTF_OTHERS,
&lpEnumUnk);
The differentiating aspect between OLE controls and other objects such as
internal Visual Basic controls is that only OLE controls support the
IOleObject interface. Hence, if a QueryInterface for IID_IOleObject fails
for an object, then it is a different type of object. Also, if the control
container provides support for Extended controls as does Visual Basic 4.0,
the Extended control for a particular OLE control can also be retrieved
using the method illustrated by the sample code.
void EnumAllControlNames(LPOLECLIENTSITE lpSite)
{
LPOLECONTAINER lpContainer;
LPENUMUNKNOWN lpEnumUnk;
// Note that the IOleContainer interface is currently defined as
// mandatory. It must be implemented by control containers,
// in the OLE Control Containers Guidelines.
HRESULT hr = lpSite->GetContainer(&lpContainer);
if(FAILED(hr)) {
OutputDebugString(_T("Unable to get to the container.\n"));
return;
}
// OLECONTF_EMBEDDINGS is used to retrieve OLE Controls.
// OLECONTF_OTHERS is used to retrieve other objects such as
// Visual Basic internal controls
hr = lpContainer->EnumObjects(
OLECONTF_EMBEDDINGS | OLECONTF_OTHERS,
&lpEnumUnk);
if(FAILED(hr)) {
lpContainer->Release();
return;
}
LPUNKNOWN lpUnk;
while (lpEnumUnk->Next(1, &lpUnk, NULL) == S_OK) {
LPOLEOBJECT lpObject = NULL;
LPOLECONTROLSITE lpTargetSite = NULL;
LPOLECLIENTSITE lpClientSite = NULL;
LPDISPATCH lpDisp;
hr = lpUnk->QueryInterface(
IID_IOleObject, (LPVOID*)&lpObject);
if(SUCCEEDED(hr)) {
// This is an OLE control.
// Navigate to the Extended Control because Visual Basic 4.0 uses
// Extended controls.
hr = lpObject->GetClientSite(&lpClientSite);
if(SUCCEEDED(hr)) {
// You have the IOleClientSite interface
hr = lpClientSite->QueryInterface(
IID_IOleControlSite, (LPVOID*)&lpTargetSite);
if(SUCCEEDED(hr)) {
// You have the IOleControlSite interface
// Get the IDispatch for the extended control.
// Note that Extended controls are optional in the OLE
// specifications for OLE Control Containers.
hr = lpTargetSite->GetExtendedControl(&lpDisp);
}
}
}
else {
// This is either an internal VB control or the
// VB form itself.
hr = lpUnk->QueryInterface(
IID_IDispatch, (LPVOID*)&lpDisp);
}
if(SUCCEEDED(hr)) {
VARIANT va;
VariantInit(&va);
DISPID dispid;
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
// Get the names of all the controls present in a VB form.
LPWSTR lpName[1] = { (WCHAR *)L"Name" };
hr = lpDisp->GetIDsOfNames(IID_NULL, lpName, 1,
LOCALE_SYSTEM_DEFAULT, &dispid);
if(SUCCEEDED(hr)) {
hr = lpDisp->Invoke(dispid/*0x80010000*/, IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET |
DISPATCH_METHOD,
&dispParams, &va, NULL, NULL);
if(SUCCEEDED(hr)) {
CString szTmp((LPCWSTR)va.bstrVal);
// szTmp now has the name.
OutputDebugString(_T("And the name is ... ") + szTmp +
_T("\n"));
}
}
lpDisp->Release();
}
// Release interface pointers.
if(lpObject) lpObject->Release();
if(lpTargetSite) lpTargetSite->Release();
if(lpClientSite) lpClientSite->Release();
lpUnk->Release();
} // End of While statement
// Final clean up
lpEnumUnk->Release();
lpContainer->Release();
}
Additional words: VB VC visualc cdk ocx
Keywords: kbhowto kbctrlcreate KB141414