获取idispatch接口的Idispatch成员的访问权限

时间:2010-09-12 03:42:30

标签: delphi interface invoke idispatch

我是一名物理学家。我正在尝试使用导入的activex控件(ocx文件)处理Delphi。假设库中有3个自动化接口:IGraph,IGraphAxes和IAxis。该库的结构如下:

=== IGraph的属性:===
Idispatch * IGraphAxes;
...... //其他成员

=== IGraphAxes的属性:===
Idispatch * XAxis;
Idispatch * YAxis;
Idispatch * ZAxis;
整数颜色;
整数风格;
...... //其他成员

=== IAxis属性:===
float Min,Max;
Boolean ShowNumbers;
...... //其他成员

从IGraph,我可以使用GetIDsOfNames()和Invoke()函数访问IGraphAxes(颜色和样式)的简单成员。但是当我尝试访问XAxis(或YAxis,Zaxis)时,它会生成错误。首先,我使用GetIDsOfNames()并返回XAxis的dispid而没有任何问题。但是,当我使用该dispid调用Invoke时,会出现“地址访问冲突...”错误。看来,idispatch指针(** Xaxis)*指向什么都没有。我怎么解决这个问题?如何制作 Idispatch * Xaxis

IAxis接口是否相互连接?
附:对不起我的英语,我不是母语人士

4 个答案:

答案 0 :(得分:2)

Delphi内置了对IDispatch后期绑定的支持,因此您无需直接调用Invoke()。只需像普通属性一样访问成员,Delphi将为您在幕后调用Invoke()。

如果您想直接调用Invoke(),请显示失败的实际代码。 AV很可能是由于代码中的错误而不是OCX本身的错误。

答案 1 :(得分:0)

感谢您的回复。 实际上,activex控件是用于绘制一些3d图形的第三方可视组件。 以下是activex库的内容:

  

[
   UUID(...),
   版本(x.x中),
   helpstring(“3-D Graph模块”),
  控制,
   自定义(...,...),
  自定义(...,...)
  ]

     

库   GraphLib
  {

     

导入库( “STDOLE2.TLB”);

     

[
      UUID(...),
      helpstring(“用于三维图形控制的调度接口”),
      隐藏
    ]
    dispinterface _IGraph
    {
      属性:
      [
      ID(0x0000006)
      ]
      IDispatch * GraphAxes(...);
      方法:
      [
      ID(0x0000001)
      ]
      byte AddScatterGraph(...);
      [
      ID(0x0000002)
      ]
      byte AddVectorFieldGraph(...);
      [
      ID(0x0000003)
      ]
      byte AddParametricSurfaceGraph(...);
      [
      ID(0x0000004)
      ]
      byte AddSurfaceGraph(...);
      [
      ID(0x0000005)
      ]
      byte RemoveGraphs(void);
       };
       [
      UUID(...),
      helptring(“三维图形控制”),
      控制
       ]
      coclass cGraph
      {
      [default] dispinterface _IGraph;
      [default,source] dispinterface _IGraphEvents;
       };
       [
      UUID(...)
       ]
       调度表IGraphAxis
      {
      属性:
      [
      ID(00000001)
      ]
      字节编号;
      [
      ID(0x00000002)
      ]
      双敏;
      [
      ID(0x00000003)
      ]
      double Max;
      [
      ID(0x00000004)
      ]
      简短的GridNum;
      [
      ID(0x00000005)
      ]
      byte ShowLabel;
      方法:
     };
     [
      UUID(...)
     ]
     coclass cGraphAxis
     {
      [default] dispinterface IGraphAxis;
     };
      [
      UUID(...)
      ]
      调度表IGraphAxes
      {
      属性:
      [
      ID(00000001)
      ]
       IDispatch * XAxis;
      [
      ID(0x00000002)
      ]
       IDispatch * YAxis;
      [
      ID(0x00000003)
      ]
       IDispatch * ZAxis;
      [
      ID(0x00000004)
      ]
       整数颜色;
      [
      ID(0x00000005)
      ]
       整数风格;
      方法:
     };
      [
      UUID(...)
      ]
      coclass cGraphAxes
     {
      [default] dispinterface IGraphAxes;
     };
      [
      UUID(...),
      helpstring(“用于三维图形控制的事件界面”)
      ]
      dispinterface _IGraphEvents
     {
      属性:
      方法:
      [
      ID(0xFFFFFDA3)
      ]
      void MouseDown(...);
      [
      ID(0xFFFFFDA8)
      ]
      void点击...);
      [
      ID(0xFFFFFDA7)
      ]
      void DblClick(...);
      [
      ID(0xFFFFFDA6)
      ]
      void KeyDown(...);
      [
      ID(0xFFFFFDA5)
      ]
      void KeyPress(...);
      [
      ID(0xFFFFFDA4)
      ]
      void KeyUp(...);
      [
      ID(0xFFFFFDA2)
      ]
      void MouseMove(...);
      [
      ID(0xFFFFFDA1)
      ]
      void MouseUp(...);
     };
   };

