While working on a support case involving StarTeam and CaliberRM, I had to write a program to see which of the following scenario is true:

  • StarTeam SDK is not giving the correct output, CaliberRM is interpreting the output correctly
  • StarTeam SDK is giving the correct output, CaliberRM is not interpreting the output correctly

So guess what language I chose to use? Delphi! ;o)

Given:

var
  Folders: IStCollection;
  V: OleVariant;

and that Folders has an Items default property returning a IStCollection,

I had to cast Folders[ItemIndex]: OleVariant to another interface, IStFolder (var Folder: IStFolder)

So, I tried this:

Folder := Folders[ItemIndex];

and got “[Pascal Error] StarTeamFolderEnumerator.pas(70): E2010 Incompatible types: 'IStFolder' and 'OleVariant'”.

And this:

Folder := Folders[ItemIndex] as IStFolder;

and got “[Error] StarTeamFolderEnumeratorImpl.pas(61): E2015 Operator not applicable to this operand type”.

My good friend, Tim to the rescue again! It turns out that I have to cast Folders[ItemIndex] to an IDispatch first, before casting it to an IStFolder, because Folders[ItemIndex] is an OleVariant, which, in this case, is just an IDispatch.

V := Folders[ItemIndex];
Folder := IDispatch(V) as IStFolder;

Tim explains,

  1. yeah, you cant type a OLEVariant directly to a IWhatever.
  2. because the OLEVariant is just a wrapper around a IDispatch
  3. but you can typecast a IDispatch to Iwhaterver but under the hood, its calling the IUnknown getinterface method