如何测试 OleVariant 是否包含接口
How to test if a OleVariant contains an interface
通过其自动化界面使用 Excel 的一个烦人的事情是弱类型。
return 值可以包含 任何东西 不同的类型。
我如何测试 caller
编辑的变体 return 是否是 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 return 值。
if VarIsType(Caller, varDispatch) and Supports(Caller, ExcelRange) then begin
遗憾的是,代码确实很冗长,但接近我通常使用的代码:
if IUnknown(Caller).QueryInterface(ExcelRange, ICaller)=S_OK then
我可能会为此使用 Supports
:
if Supports(Caller, ExcelRange) then
....
这解析为与@Stijn 给出的代码相同,但 Supports
调用更简洁。
System.Variants
单元具有 VarSupports()
功能用于 testing/extracting 来自 (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;
通过其自动化界面使用 Excel 的一个烦人的事情是弱类型。
return 值可以包含 任何东西 不同的类型。
我如何测试 caller
编辑的变体 return 是否是 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 return 值。
if VarIsType(Caller, varDispatch) and Supports(Caller, ExcelRange) then begin
遗憾的是,代码确实很冗长,但接近我通常使用的代码:
if IUnknown(Caller).QueryInterface(ExcelRange, ICaller)=S_OK then
我可能会为此使用 Supports
:
if Supports(Caller, ExcelRange) then
....
这解析为与@Stijn 给出的代码相同,但 Supports
调用更简洁。
System.Variants
单元具有 VarSupports()
功能用于 testing/extracting 来自 (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;