Après @ conseils de IgorTandetnik, je suis venu avec la méthode suivante qui semble faire le travail (c'est un pseudo- Code bien):
BOOL VariantToObjectProperties(CComVariant& var)
{
HRESULT hr;
if (var.vt != VT_DISPATCH)
return FALSE;
CComPtr<IDispatch> pDispatch = var.pdispVal;
CComQIPtr<IDispatchEx> pDispatchEx;
if(FAILED(hr = pDispatch->QueryInterface(IID_IDispatchEx, (void **)&pDispatchEx)))
return FALSE;
BSTR bstrName;
DISPID dispid;
//Assume success
BOOL bRes = TRUE;
//Enumerate object names
hr = pDispatchEx->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
while (hr == NOERROR)
{
if(SUCCEEDED(hr = pDispatchEx->GetMemberName(dispid, &bstrName)))
{
// get DISPID of item
DISPID dispidIndex = 0;
LPOLESTR pIndex = reinterpret_cast<LPOLESTR>(const_cast<WCHAR *>(bstrName));
if(SUCCEEDED(hr = pDispatch->GetIDsOfNames(IID_NULL, &pIndex, 1, LOCALE_USER_DEFAULT, &dispidIndex)))
{
CComVariant varItem;
DISPPARAMS dispParams = {0};
if(SUCCEEDED(hr = pDispatch->Invoke(dispidIndex, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &varItem, NULL, NULL)))
{
//Object's property name is in 'bstrName'
//Object's property value is in 'varItem'
}
else
{
ASSERT(NULL);
bRes = FALSE;
}
}
else
{
ASSERT(NULL);
bRes = FALSE;
}
}
SysFreeString(bstrName);
hr = pDispatchEx->GetNextDispID(fdexEnumAll, dispid, &dispid);
}
return bRes && hr == S_FALSE;
}