答案 2 :(得分:0)

这是从类型库生成的单元文件 unit GraphLib_TLB;

// ************************************************************************  
// The types declared in this file were generated from data read from a       
// Type Library. If this type library is explicitly or indirectly (via        
// another type library referring to this type library) re-imported, or the   
// 'Refresh' command of the Type Library Editor activated while editing the   
// Type Library, the contents of this file will be regenerated and all        
// manual modifications will be lost.                                         
// ************************************************************************ //

// ************************************************************************  //  
// Type Lib: graph3d.ocx (1)  
// LIBID: {...}  
// LCID: 0  
// HelpString: 3-D Graph module  
// DepndLst:   
//   (1) v2.0 stdole, (C:\Windows\system32\stdole2.tlb)  
// ************************************************************************ //  
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.   
{$WARN SYMBOL_PLATFORM OFF}  
{$WRITEABLECONST ON}  
{$VARPROPSETTER ON}  
interface  

uses Windows, ActiveX, Classes, Graphics, OleCtrls, OleServer, StdVCL, Variants;  

// *********************************************************************//  
// GUIDS declared in the TypeLibrary. Following prefixes are used:        
//   Type Libraries     : LIBID_xxxx                                      
//   CoClasses          : CLASS_xxxx                                      
//   DISPInterfaces     : DIID_xxxx                                       
//   Non-DISP interfaces: IID_xxxx                                        
// *********************************************************************//  
const  
  // TypeLibrary Major and minor versions  
  GraphLibMajorVersion = x;  
  GraphLibMinorVersion = x;  

  LIBID_GLLib: TGUID = '{...}';  

  DIID__IGraph: TGUID = '{...}';  
  DIID__IGraphEvents: TGUID = '{...}';  
  CLASS_cGraph: TGUID = '{...}';  
  DIID_IGraphAxis: TGUID = '{...}';  
  CLASS_cGraphAxis: TGUID = '{...}';  
  DIID_IGraphAxes: TGUID = '{...}';  
  CLASS_cGraphAxes: TGUID = '{...}';  
type  

// *********************************************************************//  
// Forward declaration of types defined in TypeLibrary                      
// *********************************************************************//  
  _IGraph = dispinterface;  
  _IGraphEvents = dispinterface;  
  IGraphAxis = dispinterface;   
  IGraphAxes = dispinterface;  
// *********************************************************************//  
// Declaration of CoClasses defined in Type Library                         
// (NOTE: Here we map each CoClass to its Default Interface)                
// *********************************************************************//  
  cGraph = _IGraph;  
  cGraphAxis = IGraphAxis;  
  cGraphAxes = IGraphAxes;  

// *********************************************************************//  
// Declaration of structures, unions and aliases.                           
// *********************************************************************//  
  PWideString1 = ^WideString; {*}  
  PShortint1 = ^Shortint; {*}  
  PSmallint1 = ^Smallint; {*}  

// *********************************************************************//  
// DispIntf:  _IGraph  
// Flags:     (4112) Hidden Dispatchable  
// GUID:      {...}  
// *********************************************************************//  
  _IGraph = dispinterface  
    ['{...}']  
    function AddScatterGraph(...): {??Shortint}OleVariant; dispid 1;  
    function AddVectorFieldGraph(...): {??Shortint}OleVariant; dispid 2;  
    function AddParametricSurfaceGraph(...): {??Shortint}OleVariant; dispid 3;  
    function AddSurfaceGraph(...): {??Shortint}OleVariant; dispid 4;  
    function RemoveGraphs: {??Shortint}OleVariant; dispid 5;  
    property GraphAxes: IDispatch dispid 6;  
  end;  

// *********************************************************************//  
// DispIntf:  _IGraphEvents  
// Flags:     (4096) Dispatchable  
// GUID:      {...}  
// *********************************************************************//  
  _IGraphEvents = dispinterface  
    ['{...}']  
    procedure MouseDown(); dispid -605;  
    procedure Click; dispid -600;  
    procedure DblClick; dispid -601;  
    procedure KeyDown(...); dispid -602;  
    procedure KeyPress(...); dispid -603;  
    procedure KeyUp(...); dispid -604;  
    procedure MouseMove(...); dispid -606;  
    procedure MouseUp(...); dispid -607;  
    procedure ReadyStateChange; dispid -609;  
  end;  

