我是一名物理学家。我正在尝试使用导入的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接口是否相互连接?
附:对不起我的英语,我不是母语人士
答案 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成员?