Pessoalmente, acho que a limitação da implementação do controle activex do DELPHI existe no fato de que a classe base do controle activex do DELPHI é derivada de TAutoObject da seguinte forma:
TActiveXControl = classe(TAutoObject,
IConnectionPointContainer,
IDataObject,
Segurança de Objetos,
IOleControl,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObject,
iperPRopertyNavegação,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
IViewObject,
IViewObject2)
....
....
fim;
Qualquer pessoa que tenha usado DELPHI para criar controles activex sabe que o assistente de controle activex do DELPHI deve especificar o controle de formulário VCL contido no controle (controle VCL derivado de TWinControl), de modo que sua implementação deve incluir um controle de formulário VCL para fazer este controle de formulário VCL. disponível a qualquer momento, o DELPHI também fornece uma janela pai para o controle. Veja o código abaixo:
procedimento TActiveXControl.Initialize;
começar
herdado Inicializar;
FConnectionPoints := TConnectionPoints.Create(Self);
FControlFactory := Fábrica como TActiveXControlFactory;
se FControlFactory.EventTypeInfo <> nulo então
FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID,
ckSingle, EventConnect);
FPropertySinks := FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink,
ckMulti, nulo);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
se csReflector em FControl.ControlStyle então
FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) senão
FWinControl := FControl;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
InicializarControl;
fim;
Esta é a limitação da implementação do controle activex do DELPHI. Como podemos controlar esta ParkingWindow? Mesmo que possamos controlar o tamanho de todo o controle activex e expandi-lo bastante, quanto menor for o controle activex na Internet, melhor. pelo menos agora o DELPHI deve implementar algo semelhante ao vc light Magnitude control (implementa apenas IPersistStreamInit, As interfaces IOleControl, IOleObject, IOleInPlaceActiveObject, IViewObjectEx, IOleInPlaceObjectWindowless (objetos COM dessas interfaces) são muito difíceis, muito menos implementar a interface conforme necessário (dependendo se o controle activex é usado no IE, Word ou outros). Uma solução não é derivar de TAutoObject mas diretamente do controle de formulário como segue:
TMyActiveXControl=class(TMyControl,
//TMyControl é uma classe geral ou uma classe de controle de formulário VCL.
//As interfaces a seguir nem sempre precisam ser derivadas e implementadas. Pode ser derivado e implementado sob demanda
IConnectionPointContainer,
IDataObject,
Segurança de Objetos,
IOleControl,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObject,
IPerPropertyBrowsing,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
IViewObject,
IViewObject2)
....
....
fim;
Mas se sim, surge um novo problema: como registrar esse controle activex? Como não existe um objeto de fábrica de classe adequado, a fábrica de classe do DELPHI tem o seguinte relacionamento:
-->TActiveXControlFactory-->TActiveFormFactory
E o TComObjectFactory é implementado assim,
TComObject = classe(TObject, IUnknown, ISupportErrorInfo)
. . . .
Fim;
TComClass = classe do TComObject;
TComObjectFactory = classe(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
construtor Create(ComServer: TComServerObject; ComClass: TComClass;
const ClassID: TGUID const ClassName, Descrição: string;
Instanciação: TClassInstancing ThreadingModel: TThreadingModel = tmSingle);
Fim;
O construtor da fábrica de classes requer o parâmetro ComClass e TComObject é derivado de TObject. Portanto, se não conseguirmos encontrar uma classe base de fábrica de classes adequada para derivar, a menos que haja a seguinte implementação delphi:
TMyComObject = classe(TMyControl, IUnknown, ISupportErrorInfo)
. . . .
Fim;
TMyComClass = classe de TMyComObject;
TMyComObjectFactory = classe(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
construtor Create(ComServer: TComServerObject; MyComClass: TMyComClass;
const ClassID: TGUID const ClassName, Descrição: string;
Instanciação: TClassInstancing ThreadingModel: TThreadingModel = tmSingle);
Fim;
Infelizmente, mesmo que exista tal classe, não podemos usá-la. Esta limitação vem da implementação da fábrica de classes COM do DELPHI da seguinte maneira:
TComServer = classe(TComServerObject)
Privado
. . . .
procedimento FactoryFree(Fábrica: TComObjectFactory);
procedimento FactoryRegisterClassObject(Fábrica: TComObjectFactory);
procedimento FactoryUpdateRegistry(Fábrica: TComObjectFactory);
procedimento LastReleased;
fim;
O problema está nessas funções. Essas funções exigem que os parâmetros sejam do tipo TComObjectFactory, o que significa que a implementação do servidor COM fornecida pelo Delphi deve ser usada. Então a classe factory do objeto COM deve ser derivada de TComObjectFactory. ideia do porquê. Sem usar uma interface, por exemplo, a seguinte implementação:
TComServer = classe(TComServerObject)
Privado
. . . .
procedimento FactoryFree(Fábrica: IClassFactory);
procedimento FactoryRegisterClassObject (Fábrica: IClassFactory);
procedimento FactoryUpdateRegistry(Fábrica: IClassFactory);
procedimento LastReleased;
fim;
Em última análise, o problema está na implementação do servidor COM e na fábrica de classes fornecida pelo Delphi. Agora não há nada que eu possa fazer. Pelo menos ainda não encontrei nenhuma boa solução. implementar a dll do servidor COM e minha própria fábrica de classes de controle ActiveX (na verdade eu fiz uma, parece muito simples, alguns métodos Delph para implementar servidores COM podem ser usados diretamente).