【问题标题】:Getting an access to member of IDispatch interface获取对 IDispatch 接口成员的访问权限
【发布时间】:2010-09-12 03:42:29
【问题描述】:

我是物理学家。我正在尝试使用导入的 activex 控件(ocx 文件)在 Delphi 上工作。假设库中有 3 个自动化接口:IGraph、IGraphAxes 和 IAxis。图书馆的结构是这样的:

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

===IGraphAxes 的属性:===
Idispatch* XAxis;
Idispatch* YAxis;
Idispatch* ZAxis;
整数颜色;
整数样式;
… //其他成员

===IAxis 属性:===
浮动最小值,最大值;
布尔显示编号;
… //其他成员

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

IAxis 接口相互依附?
附言对不起我的英语,我不是母语人士

【问题讨论】:

    标签: delphi interface invoke idispatch


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      [
      uuid(...),
      版本(x.x),
      helpstring("3-D 图形模块"),
      控制,
      自定义(...,...),
      自定义(...,...)
      ]

      图书馆 图形库
      {

      importlib("stdole2.tlb");

      [
      uuid(...),
      helpstring("3-D 图形控制的调度接口"),
      隐藏
      ]
      调度接口 _IGraph
      {
      属性:
      [
      id(0x0000006)
      ]
      IDispatch * GraphAxes(...);
      方法:
      [
      id(0x0000001)
      ]
      字节 AddScatterGraph(...);
      [
      id(0x0000002)
      ]
      字节 AddVectorFieldGraph(...);
      [
      id(0x0000003)
      ]
      字节 AddParametricSurfaceGraph(...);
      [
      id(0x0000004)
      ]
      字节 AddSurfaceGraph(...);
      [
      id(0x0000005)
      ]
      字节 RemoveGraphs( 无效 );
      };
      [
      uuid(...),
      helpstring("3-D 图形控件"),
      控制
      ]
      coclass cGraph
      {
      [默认] 调度接口 _IGraph;
      [默认,来源] 调度接口 _IGraphEvents;
      };
      [
      uuid(...)
      ]
      调度接口 IGraphAxis
      {
      属性:
      [
      id(0x00000001)
      ]
      字节编号;
      [
      id(0x00000002)
      ]
      双敏;
      [
      id(0x00000003)
      ]
      双最大;
      [
      id(0x00000004)
      ]
      短 GridNum;
      [
      id(0x00000005)
      ]
      字节显示标签;
      方法:
      };
      [
      uuid(...)
      ]
      coclass cGraphAxis
      {
      [默认] 调度接口 IGraphAxis;
      };
      [
      uuid(...)
      ]
      调度接口 IGraphAxes
      {
      属性:
      [
      id(0x00000001)
      ]
      IDispatch * XAxis;
      [
      id(0x00000002)
      ]
      IDispatch * YAxis;
      [
      id(0x00000003)
      ]
      IDispatch * ZAxis;
      [
      id(0x00000004)
      ]
      整数颜色;
      [
      id(0x00000005)
      ]
      整数样式;
      方法:
      };
      [
      uuid(...)
      ]
      coclass cGraphAxes
      {
      [默认] 调度接口 IGraphAxes;
      };
      [
      uuid(...),
      helpstring("3-D 图形控件的事件接口")
      ]
      调度接口 _IGraphEvents
      {
      属性:
      方法:
      [
      id(0xFFFFFDA3)
      ]
      void MouseDown(…);
      [
      id(0xFFFFFDA8)
      ]
      无效点击...);
      [
      id(0xFFFFFDA7)
      ]
      无效 DblClick(…);
      [
      id(0xFFFFFDA6)
      ]
      void KeyDown(…);
      [
      id(0xFFFFFDA5)
      ]
      void KeyPress(…);
      [
      id(0xFFFFFDA4)
      ]
      void KeyUp(…);
      [
      id(0xFFFFFDA2)
      ]
      无效鼠标移动(…);
      [
      id(0xFFFFFDA1)
      ]
      无效 MouseUp(…);
      };
      };

      【讨论】:

        【解决方案3】:

        当我将 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 的 Color 和 Style 属性:

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

        或者

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

        但是如何获得对 IGraphAxes 的 XAxis/YAxis/ZAxis 成员的完全访问权限?

        【讨论】:

          【解决方案4】:

          这是从类型库生成的单元文件。
          单位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.
          

          【讨论】:

            猜你喜欢
            • 2021-03-15
            • 1970-01-01
            • 2011-12-25
            • 2017-10-08
            • 2019-12-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多