再次请教piao40993470,还是Automation的问题,郁闷!资料真少~ ( 积分: 100 )

  • 主题发起人 主题发起人 crazycock
  • 开始时间 开始时间
C

crazycock

Unregistered / Unconfirmed
GUEST, unregistred user!
上一个问题(http://www.delphibbs.com/delphibbs/dispq.asp?lid=3157909 )在piao40993470的帮助下解决了。现在又有新问题了。
如果得到Automation中方法的参数的类型?
方法、属性和参数都可以得到了,参数的类型呢?怎么得到?《Delphi COM深入编程》书中没有提到,搞得我查了半天资料也没有查到,偶尔有一点VC的资料,看了半天也是没有获取参数类型的代码,晕菜~
还请大家多多指点,也请piao40993470帮忙看看。
付一段《Delphi COM深入编程》中的例程。
procedure TForm1.LoadInterface(TypeInfo:ITypeInfo;TypeAttr:PTypeAttr);
var
TypeLibNode:TTreeNode;
AName:WideString;
ADOcString:WideString;
AHelpContext:LongInt;
FunctionsNode:TTreeNode;
FunctionNode:TTreeNode;
FuncIndex:Integer;
FuncDesc:PFuncDesc;
ParametersNode:TTreeNode;
ParamIndex:Integer;
Names:PBStrList;
cNames:Integer;
begin
TypeInfo.GetDocumentation(-1,@AName,@ADocString,@AHelpContext,nil);
if TypeAttr.typekind=TKIND_DISPATCH then
TypeLibNode:=treeT1.Items.AddChild(FDispatchRoot,AName)
else
TypeLibNode:=treeT1.Items.AddChild(FInterfaceRoot,AName);

treeT1.Items.AddChild(TypeLibNode,GUIDToString(TypeAttr.guid));
treeT1.Items.AddChild(TypeLibNode,'Version '+IntToStr(TypeAttr.wMajorVerNum)+'.'+IntToStr(TypeAttr.wMinorVerNum));
if ADOcString<>'' then
treeT1.Items.AddChild(TypeLibNode,'Help string:'+ADocString);
if AHelpContext<>0 then
treeT1.Items.AddChild(TypeLibNode,'Help context:'+IntToStr(AHelpContext));

New(Names);
try
//载入函数
FunctionsNode:=treeT1.Items.AddChild(TypeLibNode,'Functions');
for FuncIndex:=0 to TypeAttr.cFuncs-1 do begin
TypeInfo.GetFuncDesc(FuncIndex,FuncDesc);
try
TypeInfo.GetDocumentation(FuncDesc.memid,@AName,@ADocString,@AhelpContext,nil);
FunctionNode:=treeT1.Items.AddChild(FunctionsNode,AName);
if ADOcString<>'' then
treeT1.Items.AddChild(FunctionNode,'Help string:'+ADocString);
if AHelpContext<>0 then
treeT1.Items.AddChild(FunctionNode,'Help context:'+IntToStr(AHelpContext));

if FuncDesc.cParams>0 then begin
//载入参数
ParametersNode:=treeT1.Items.AddChild(FunctionNode,'Paramerters');
TypeInfo.GetNames(FuncDesc.memid,Names,SizeOf(TBStrList),cNames);

//Skip Names[0] -it's the function name
for ParamIndex:=1 to FuncDesc.cParams do
treeT1.Items.AddChild(ParametersNode,Names[ParamIndex]);
end;
finally
TypeInfo.ReleaseFuncDesc(FuncDesc);
end;
end;
finally
Dispose(Names);
end;
end;
 
上一个问题(http://www.delphibbs.com/delphibbs/dispq.asp?lid=3157909 )在piao40993470的帮助下解决了。现在又有新问题了。
如果得到Automation中方法的参数的类型?
方法、属性和参数都可以得到了,参数的类型呢?怎么得到?《Delphi COM深入编程》书中没有提到,搞得我查了半天资料也没有查到,偶尔有一点VC的资料,看了半天也是没有获取参数类型的代码,晕菜~
还请大家多多指点,也请piao40993470帮忙看看。
付一段《Delphi COM深入编程》中的例程。
procedure TForm1.LoadInterface(TypeInfo:ITypeInfo;TypeAttr:PTypeAttr);
var
TypeLibNode:TTreeNode;
AName:WideString;
ADOcString:WideString;
AHelpContext:LongInt;
FunctionsNode:TTreeNode;
FunctionNode:TTreeNode;
FuncIndex:Integer;
FuncDesc:PFuncDesc;
ParametersNode:TTreeNode;
ParamIndex:Integer;
Names:PBStrList;
cNames:Integer;
begin
TypeInfo.GetDocumentation(-1,@AName,@ADocString,@AHelpContext,nil);
if TypeAttr.typekind=TKIND_DISPATCH then
TypeLibNode:=treeT1.Items.AddChild(FDispatchRoot,AName)
else
TypeLibNode:=treeT1.Items.AddChild(FInterfaceRoot,AName);

treeT1.Items.AddChild(TypeLibNode,GUIDToString(TypeAttr.guid));
treeT1.Items.AddChild(TypeLibNode,'Version '+IntToStr(TypeAttr.wMajorVerNum)+'.'+IntToStr(TypeAttr.wMinorVerNum));
if ADOcString<>'' then
treeT1.Items.AddChild(TypeLibNode,'Help string:'+ADocString);
if AHelpContext<>0 then
treeT1.Items.AddChild(TypeLibNode,'Help context:'+IntToStr(AHelpContext));

New(Names);
try
//载入函数
FunctionsNode:=treeT1.Items.AddChild(TypeLibNode,'Functions');
for FuncIndex:=0 to TypeAttr.cFuncs-1 do begin
TypeInfo.GetFuncDesc(FuncIndex,FuncDesc);
try
TypeInfo.GetDocumentation(FuncDesc.memid,@AName,@ADocString,@AhelpContext,nil);
FunctionNode:=treeT1.Items.AddChild(FunctionsNode,AName);
if ADOcString<>'' then
treeT1.Items.AddChild(FunctionNode,'Help string:'+ADocString);
if AHelpContext<>0 then
treeT1.Items.AddChild(FunctionNode,'Help context:'+IntToStr(AHelpContext));

if FuncDesc.cParams>0 then begin
//载入参数
ParametersNode:=treeT1.Items.AddChild(FunctionNode,'Paramerters');
TypeInfo.GetNames(FuncDesc.memid,Names,SizeOf(TBStrList),cNames);

//Skip Names[0] -it's the function name
for ParamIndex:=1 to FuncDesc.cParams do
treeT1.Items.AddChild(ParametersNode,Names[ParamIndex]);
end;
finally
TypeInfo.ReleaseFuncDesc(FuncDesc);
end;
end;
finally
Dispose(Names);
end;
end;
 
烦啊烦。问题又有了。
在ActiveX中如果要传递图像,如果导入tlb文件,这样的句子很容易实现。
SetOlePicture(Image1.Picture,FDemo.Picture as IPictureDisp);
但是,如果我是晚绑定的呢?一个最简单的例子。
SetOlePicture(Image1.Picture,OleContainer1.OleObject.Icon as IPictureDisp);
编译没法通过的,换成invoke方式,用VarResult来这样做也是一样没法编译的。
类似传图像的例子都是前期绑定,没有谈到后期绑定的情况。

大家帮帮我吧~~~(注:先帮前面那个问题,这个地方可以用base64编码后传文本解决)
 
对应于参数的参数类型是
FuncDesc^.lprgelemdescParam[ParamIndex].tdesc.vt
基值对应于ActiveX单元中475 -- 571 中的描述


{$EXTERNALSYM VT_EMPTY}
VT_EMPTY = 0; { [V] [P] nothing }
{$EXTERNALSYM VT_NULL}
VT_NULL = 1; { [V] SQL style Null }
{$EXTERNALSYM VT_I2}
VT_I2 = 2; { [V][T][P] 2 byte signed int }
{$EXTERNALSYM VT_I4}
VT_I4 = 3; { [V][T][P] 4 byte signed int }
{$EXTERNALSYM VT_R4}
VT_R4 = 4; { [V][T][P] 4 byte real }
{$EXTERNALSYM VT_R8}
VT_R8 = 5; { [V][T][P] 8 byte real }
{$EXTERNALSYM VT_CY}
VT_CY = 6; { [V][T][P] currency }
{$EXTERNALSYM VT_DATE}
VT_DATE = 7; { [V][T][P] date }
{$EXTERNALSYM VT_BSTR}
VT_BSTR = 8; { [V][T][P] binary string }
{$EXTERNALSYM VT_DISPATCH}
VT_DISPATCH = 9; { [V][T] IDispatch FAR* }
{$EXTERNALSYM VT_ERROR}
VT_ERROR = 10; { [V][T] SCODE }
{$EXTERNALSYM VT_BOOL}
VT_BOOL = 11; { [V][T][P] True=-1, False=0 }
{$EXTERNALSYM VT_VARIANT}
VT_VARIANT = 12; { [V][T][P] VARIANT FAR* }
{$EXTERNALSYM VT_UNKNOWN}
VT_UNKNOWN = 13; { [V][T] IUnknown FAR* }
{$EXTERNALSYM VT_DECIMAL}
VT_DECIMAL = 14; { [V][T] 16 byte fixed point }

{$EXTERNALSYM VT_I1}
VT_I1 = 16; { [T] signed char }
{$EXTERNALSYM VT_UI1}
VT_UI1 = 17; { [T] unsigned char }
{$EXTERNALSYM VT_UI2}
VT_UI2 = 18; { [T] unsigned short }
{$EXTERNALSYM VT_UI4}
VT_UI4 = 19; { [T] unsigned long }
{$EXTERNALSYM VT_I8}
VT_I8 = 20; { [T][P] signed 64-bit int }
{$EXTERNALSYM VT_UI8}
VT_UI8 = 21; { [T] unsigned 64-bit int }
{$EXTERNALSYM VT_INT}
VT_INT = 22; { [T] signed machine int }
{$EXTERNALSYM VT_UINT}
VT_UINT = 23; { [T] unsigned machine int }
{$EXTERNALSYM VT_VOID}
VT_VOID = 24; { [T] C style void }
{$EXTERNALSYM VT_HRESULT}
VT_HRESULT = 25; { [T] }
{$EXTERNALSYM VT_PTR}
VT_PTR = 26; { [T] pointer type }
{$EXTERNALSYM VT_SAFEARRAY}
VT_SAFEARRAY = 27; { [T] (use VT_ARRAY in VARIANT) }
{$EXTERNALSYM VT_CARRAY}
VT_CARRAY = 28; { [T] C style array }
{$EXTERNALSYM VT_USERDEFINED}
VT_USERDEFINED = 29; { [T] user defined type }
{$EXTERNALSYM VT_LPSTR}
VT_LPSTR = 30; { [T][P] null terminated string }
{$EXTERNALSYM VT_LPWSTR}
VT_LPWSTR = 31; { [T][P] wide null terminated string }

{$EXTERNALSYM VT_FILETIME}
VT_FILETIME = 64; { [P] FILETIME }
{$EXTERNALSYM VT_BLOB}
VT_BLOB = 65; { [P] Length prefixed bytes }
{$EXTERNALSYM VT_STREAM}
VT_STREAM = 66; { [P] Name of the stream follows }
{$EXTERNALSYM VT_STORAGE}
VT_STORAGE = 67; { [P] Name of the storage follows }
{$EXTERNALSYM VT_STREAMED_OBJECT}
VT_STREAMED_OBJECT = 68; { [P] Stream contains an object }
{$EXTERNALSYM VT_STORED_OBJECT}
VT_STORED_OBJECT = 69; { [P] Storage contains an object }
{$EXTERNALSYM VT_BLOB_OBJECT}
VT_BLOB_OBJECT = 70; { [P] Blob contains an object }
{$EXTERNALSYM VT_CF}
VT_CF = 71; { [P] Clipboard format }
{$EXTERNALSYM VT_CLSID}
VT_CLSID = 72; { [P] A Class ID
 
后期绑定也可以的呀,
参数类型应该是
MyDispParams: TDispParams;
MyParams: array[0..1] of TVariantArg;
VarResult: OleVariant;
ExcepInfo: TExcepInfo;
调用时
MyParams[0].vt := VT_BSTR;
MyParams[0].bstrVal := '我的子窗体';
[red]MyParams[1].vt := VT_UNKNOWN;
MyParams[1].unkVal := Pointer(MyClass);[/red]
with MyDispParams do
begin
rgvarg := @MyParams;
rgdispidNamedArgs := nil;
cArgs := 2;
cNamedArgs := 0;
end;
MyStatus := MyIntf.Invoke(201,GUID_NULL,0,DISPATCH_METHOD,MyDispParams,@VarResult, @ExcepInfo, nil);

其中MyClass就是一个接口类型,在接口函数中用IUnknown类型,
函数中再MyClass as IPictureDisp回去用就可以了嘛
 
老大,能否指点一些这方面的资料来源或者书籍呢?
 
其中MyClass就是一个接口类型,在接口函数中用IUnknown类型,
函数中再MyClass as IPictureDisp回去用就可以了嘛
========================
哪里有MyClass变量了?
 
只是没给出定义而已,你就当它是个接口类型就可以了吧,由于任意一个接口都是从IUnknown继承而来的,所以用IUnknown作为参数是没问题的。

了解有关OLE、COM的基础知识看《Delphi6 开发人员指南》就可以了
 
访问一个Get属性,如果这个属性是IPicture类型的,通过invoke调用,返回的属性值应该在“VarResult”里面吧,怎么转成IPicture?
piao给的例子是通过方法的out参数返回的。
 
混乱了?!
你给出的问题不是怎么通过Invoke调用这样一个方法吗?
SetOlePicture(Image1.Picture,FDemo.Picture as IPictureDisp);
也就是说现在你的这个方法有两个参数
一个是TPicture类型的,一个是IPictureDisp。
我回答的方法就是说明,怎么传递对象或者是接口为参数类型的Invoke调用
 
呀~没给说清楚:)不好意思。
SetOlePicture和GetOlePicture是delphi自己带的函数,作用是在IPictureDisp和TPicture之间转换。
[green]如果得到Automation中方法的参数的类型?方法、属性和参数都可以得到了,参数的类型呢?[/green]这些问题已经解决了。
我现在的问题是:[red]我有一个属性,是Get方式的,是TPicture类型的,我如何通过invoke方式得到这个属性的值?[/red]
提到SetOlePicture和GetOlePicture是delphi是因为——我使用后期绑定的方法,
var
a:Varaint;
begin
a:=OleContainer1.OleObject;
//ActiveX中定义为property Icon: IPicture read Get_Icon;
GetOlePicture(Image1.Picture,a.Icon as IPictureDisp);[blue]//编译失败![/blue]
end;
 
在AxCtrls单元中的定义:
[red]procedure GetOlePicture(Picture: TPicture; var OlePicture: IPictureDisp);[/red]
第二个参数是变参,你直接a.Icon as IPictureDisp这样调用当然不行了,
定义个临时变量试试
 
这样写么?
procedure TForm1.BitBtn1Click(Sender: TObject);
var
a:Variant;
b:IPictureDisp;
begin
a:=OleContainer1.OleObject;
b:=a.Icon as IPictureDisp;//编译卡壳了。
SetOlePicture(Image1.Picture,b);
end;
 
你确定Icon的类型能转换为IPictureDisp吗?
如果是TIcon的话肯定是不行的
 
我是用TPicture来加载Icon,对于TPicture是肯定可以转IPictureDisp的。
由于后期绑定没法as IPictureDisp,所以暂时通过其他方法解决先了。例如base64编码一下。
放分。谢谢piao的指点。现在在看delphi6开发人员指南中有关的章节,介绍得还不错。
 
后退
顶部