個人的には、DELPHI の activex コントロールの実装の制限は、DELPHI の activex コントロールの基本クラスが次のように TAutoObject から派生しているという事実にあると思います。
TActiveXControl = クラス(TAutoObject,
IConnectionPointContainer、
IDataObject、
IObjectSafety、
IOleコントロール、
IOleInPlaceActiveObject、
IOleInPlaceオブジェクト、
IOleオブジェクト、
iperPROpertyBrowsing、
IPersistPropertyバッグ、
IPersistストレージ、
IPersistStreamInit、
Iクイックアクティベート、
ISimpleFrameSite、
ISpecifyPropertyPages、
IViewObject、
IViewObject2)
....
....
終わり;
DELPHI を使用して activex コントロールを作成したことのある人は、DELPHI の activex コントロール ウィザードでコントロールに含まれる VCL フォーム コントロール (TWinControl から派生した VCL コントロール) を指定する必要があることを知っています。そのため、この VCL フォーム コントロールを作成するには、その実装に VCL フォーム コントロールが含まれている必要があります。 DELPHI はいつでも利用できるように、コントロールの親ウィンドウも提供します。以下のコードを見てください。
プロシージャ TActiveXControl.Initialize;
始める
継承された初期化。
FConnectionPoints := TConnectionPoints.Create(Self);
FControlFactory := TActiveXControlFactory としてのファクトリ;
FControlFactory.EventTypeInfo <> nil の場合
FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID,
ckSingle、EventConnect);
FPropertySinks := FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink,
ckMulti、nil);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
FControl.ControlStyle に csReflector がある場合、
FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) else
FWinControl := FControl;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
コントロールを初期化します。
終わり;
これは、DELPHI の activex コントロールの実装の制限です。このパーキングウィンドウをどのように制御すればよいでしょうか?少なくとも現時点では、DELPHI は vc light Magnitude control と同様のものを実装する必要があります (IPersistStreamInit のみを実装します)。 IOleControl、IOleObject、IOleInPlaceActiveObject、IViewObjectEx、IOleInPlaceObjectWindowless インターフェイス (これらのインターフェイスの COM オブジェクト) は、必要に応じてインターフェイスを実装することはもちろん、(activex コントロールが IE、Word、またはその他で使用されるかどうかによって異なります) 非常に困難です。 1 つの解決策は、次のように TAutoObject からではなく、フォーム コントロールから直接派生することです。
TMyActiveXControl=クラス(TMyControl,
//TMyControl は一般クラスまたは VCL フォーム コントロール クラスです。
//以下のインターフェースは必ずしも派生して実装する必要はありません。オンデマンドで派生および実装可能
IConnectionPointContainer、
IDataObject、
IObjectSafety、
IOleコントロール、
IOleInPlaceActiveObject、
IOleInPlaceオブジェクト、
IOleオブジェクト、
IPerPropertyBrowsing、
IPersistPropertyバッグ、
IPersistストレージ、
IPersistStreamInit、
Iクイックアクティベート、
ISimpleFrameSite、
ISpecifyPropertyPages、
IViewObject、
IViewObject2)
....
....
終わり;
しかし、その場合、この activex コントロールをどのように登録するかという新たな問題が生じます。適切なクラス ファクトリ オブジェクトがないため、DELPHI のクラス ファクトリには次の関係があります。
-->TActiveXControlFactory-->TActiveFormFactory
TComObjectFactory は次のように実装されます。
TComObject = クラス(TObject, IUnknown, ISupportErrorInfo)
。 。 。 。
終わり;
TComClass = TComObject のクラス。
TComObjectFactory = クラス(TObject, IUnknown, IClassFactory, IClassFactory2)
……
コンストラクター Create(ComServer: TComServerObject; ComClass: TComClass;
const クラス ID: TGUID、説明: 文字列;
インスタンス化: TClassInstancing; スレッドモデル: TThreadingModel = tmSingle);
終わり;
クラス ファクトリのコンストラクタにはパラメータ ComClass が必要であり、TComObject は TObject から派生します。そのため、次の delphi 実装がない限り、派生元となる適切なクラス ファクトリの基本クラスが見つからない場合は次のとおりです。
TMyComObject = クラス(TMyControl, IUnknown, ISupportErrorInfo)
。 。 。 。
終わり;
TMyComClass = TMyComObject のクラス;
TMyComObjectFactory = class(TObject, IUnknown, IClassFactory, IClassFactory2)
……
コンストラクター Create(ComServer: TComServerObject; MyComClass: TMyComClass;
const クラス ID: TGUID、説明: 文字列;
インスタンス化: TClassInstancing; スレッドモデル: TThreadingModel = tmSingle);
終わり;
残念ながら、たとえそのようなクラスがあったとしても、この制限は、次のような DELPHI の COM クラス ファクトリの実装に起因しています。
TComServer = クラス(TComServerObject)
プライベート
。 。 。 。
プロシージャ FactoryFree(ファクトリ: TComObjectFactory);
プロシージャ FactoryRegisterClassObject(ファクトリ: TComObjectFactory);
プロシージャ FactoryUpdateRegistry(ファクトリ: TComObjectFactory);
プロシージャ Lastリリース;
終わり;
問題はこれらの関数にあり、これらの関数はパラメータが TComObjectFactory である必要があるため、Delphi が提供する COM サーバーの実装を使用する必要があります。インターフェイスを使用しない理由としては、たとえば次のような実装があります。
TComServer = クラス(TComServerObject)
プライベート
。 。 。 。
プロシージャ FactoryFree(ファクトリ: IClassFactory);
プロシージャ FactoryRegisterClassObject(ファクトリ: IClassFactory);
プロシージャ FactoryUpdateRegistry(ファクトリ: IClassFactory);
プロシージャ Lastリリース;
終わり;
結局のところ、問題は、Delphi が提供する COM サーバーとクラス ファクトリの実装にあります。少なくとも、私が考えられる唯一の解決策はまだありません。 COM サーバー DLL と独自の ActiveX コントロール クラス ファクトリを実装します (実際に作成しました。非常にシンプルに感じられます。COM サーバーを実装するためのいくつかの Delph メソッドは直接使用できます)。