如何测试OleVariant是否包含接口

时间:2015-06-03 13:35:12

标签: delphi variant office-automation

通过其自动化界面使用Excel的一个令人讨厌的事情是打字很弱 返回值可以包含任何不同的类型 如何测试caller返回的变体是ExcelRange接口?

function TAddInModule.InBank: boolean;
var
  ExcelAppAsVariant: OleVariant;
  test: string;
  Caller: OleVariant;
begin  //Exception handling omitted for brevity. 
  Result:= false;
  ExcelAppAsVariant:= ExcelApp.Application;
  Caller:= ExcelApp.Application.Caller[EmptyParam, 0];
  if IDispatch(Caller) is ExcelRange then begin //E2015 Operator not applicable 
    Result:= lowercase(Caller.Parent.Name) = 'bank' 
  end;
end;

as运算符工作(IDispatch(Caller) as ExcelRange).Parent;编译得足够好。

以下代码有效,但似乎过于冗长:

if VarIsType(Caller, varDispatch) then begin 
  IUnknown(Caller).QueryInterface(ExcelRange, ICaller) 
  if Assigned(ICaller) then ICaller......

也没有内置功能VarIsInterface(Variant, Interface) 如何测试OleVariant是否包含给定的界面?

另请参阅:How to cast OleVariant to IDispatch derived?

修改
谢谢大家,我使用以下方法进行测试,因为Excel将接口和OleStrings混合为可能的返回值。

if VarIsType(Caller, varDispatch) and Supports(Caller, ExcelRange) then begin

3 个答案:

答案 0 :(得分:3)

我可能会使用Supports

if Supports(Caller, ExcelRange) then
  ....

这解析为与@Stijn相同的代码,但Supports调用更简洁。

答案 1 :(得分:2)

代码确实令人遗憾,冗长,但接近我通常使用的代码:

if IUnknown(Caller).QueryInterface(ExcelRange, ICaller)=S_OK then

答案 2 :(得分:2)

System.Variants单元具有VarSupports()个功能,用于从(Ole)Variant测试/提取接口:

function VarSupports(const V: Variant; const IID: TGUID; out Intf): Boolean; overload;
function VarSupports(const V: Variant; const IID: TGUID): Boolean; overload;

例如:

Caller := ExcelApp.Application.Caller[EmptyParam, 0];
if VarSupports(Caller, ExcelRange) then
  Result := LowerCase(Caller.Parent.Name) = 'bank';

if VarSupports(Caller, ExcelRange, ICaller) then 
  ICaller.DoSomething;