2

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

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

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

===IAxis 属性:===
float Min, Max;
布尔显示编号;
… //其他成员

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

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

4

4 回答 4

2

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

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

于 2010-09-12T07:07:47.230 回答
0

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

[
uuid(...),
version(xx),
helpstring("3-D Graph module"),
control,
custom(..., ...),
custom(..., ...)
]

库 GraphLib
{

importlib("stdole2.tlb");

[
uuid(...),
helpstring("Dispatch interface for 3-D Graph Control"),
hidden
]
dispinterface _IGraph
{
properties:
[
id(0x0000006)
]
IDispatch * GraphAxes(...);
方法:
[
id(0x0000001)
]
字节 AddScatterGraph(...);
[
id(0x0000002)
]
字节 AddVectorFieldGraph(...);
[
id(0x0000003)
]
字节 AddParametricSurfaceGraph(...);
[
id(0x0000004)
]
字节 AddSurfaceGraph(...);
[
id(0x0000005)
]
字节 RemoveGraphs( 无效 );
};
[
uuid(...),
helpstring("3-D Graph Control"),
control
]
coclass cGraph
{
[default] dispinterface _IGraph;
[默认,来源] 调度接口 _IGraphEvents;
};
[
uuid(...)
]
调度接口 IGraphAxis
{
属性:
[
id(0x00000001)
]
字节编号;
[
id(0x00000002)
]
双最小;
[
id(0x00000003)
]
双最大;
[
id(0x00000004)
]
短 GridNum;
[
id(0x00000005)
]
字节显示标签;
方法:
};
[
uuid(...)
]
coclass cGraphAxis
{
[默认] dispinterface 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 图形控件的事件接口")
]
dispinterface _IGraphEvents
{
属性:
方法:
[
id(0xFFFFFDA3)
]
void MouseDown(...);
[
id(0xFFFFFDA8)
]
无效点击…);
[
id(0xFFFFFDA7)
]
无效 DblClick( …);
[
id(0xFFFFFDA6)
]
无效 KeyDown(… );
[
id(0xFFFFFDA5)
]
无效按键(…);
[
id(0xFFFFFDA4)
]
无效键(…);
[
id(0xFFFFFDA2)
]
无效 MouseMove(…);
[
id(0xFFFFFDA1)
]
无效 MouseUp(…);
};
};

于 2010-09-20T04:53:10.980 回答
0

这是从类型库生成的单元文件。
单元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.
于 2010-09-20T06:55:11.213 回答
0

当我将 ocx 文件导入 Delphi 时,它出现在 Component Palette 的 ActiveX 选项卡上。我只是用鼠标拖动它并放在一个表格和一个对象上
Graph1: 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 成员的完全访问权限?

于 2010-09-20T06:58:45.650 回答