1

This question arose from the following question :

Chaining methods of ATL/COM objects

Let's say I have a instance MyObj1 of an ATL/COM class TheClass of a dll exposed to vba, and a method TheMethod of TheClass.

In VBA, I have a function

Public Function func(x as Variant) as Variant
    '... something
    MyObj1.TheMethod( x )
    '... other things
End Function

This function is used in excel, and I pass an excel range of cell to it. At debug in VBA, x is seen of vba type "Variant/Object/Range", and has a "Value2" of vba type "Variant/Variant", and if the range is for instance a rectangle containing expty cells and doubles in excel, when Value2 is unfolded (still in watch in debug in vba), it is composed of Variant's of types "Variant/Double" or "Variant/Empty". It is this "core" "Value2" Variant that I would like to isolate in the next step, in c++.

At the next step, at debug in c++ at the entry of the ATL method TheMethod of signature

STDMETHODIMP TheClass::TheMethod( VARIANT* var_in )

var_in (which received the latter x) is seen having a vt equal to VT_DISPATCH. This guy carries for sure (even if I don't know) all the stuff already carried by the latter x, but I would like to know how to isolate the "Value2" part of it to catch it and work with it, as only the Value2 part interests me.

Let me say that I know that rather than doing it in c++, I could do this in vba :

Public Function func(x as Variant) as Variant
    '... something
    MyObj1.TheMethod( x.Value2 )
    '... other things
End Function

but I don't want to resort to such thing in VBA.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Olórin
  • 3,367
  • 2
  • 22
  • 42
  • 1
    Well, that `IDispatch` pointer packed into the variant is, obviously, that of a [`Range` object](http://msdn.microsoft.com/en-us/library/office/ff838238.aspx). To do the equivalent of `x.Value2` in C++, you would either `#import` Excel's TLB and use generated wrappers, or use late binding, perhaps with the help of `CComDispatchDriver`. – Igor Tandetnik Sep 18 '13 at 05:28

1 Answers1

1

Ok, so as Igor Tandetnik suggested, i did something like :

VARIANT * pVARIANT_IN_EXTENSION = new VARIANT() ;
VariantInit(pVARIANT_IN_EXTENSION);
IDispatch * piDisp = pVARIANT_IN->pdispVal ;
::DISPPARAMS invokeparams = {0} ;
HRESULT hRes = piDisp->Invoke(0, IID_NULL, 0, DISPATCH_PROPERTYGET,&invokeparams, pVARIANT_IN_EXTENSION, NULL, NULL);

to get the real "array variant" (of vt equal to VT_ARRAY) packed into the VT_DISPATCH variant pVARIANT_IN.

I will later give a try to the import of Excel's type library.

Olórin
  • 3,367
  • 2
  • 22
  • 42