By Adam Nagy
Sometimes you may need to cast an object to a different type. E.g. when trying to get to the Parameters property of a ComponentDefinition got from a ComponentOccurrence. ComponentDefinition does not have a Parameters property, but PartComponentDefinition and AssemblyComponentDefinition do.
You have two ways to solve this problem:
1) Either use early binding and cast ComponentDefinition to PartComponentDefinition or AssemblyComponentDefinition using CComQIPtr (QI = Query Interface)
2) Use late binding to access the Parameters property through the ComponentDefinition object
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HRESULT Result = NOERROR;
::CoInitialize(NULL);
// Access Inventor
{
CLSID InvAppClsid;
Result = CLSIDFromProgID (_T("Inventor.Application"), &InvAppClsid);
if (FAILED(Result)) return Result;
CComPtr pInvAppUnk;
Result = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk);
if (FAILED (Result))
_tprintf_s(_T("Could not get the active Inventor instancen"));
if (FAILED(Result)) return Result;
CComPtr pInvApp;
Result = pInvAppUnk->QueryInterface(
__uuidof(Application), (void **) &pInvApp);
if (FAILED(Result)) return Result;
CComPtr pAddIn =
pInvApp->ApplicationAddIns->ItemById[
_T("{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}")];
// Get Parameters
{
// First the occurrence needs to be selected
// in the user interface
CComQIPtr oOcc =
pInvApp->ActiveDocument->SelectSet->Item[1];
// 1) Use early binding and CComQIPtr
CComPtr pParams;
CComQIPtr pPartCompDef = oOcc->Definition;
if (pPartCompDef)
{
// It is a part component definition, so we can get the
// parameters of the part definition
pParams = pPartCompDef->Parameters;
}
CComQIPtr pAsmCompDef = oOcc->Definition;
if (pAsmCompDef)
{
// It is an assembly component definition, so we // can get the parameters of the assembly definition
pParams = pAsmCompDef->Parameters;
}
MessageBox(NULL, pParams->Item[1]->Name,
_T("Name of first parameter (early binding)"), MB_OK);
// 2) Use late binding
// This requires the AutoWrap function from article
// http://adndevblog.typepad.com/manufacturing/2013/09/run-ilogic-rule-from-external-application.html
// Since both PartComponentDefinition and
// AssemblyComponentDefinition have a Parameters property
// we could get it like this too
VARIANT res;
AutoWrap(
DISPATCH_PROPERTYGET, &res, oOcc->Definition, _T("Parameters"), 0);
CComQIPtr pParamsLate = res.pdispVal;
MessageBox(NULL, pParamsLate->Item[1]->Name,
_T("Name of first parameter (late binding)"), MB_OK);
} } ::CoUninitialize();
return nRetCode;}

Leave a Reply