// *********************************************************************//  
// DispIntf:  IGraphAxis  
// Flags:     (4096) Dispatchable  
// GUID:      {...}  
// *********************************************************************//  
  IGraphAxis = dispinterface  
    ['{...}']  
    property Numbered: {??Shortint}OleVariant dispid 1;  
    property Min: Double dispid 2;  
    property Max: Double dispid 3;  
    property GridNum: Smallint dispid 4;  
    property ShowLabel: {??Shortint}OleVariant dispid 5;        
  end;  

// *********************************************************************//  
// DispIntf:  IGraphAxes  
// Flags:     (4096) Dispatchable  
// GUID:      {...}  
// *********************************************************************//  
  IGraphAxes = dispinterface  
    ['{...}']  
    property XAxis: IDispatch dispid 1;  
    property YAxis: IDispatch dispid 2;  
    property ZAxis: IDispatch dispid 3;  
    property Color: Integer dispid 4;  
    property Style: Smallint dispid 5;  
  end;  

// *********************************************************************//  
// OLE Control Proxy class declaration  
// Control Name     : TGraph  
// Help String      : 3-D Graph Control  
// Default Interface: _IGraph  
// Def. Intf. DISP? : Yes  
// Event   Interface: _IGraphEvents  
// TypeFlags        : (34) CanCreate Control  
// *********************************************************************//  
  TGraph = class(TOleControl)  
  private  
    FOnError: TGraphError;  
    FOnReadyStateChange: TNotifyEvent;  
    FIntf: _IGraph;  
    function  GetControlInterface: _IGraph;  
  protected  
    procedure CreateControl;  
    procedure InitControlData; override;  
    function Get_GraphAxes: IDispatch;  
    procedure Set_GraphAxes(const Value: IDispatch);  
  public  
    function AddScatterGraph(...): {??Shortint}OleVariant;  
    function AddVectorFieldGraph(...): {??Shortint}OleVariant;  
    function AddParametricSurfaceGraph(...): {??Shortint}OleVariant;  
    function AddSurfaceGraph(...): {??Shortint}OleVariant;  
    function RemoveGraphs: {??Shortint}OleVariant;  
    property ControlInterface: _IGraph read GetControlInterface;  
    property DefaultInterface: _IGraph read GetControlInterface;  
    property GraphAxes: IDispatch index 6 read GetIDispatchProp write SetIDispatchProp;  
  published  
    //properties visible in the Object Inspector go here   
    ...  
    property  OnDragDrop;  
    property  OnDragOver;  
    property  OnEndDrag;  
    property  OnEnter;  
    property  OnExit;  
    property  OnStartDrag;  
    property  OnMouseUp;  
    property  OnMouseMove;  
    property  OnMouseDown;  
    property  OnKeyUp;  
    property  OnKeyPress;  
    property  OnKeyDown;  
    property  OnDblClick;  
    property  OnClick;  
    property OnError: TGraphError read FOnError write FOnError;  
    property OnReadyStateChange: TNotifyEvent read FOnReadyStateChange write FOnReadyStateChange;    
  end;    

// *********************************************************************//  
// The Class CocGraphAxis provides a Create and CreateRemote method to            
// create instances of the default interface IGraphAxis exposed by                
// the CoClass cGraphAxis. The functions are intended to be used by               
// clients wishing to automate the CoClass objects exposed by the           
// server of this typelibrary.                                              
// *********************************************************************//  
  CocGraphAxis = class  
    class function Create: IGraphAxis;  
    class function CreateRemote(const MachineName: string): IGraphAxis;  
  end;  

// *********************************************************************//  
// The Class CocGraphAxes provides a Create and CreateRemote method to            
// create instances of the default interface IGraphAxes exposed by                
// the CoClass cGraphAxes. The functions are intended to be used by               
// clients wishing to automate the CoClass objects exposed by the           
// server of this typelibrary.                                              
// *********************************************************************//  
  CocGraphAxes = class  
    class function Create: IGraphAxes;  
    class function CreateRemote(const MachineName: string): IGraphAxes;  
  end;  

procedure Register;  

resourcestring  
  dtlServerPage = 'ActiveX';  

  dtlOcxPage = 'ActiveX';  

implementation  

uses ComObj;  

procedure TGraph.InitControlData;  
const  
  CEventDispIDs: array [0..1] of DWORD = (...);  
  CLicenseKey: array[0..33] of Word = ($006F, ..., ..., e.g.);  
  CControlData: TControlData2 = (  
    ClassID: '{...}';  
    EventIID: '{...}';  
    EventCount: 2;  
    EventDispIDs: @CEventDispIDs;  
    LicenseKey: @CLicenseKey;  
    Flags: $00000000;  
    Version: 401);  
begin  
  ControlData := @CControlData;  
  TControlData2(CControlData).FirstEventOfs := Cardinal(@@FOnError) - Cardinal(Self);  
end;  

