Лично я считаю, что ограничение реализации элемента управления ActiveX в DELPHI заключается в том, что базовый класс элемента управления ActiveX в DELPHI является производным от TAutoObject следующим образом:
TActiveXControl = класс (TAutoObject,
ИСоединениеПоинтКонтейнер,
ИДанныеОбъект,
ИОбъектБезопасность,
Иолеконтрол,
Иолеинплацеактивеобъект,
Иолеинплацеобъект,
ИОлеОбъект,
iperPRopertyПросмотр,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
ЯВьюОбъект,
IViewObject2)
....
....
конец;
Любой, кто использовал DELPHI для создания элементов управления ActiveX, знает, что мастер элементов управления ActiveX DELPHI должен указать элемент управления формой VCL, содержащийся в элементе управления (элемент управления VCL, производный от TWinControl), поэтому его реализация должна включать элемент управления формой VCL. Чтобы создать этот элемент управления формой VCL. доступный в любое время, DELPHI также предоставляет родительское окно для элемента управления. Посмотрите на код ниже:
процедура TActiveXControl.Initialize;
начинать
унаследовано Инициализировать;
FConnectionPoints: = TConnectionPoints.Create(Self);
FControlFactory := Фабрика как TActiveXControlFactory;
если FControlFactory.EventTypeInfo <> ноль, то
FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID,
ckSingle, EventConnect);
FPropertySinks: = FConnectionPoints.CreateConnectionPoint(IPPropertyNotifySink,
ckMulti, ноль);
FControl:= FControlFactory.WinControlClass.CreateParented(ParkingWindow);
если csReflector в FControl.ControlStyle, тогда
FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) еще
ФВинКонтроль := ФКонтроль;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
ИнициализироватьКонтроль;
конец;
Это ограничение реализации элемента управления activex в DELPHI. Как нам управлять этим окном парковки? Даже если мы можем контролировать размер всего элемента управления activex и значительно его расширять, чем меньше элемент управления activex в Интернете, тем лучше. по крайней мере, теперь DELPHI должен реализовать что-то похожее на управление Magnitude vclight (реализует только IPersistStreamInit, IOleControl, IOleObject, IOleInPlaceActiveObject, IViewObjectEx, IOleInPlaceObjectWindowless-интерфейсы (COM-объекты этих интерфейсов) очень сложны, не говоря уже о реализации интерфейса по мере необходимости (в зависимости от того, используется ли элемент activex в IE, Word или других). Одним из решений является не получение наследника от TAutoObject, а непосредственно из элемента управления формы следующим образом:
TMyActiveXControl=класс(TMyControl,
//TMyControl — это общий класс или класс управления формой VCL.
//Следующие интерфейсы не всегда нужно создавать и реализовывать. Может быть получен и реализован по требованию
ИСоединениеПоинтКонтейнер,
ИДанныеОбъект,
ИОбъектБезопасность,
Иолеконтрол,
Иолеинплацеактивеобъект,
Иолеинплацеобъект,
ИОлеОбъект,
IPerPropertyBrowsing,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
ЯВьюОбъект,
IViewObject2)
....
....
конец;
Но если это так, то возникает новая проблема: как зарегистрировать этот активный элемент управления? Поскольку подходящего объекта фабрики классов нет, фабрика классов DELPHI имеет следующую связь:
--> TActiveXControlFactory --> TActiveFormFactory
И TComObjectFactory реализован вот так:
TComObject = класс (TObject, IUnknown, ISupportErrorInfo)
. . . .
Конец;
TComClass = класс TComObject;
TComObjectFactory = класс (TObject, IUnknown, IClassFactory, IClassFactory2)
…..
конструктор Create(ComServer: TComServerObject; ComClass: TComClass;
const ClassID: TGUID; const ClassName, Описание: строка;
Создание экземпляра: TClassInstancingModel: TThreadingModel = tmSingle);
Конец;
Конструктору фабрики классов требуется параметр ComClass, а TComObject является производным от TObject. Поэтому, если мы не можем найти подходящий базовый класс фабрики классов для получения, если не существует следующей реализации Delphi:
TMyComObject = класс (TMyControl, IUnknown, ISupportErrorInfo)
. . . .
Конец;
TMyComClass = класс TMyComObject;
TMyComObjectFactory = класс (TObject, IUnknown, IClassFactory, IClassFactory2)
…..
конструктор Create(ComServer: TComServerObject; MyComClass: TMyComClass;
const ClassID: TGUID; const ClassName, Описание: строка;
Создание экземпляра: TClassInstancingModel: TThreadingModel = tmSingle);
Конец;
К сожалению, даже если такой класс существует, мы не можем его использовать. Это ограничение связано со следующей реализацией фабрики классов COM в DELPHI:
TComServer = класс (TComServerObject)
Частный
. . . .
процедура FactoryFree (Фабрика: TComObjectFactory);
процедура FactoryRegisterClassObject (Factory: TComObjectFactory);
процедура FactoryUpdateRegistry (Factory: TComObjectFactory);
процедура LastReleased;
конец;
Проблема заключается в этих функциях. Эти функции требуют, чтобы параметры имели тип TComObjectFactory, а это означает, что необходимо использовать реализацию COM-сервера, предоставленную Delphi. Тогда фабрика классов COM-объекта должна быть производной от TComObjectFactory. идея, почему без использования интерфейса, например, следующая реализация:
TComServer = класс (TComServerObject)
Частный
. . . .
процедура FactoryFree (Фабрика: IClassFactory);
процедура FactoryRegisterClassObject (Фабрика: IClassFactory);
процедура FactoryUpdateRegistry (Factory: IClassFactory);
процедура LastReleased;
конец;
В конечном счете, проблема заключается в реализации COM-сервера и фабрики классов, предоставляемых Delphi. Теперь я ничего не могу сделать. По крайней мере, я пока не нашел хорошего решения. Единственное, о чем я могу сейчас подумать. реализовать dll COM-сервера и мою собственную фабрику классов элементов управления ActiveX (я действительно сделал ее, она кажется очень простой, некоторые методы Delph для реализации COM-серверов можно использовать напрямую).