Получение доступа к члену Idispatch интерфейса idispatch - PullRequest
2 голосов
/ 12 сентября 2010

Я физик. Я пытаюсь работать на Delphi с импортированным элементом управления ActiveX (файл OCX). Допустим, в библиотеке есть 3 интерфейса автоматизации: IGraph, IGraphAxes и IAxis. Структура библиотеки такова:

=== Свойства IGraph: ===
Idispatch * IGraphAxes;
... // другие участники

=== Свойства IGraphAxes: ===
Идентификатор * XAxis;
Idispatch * YAxis;
Идентификатор * ZAxis;
целое число Цвет;
целочисленный стиль;
… // другие участники

=== Свойства IAxis: ===
мин., Макс;
Логические номера шоу;
… // другие участники

Из IGraph я могу получить доступ к простым членам IGraphAxes (цвет и стиль), используя функции GetIDsOfNames () и Invoke (). Но когда я пытаюсь получить доступ к XAxis (или YAxis, Zaxis), возникает ошибка. Во-первых, я использую GetIDsOfNames () и он возвращает dispid XAxis без каких-либо проблем. Но когда я вызываю Invoke с этим показом, возникает ошибка «Нарушение доступа по адресу…». Кажется, указатель idispatch (** Xaxis) * ничего не указывает. Как я могу решить это? Как сделать
Идентификатор * Xaxis
и
Интерфейс IAxis подключен друг к другу?
Постскриптум извините за мой английский, я не являюсь носителем языка

Ответы [ 4 ]

2 голосов
/ 12 сентября 2010

Delphi имеет встроенную поддержку позднего связывания IDispatch, поэтому вам не нужно вызывать Invoke () напрямую. Просто получите доступ к членам, как к обычным свойствам, и Delphi вызовет Invoke () для вас за кулисами.

Если вы хотите вызвать Invoke () напрямую, то, пожалуйста, покажите свой фактический код, который не работает. Вероятно, AV вызван ошибкой в ​​вашем коде, а не в самом OCX.

0 голосов
/ 20 сентября 2010

Когда я импортирую файл ocx в Delphi, он появляется на вкладке ActiveX палитры компонентов. Я просто перетаскиваю его мышью и надеваю форму и объект
График 1: TGraph;
автоматически добавляется в мой код. Его свойства и события становятся видимыми в окне инспектора объектов. Теперь я хочу получить доступ к осям элемента управления из моего кода. Как видите, свойство представляет собой координатные оси. Также я предполагаю, что члены IGraphAxes XAxis / YAxis / ZAxis являются указателями idispatch типа IGraphAxis. Я написал следующие процедуры для доступа к интерфейсу 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;

Они отлично работают со свойствами Color и Style IGraphAxes:

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

или

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

Но как получить полный доступ к членам XAxis / YAxis / ZAxis IGraphAxes?

0 голосов
/ 20 сентября 2010

А вот файл модуля, сгенерированный из библиотеки типов.
блок 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.
0 голосов
/ 20 сентября 2010

Спасибо за ваш ответ. На самом деле элемент управления activex - это сторонний визуальный компонент для построения трехмерной графики. Вот содержимое библиотеки activex:

[
UUID (...),
версия (x.x),
строка помощи («Модуль 3-D графика»),
контроль,
обычай (..., ...),
обычай (..., ...)
]

библиотека GraphLib
{

importlib ( "Stdole2.tlb");

[
UUID (...),
helpstring («Интерфейс отправки для управления трехмерным графиком»),
скрыт
]
dispinterface _IGraph
{
Свойства:
[
Идентификатор (0x0000006)
]
IDispatch * GraphAxes (...);
методы:
[
Идентификатор (0x0000001)
]
байт AddScatterGraph (...);
[
Идентификатор (0x0000002)
]
байт AddVectorFieldGraph (...);
[
Идентификатор (0x0000003)
]
byte AddParametricSurfaceGraph (...);
[
Идентификатор (0x0000004)
]
байт AddSurfaceGraph (...);
[
Идентификатор (0x0000005)
]
byte RemoveGraphs (void);
}; * * Тысяча пятьдесят одна [
UUID (...),
строка помощи («Управление трехмерным графиком»),
контроль
]
кокласс cGraph
{
[по умолчанию] dispinterface _IGraph;
[по умолчанию, источник] dispinterface _IGraphEvents;
}; * +1061 * [
UUID (...)
]
dispinterface IGraphAxis
{
Свойства:
[
Идентификатор (0x00000001)
]
Байт пронумерован;
[
Идентификатор (0x00000002)
]
двойной мин;
[
Идентификатор (0x00000003)
]
двойной Макс;
[
Идентификатор (0x00000004)
]
короткий GridNum;
[
Идентификатор (0x00000005)
]
byte ShowLabel;
методы:
};
[
UUID (...)
]
кокласс cGraphAxis
{
[по умолчанию] dispinterface IGraphAxis;
};
[
UUID (...)
]
dispinterface IGraphAxes
{
Свойства:
[
Идентификатор (0x00000001)
]
IDispatch * XAxis;
[
Идентификатор (0x00000002)
]
IDispatch * YAxis;
[
Идентификатор (0x00000003)
]
IDispatch * ZAxis;
[
Идентификатор (0x00000004)
]
Целочисленный цвет;
[
Идентификатор (0x00000005)
]
целочисленный стиль;
методы:
};
[
UUID (...)
]
кокласс cGraphAxes
{
[по умолчанию] dispinterface IGraphAxes;
}; * * Одна тысяча сто тридцать одна [
UUID (...),
helpstring («Интерфейс событий для управления трехмерным графиком»)
]
dispinterface _IGraphEvents
{
Свойства:
методы:
[
Идентификатор (0xFFFFFDA3)
]
void MouseDown (…);
[
Идентификатор (0xFFFFFDA8)
]
Пустой клик…);
[
Идентификатор (0xFFFFFDA7)
]
void DblClick (…);
[
Идентификатор (0xFFFFFDA6)
]
void KeyDown (…);
[
Идентификатор (0xFFFFFDA5)
]
void KeyPress (…);
[
Идентификатор (0xFFFFFDA4)
]
void KeyUp (…);
[
Идентификатор (0xFFFFFDA2)
]
void MouseMove (…);
[
Идентификатор (0xFFFFFDA1)
]
void MouseUp (…);
}; * +1172 * };

...