Personalmente, creo que la limitación de la implementación del control activex de DELPHI existe en el hecho de que la clase base del control activex de DELPHI se deriva de TAutoObject de la siguiente manera:
TActiveXControl = clase(TAutoObject,
IConnectionPointContainer,
objeto IData,
seguridad de objetos,
control de IOle,
IOleInPlaceActiveObjeto,
IOleInPlaceObjeto,
IOleObjeto,
iperPROpertyBrowsing,
IPersistPropertyBag,
almacenamiento IPersista,
IPersistStreamInit,
I activación rápida,
Sitio de marco simple,
ISpecifyPropertyPages,
IViewObjeto,
IViewObject2)
....
....
fin;
Cualquiera que haya utilizado DELPHI para crear controles activex sabe que el asistente de control activex de DELPHI debe especificar el control de formulario VCL contenido en el control (control VCL derivado de TWinControl), por lo que su implementación debe incluir un control de formulario VCL para hacer este control de formulario VCL. Disponible en cualquier momento, DELPHI también proporciona una ventana principal para el control. Mira el código a continuación:
procedimiento TActiveXControl.Initialize;
comenzar
inicializar heredado;
FConnectionPoints := TConnectionPoints.Create(Self);
FControlFactory := Fábrica como TActiveXControlFactory;
si FControlFactory.EventTypeInfo <> nulo entonces
FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID,
ckSingle, EventConnect);
FPropertySinks:= FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink,
ckMulti, nulo);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
si csReflector en FControl.ControlStyle entonces
FWinControl: = TReflectorWindow.Create (ParkingWindow, FControl) más
FWinControl := FControl;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
InicializarControl;
fin;
Esta es la limitación de la implementación del control activex de DELPHI. ¿Cómo controlamos este ParkingWindow? Incluso si podemos controlar el tamaño de todo el control activex y expandirlo mucho, cuanto más pequeño sea el control activex en Internet, mejor. al menos ahora DELPHI debe implementar algo similar al control de magnitud de vc light (solo implementa IPersistStreamInit, Las interfaces IOleControl, IOleObject, IOleInPlaceActiveObject, IViewObjectEx, IOleInPlaceObjectWindowless (objetos COM de estas interfaces) son muy difíciles, y mucho menos implementar la interfaz según sea necesario (dependiendo de si el control activex se usa en IE, Word u otros). Una solución no es derivar de TAutoObject sino directamente del control de formulario de la siguiente manera:
TMyActiveXControl=clase(TMyControl,
//TMyControl es una clase general o una clase de control de formulario VCL.
// No siempre es necesario derivar e implementar las siguientes interfaces. Puede derivarse e implementarse bajo demanda.
IConnectionPointContainer,
objeto IData,
seguridad de objetos,
control de IOle,
IOleInPlaceActiveObjeto,
IOleInPlaceObjeto,
IOleObjeto,
navegación IPerProperty,
IPersistPropertyBag,
almacenamiento IPersista,
IPersistStreamInit,
I activación rápida,
Sitio de marco simple,
ISpecifyPropertyPages,
IViewObjeto,
IViewObject2)
....
....
fin;
Pero si es así, surge un nuevo problema ¿Cómo registrar este control activex? Debido a que no existe un objeto de fábrica de clases adecuado, la fábrica de clases de DELPHI tiene la siguiente relación:
-->TActiveXControlFactory-->TActiveFormFactory
Y TComObjectFactory se implementa así,
TComObject = clase(TObject, IUnknown, ISupportErrorInfo)
. . . .
Fin;
TComClass = clase de TComObject;
TComObjectFactory = clase(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
constructor Crear(ComServer: TComServerObject; ComClass: TComClass;
const ClassID: TGUID; const ClassName, Descripción: cadena;
Instancia: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
Fin;
El constructor de la fábrica de clases requiere el parámetro ComClass, y TComObject se deriva de TObject. Por lo tanto, si no podemos encontrar una clase base de fábrica adecuada de la que derivar, a menos que exista la siguiente implementación de Delphi:
TMyComObject = clase(TMyControl, IUnknown, ISupportErrorInfo)
. . . .
Fin;
TMyComClass = clase de TMyComObject;
TMyComObjectFactory = clase(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
constructor Crear(ComServer: TComServerObject; MyComClass: TMyComClass;
const ClassID: TGUID; const ClassName, Descripción: cadena;
Instancia: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
Fin;
Desafortunadamente, incluso si existe tal clase, no podemos usarla. Esta limitación proviene de la implementación de DELPHI de la fábrica de clases COM de la siguiente manera:
TComServer = clase(TComServerObject)
Privado
. . . .
procedimiento FactoryFree(Fábrica: TComObjectFactory);
procedimiento FactoryRegisterClassObject(Fábrica: TComObjectFactory);
procedimiento FactoryUpdateRegistry(Fábrica: TComObjectFactory);
procedimiento LastReleased;
fin;
El problema radica en estas funciones. Estas funciones requieren que los parámetros sean del tipo TComObjectFactory, lo que significa que se debe utilizar la implementación del servidor COM proporcionada por Delphi. Luego, la fábrica de clases del objeto COM debe derivarse de TComObjectFactory. idea de por qué. Sin usar una interfaz, por ejemplo, la siguiente implementación:
TComServer = clase(TComServerObject)
Privado
. . . .
procedimiento FactoryFree(Factory: IClassFactory);
procedimiento FactoryRegisterClassObject(Fábrica: IClassFactory);
procedimiento FactoryUpdateRegistry(Fábrica: IClassFactory);
procedimiento LastReleased;
fin;
En última instancia, el problema radica en la implementación del servidor COM y la fábrica de clases proporcionada por Delphi. Ahora no hay nada que pueda hacer. Al menos todavía no he encontrado ninguna buena solución. implementar el dll del servidor COM y mi propia fábrica de clases de control ActiveX (de hecho, hice uno, se siente muy simple, algunos métodos Delph para implementar servidores COM se pueden usar directamente).