Personnellement, je pense que la limitation de l'implémentation du contrôle activex par DELPHI réside dans le fait que la classe de base du contrôle activex de DELPHI est dérivée de TAutoObject comme suit :
TActiveXControl = classe(TAutoObject,
IConnectionPointContainer,
IDataObject,
IObjectSécurité,
IOleControl,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObject,
iperPRertyBrowsing,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
IViewObject,
IVueObjet2)
....
....
fin;
Quiconque a utilisé DELPHI pour créer des contrôles activex sait que l'assistant de contrôle activex de DELPHI doit spécifier le contrôle de formulaire VCL contenu dans le contrôle (contrôle VCL dérivé de TWinControl), de sorte que son implémentation doit inclure un contrôle de formulaire VCL pour réaliser ce contrôle de formulaire VCL. disponible à tout moment, DELPHI propose également une fenêtre parent du champ. Regardez le code ci-dessous :
procédure TActiveXControl.Initialize ;
commencer
hérité Initialiser;
FConnectionPoints := TConnectionPoints.Create(Self);
FControlFactory := Usine en tant que TActiveXControlFactory ;
si FControlFactory.EventTypeInfo <> nul alors
FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID,
ckSingle, EventConnect);
FPropertySinks := FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink,
ckMulti, nul);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
si csReflector dans FControl.ControlStyle alors
FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) sinon
FWinControl := FControl;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
InitialiserControl ;
fin;
C'est la limite de l'implémentation du contrôle ActiveX par DELPHI. Comment contrôler ce ParkingWindow Même si nous pouvons contrôler la taille de l'ensemble du contrôle ActiveX et qu'il s'est beaucoup étendu, plus le contrôle ActiveX sur Internet est petit, mieux c'est. au moins maintenant, DELPHI doit réaliser quelque chose de similaire au contrôle de Magnitude (implémente uniquement IPersistStreamInit, Les interfaces IOleControl, IOleObject, IOleInPlaceActiveObject, IViewObjectEx, IOleInPlaceObjectWindowless (objets COM) sont très difficiles, sans parler de la mise en œuvre de l'interface à la demande (selon que le contrôle activex est utilisé dans IE, Word ou autres). Une solution n'est pas de dériver de TAutoObject mais directement du contrôle de formulaire comme suit :
TMyActiveXControl=classe(TMyControl,
//TMyControl est une classe générale ou une classe de contrôle de formulaire VCL.
//Les interfaces suivantes n'ont pas toujours besoin d'être dérivées et implémentées. Peut être dérivé et mis en œuvre sur demande
IConnectionPointContainer,
IDataObject,
IObjectSécurité,
IOleControl,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObject,
Navigation IPerProperty,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
IViewObject,
IVueObjet2)
....
....
fin;
Mais si tel est le cas, un nouveau problème se pose. Comment enregistrer ce contrôle activex ? Puisqu’il n’existe pas d’objet de fabrique de classes approprié, la fabrique de classes de DELPHI a la relation suivante :
-->TActiveXControlFactory-->TActiveFormFactory
Et TComObjectFactory est implémenté comme ceci,
TComObject = classe (TObject, IUnknown, ISupportErrorInfo)
. . . .
Fin;
TComClass = classe de TComObject ;
TComObjectFactory = classe (TObject, IUnknown, IClassFactory, IClassFactory2)
…..
constructeur Create(ComServer : TComServerObject ; ComClass : TComClass ;
const ClassID : TGUID ; const ClassName, Description : chaîne ;
Instanciation : TClassInstancing ; ThreadingModel : TThreadingModel = tmSingle );
Fin;
Le constructeur de la fabrique de classes nécessite le paramètre ComClass, et TComObject est dérivé de TObject. Par conséquent, si nous ne trouvons pas de classe de base de fabrique de classes appropriée à partir de laquelle dériver, à moins qu'il n'y ait l'implémentation Delphi suivante :
TMyComObject = classe (TMyControl, IUnknown, ISupportErrorInfo)
. . . .
Fin;
TMyComClass = classe de TMyComObject ;
TMyComObjectFactory = classe (TObject, IUnknown, IClassFactory, IClassFactory2)
…..
constructeur Create(ComServer : TComServerObject ; MyComClass : TMyComClass ;
const ClassID : TGUID ; const ClassName, Description : chaîne ;
Instanciation : TClassInstancing ; ThreadingModel : TThreadingModel = tmSingle );
Fin;
Malheureusement, même si une telle classe existe, nous ne pouvons pas l'utiliser. Cette limitation vient de l'implémentation par DELPHI de la fabrique de classes COM comme suit :
TComServer = classe (TComServerObject)
Privé
. . . .
procédure FactoryFree(Factory : TComObjectFactory);
procédure FactoryRegisterClassObject(Factory: TComObjectFactory);
procédure FactoryUpdateRegistry(Factory: TComObjectFactory);
procédure LastReleased ;
fin;
Le problème réside dans ces fonctions. Ces fonctions nécessitent que les paramètres soient de type TComObjectFactory, ce qui signifie que l'implémentation du serveur COM fourni par Delphi doit être utilisée. Ensuite, la fabrique de classes de l'objet COM doit être dérivée de TComObjectFactory. compris pourquoi, sans utiliser d'interface, par exemple, l'implémentation suivante :
TComServer = classe (TComServerObject)
Privé
. . . .
procédure FactoryFree(Factory: IClassFactory);
procédure FactoryRegisterClassObject (Factory : IClassFactory);
procédure FactoryUpdateRegistry(Factory: IClassFactory);
procédure LastReleased ;
fin;
En fin de compte, le problème réside dans l'implémentation du serveur COM et de la fabrique de classes fournie par Delphi. Maintenant, je ne peux rien faire. Au moins, je n'ai pas encore trouvé de bonne solution. implémentez la DLL du serveur COM et ma propre usine de classes de contrôle ActiveX (j'en ai créé une, cela semble très simple, certaines méthodes Delph pour implémenter des serveurs COM peuvent être utilisées directement).