procedure TGraph.CreateControl;  

  procedure DoCreate;  
  begin  
    FIntf := IUnknown(OleObject) as _IGraph;  
  end;  

begin  
  if FIntf = nil then DoCreate;  
end;  

function TGraph.GetControlInterface: _IGraph;  
begin  
  CreateControl;  
  Result := FIntf;  
end;  

function TGraph.Get_GraphAxes: IDispatch;  
begin  
  Result := DefaultInterface.GraphAxes;  
end;  

procedure TGraph.Set_GraphAxes(const Value: IDispatch);  
begin  
  DefaultInterface.GraphAxes := Value;  
end;  

function TGraph.AddScatterGraph(...): {??Shortint}OleVariant;  
begin  
  Result := DefaultInterface.AddScatterGraph(...);  
end;  

function TGraph.AddVectorFieldGraph(...): {??Shortint}OleVariant;  
begin  
  Result := DefaultInterface.AddVectorFieldGraph(...);  
end;  

function TGraph.AddParametricSurfaceGraph(...): {??Shortint}OleVariant;  
begin  
  Result := DefaultInterface.AddParametricSurfaceGraph(...);  
end;  

function TGraph.AddSurfaceGraph(...): {??Shortint}OleVariant;  
begin  
  Result := DefaultInterface.AddSurfaceGraph(...);  
end;  

function TGraph.RemoveGraphs: {??Shortint}OleVariant;  
begin  
  Result := DefaultInterface.RemoveGraphs;  
end;  

class function CocGraphAxis.Create: IGraphAxis;  
begin  
  Result := CreateComObject(CLASS_cGraphAxis) as IGraphAxis;  
end;  

class function CocGraphAxis.CreateRemote(const MachineName: string): IGraphAxis;  
begin  
  Result := CreateRemoteComObject(MachineName, CLASS_cGraphAxis) as IGraphAxis;  
end;  

class function CocGraphAxes.Create: IGraphAxes;  
begin  
  Result := CreateComObject(CLASS_cGraphAxes) as IGraphAxes;  
end;  

class function CocGraphAxes.CreateRemote(const MachineName: string): IGraphAxes;  
begin  
  Result := CreateRemoteComObject(MachineName, CLASS_cGraphAxes) as IGraphAxes;  
end;  

procedure Register;  
begin  
  RegisterComponents(dtlOcxPage, [TGraph]);  
end;  

end.

答案 3 :(得分:0)

当我将ocx文件导入Delphi时,它会出现在Component Palette的ActiveX选项卡上。我只需用鼠标拖动它,然后放在一个表格和一个物体上  图1:TGraph;
自动添加到我的代码中。它的属性和事件在Object Inspector窗口中可见。现在我想从我的代码中访问控件的轴。如您所见,该属性表示坐标轴。另外我猜IGraphAxes的XAxis / YAxis / ZAxis成员是IGraphAxis类型的idispatch指针。我编写了以下过程来访问idispatch接口:

procedure TForm2.GetProperty(dispobj: IDispatch; PropertyName: WideString;
                                var retvalue: Variant; Sender: TObject);  
var hr: HRESULT;  
    DispId: integer;  
    value: Variant;  
    params: TDispParams;  
begin  
  hr:=dispobj.GetIDsOfNames(GUID_NULL,@PropertyName, 1, LOCALE_SYSTEM_DEFAULT, @DispId);  
  Label1.Caption:=inttostr(DispId);  
  hr:=dispobj.Invoke(DispId,GUID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_PROPERTYGET,
                  Params,@Value,nil,nil);  
  Retvalue:=Value;  
  Label2.Caption:=inttostr(value);  
end;  

procedure TForm2.SetProperty(dispobj: IDispatch; PropertyName: WideString; Value: OLEVariant; Sender: TObject);  
var   
    hr: HRESULT;  
    DispId: integer;  
    params: TDispParams;  
begin  
   hr:=dispobj.GetIDsOfNames(GUID_NULL,@PropertyName,1, LOCALE_SYSTEM_DEFAULT, @DispId);  
  Label1.Caption:=inttostr(DispId);  
  params.rgvarg:=@Value;  
  params.rgdispidNamedArgs:=@DispIDArgs;  
  params.cArgs:=1;  
  params.cNamedArgs:=1;  
  hr:=dispobj.Invoke(DispId,GUID_NULL,LOCALE_SYSTEM_DEFAULT,                  DISPATCH_PROPERTYPUT,Params,nil,nil,nil);  
 end;

它们与IGraphAxes的颜色和样式属性配合使用:

GetProperty(Graph1.GraphAxes, 'Color', retvalue, Sender);

SetProperty(Graph1.GraphAxes, 'Color',value,Sender);

但是如何完全访问IGraphAxes的XAxis / YAxis / ZAxis成员?