Secara pribadi, menurut saya keterbatasan implementasi kontrol activex DELPHI ada pada kenyataan bahwa kelas dasar kontrol activex DELPHI berasal dari TAutoObject sebagai berikut:
TActiveXControl = kelas(TAutoObject,
IConnectionPointContainer,
IDataObjek,
Keamanan Objek I,
Kontrol IOle,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObjek,
iperPROpertyPenjelajahan,
Tas Properti IPersist,
Penyimpanan IPersist,
IPersistStreamInit,
SayaAktifkan Cepat,
Situs ISimpleFrame,
ISpecifyPropertyPages,
IViewObject,
IViewObject2)
....
....
akhir;
Siapa pun yang telah menggunakan DELPHI untuk membuat kontrol activex mengetahui bahwa wizard kontrol activex DELPHI harus menentukan kontrol formulir VCL yang terdapat dalam kontrol (kontrol VCL berasal dari TWinControl), sehingga implementasinya harus menyertakan kontrol formulir VCL tersedia kapan saja, DELPHI juga menyediakan jendela induk untuk kontrol. Lihatlah kode di bawah ini:
prosedur TActiveXControl.Inisialisasi;
mulai
Inisialisasi yang diwariskan;
FConnectionPoints := TConnectionPoints.Create(Self);
FControlFactory := Pabrik sebagai TActiveXControlFactory;
jika FControlFactory.EventTypeInfo <> nihil maka
FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID,
ckSingle, EventConnect);
FPropertySinks := FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink,
ckMulti, nihil);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
jika csReflector di FControl.ControlStyle lalu
FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) lain
Kontrol FWin := Kontrol F;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
Inisialisasi Kontrol;
akhir;
Ini adalah keterbatasan implementasi kontrol activex DELPHI. Bagaimana kita mengontrol ParkingWindow ini? Bahkan jika kita dapat mengontrol ukuran seluruh kontrol activex dan memperluasnya, semakin kecil kontrol activex di Internet, semakin baik setidaknya sekarang DELPHI harus mengimplementasikan sesuatu yang mirip dengan kontrol Magnitude vc light (hanya mengimplementasikan IPersistStreamInit, Antarmuka IOleControl, IOleObject, IOleInPlaceActiveObject, IViewObjectEx, IOleInPlaceObjectWindowless (objek COM dari antarmuka ini) sangat sulit, apalagi mengimplementasikan antarmuka sesuai kebutuhan (tergantung apakah kontrol activex digunakan di IE, Word, atau lainnya). Salah satu solusinya adalah tidak mengambil dari TAutoObject tetapi langsung dari kontrol form sebagai berikut:
TMyActiveXControl=kelas(TMyControl,
//TMyControl adalah kelas umum atau kelas kontrol formulir VCL.
//Antarmuka berikut tidak selalu perlu diturunkan dan diimplementasikan. Dapat diturunkan dan diimplementasikan sesuai permintaan
IConnectionPointContainer,
IDataObjek,
Keamanan Objek I,
Kontrol IOle,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObjek,
Penjelajahan IPerProperty,
Tas Properti IPersist,
Penyimpanan IPersist,
IPersistStreamInit,
SayaAktifkan Cepat,
Situs ISimpleFrame,
ISpecifyPropertyPages,
IViewObject,
IViewObject2)
....
....
akhir;
Namun jika iya, muncul masalah baru. Bagaimana cara mendaftarkan kontrol activex ini? Karena tidak ada objek pabrik kelas yang sesuai, pabrik kelas DELPHI memiliki hubungan berikut:
-->TActiveXControlFactory-->TActiveFormFactory
Dan TComObjectFactory diimplementasikan seperti ini,
TComObject = kelas(TObject, IUnknown, ISupportErrorInfo)
. . . .
Akhir;
TComClass = kelas TComObject;
TComObjectFactory = kelas(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
konstruktor Buat(ComServer: TComServerObject; ComClass: TComClass;
const ClassID: TGUID; const ClassName, Deskripsi: string;
Instancing: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
Akhir;
Konstruktor pabrik kelas memerlukan parameter ComClass, dan TComObject diturunkan dari TObject. Oleh karena itu, jika kita tidak dapat menemukan kelas dasar pabrik yang cocok untuk diturunkan, kecuali ada implementasi delphi berikut:
TMyComObject = kelas(TMyControl, IUnknown, ISupportErrorInfo)
. . . .
Akhir;
TMyComClass = kelas TMyComObject;
TMyComObjectFactory = kelas(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
konstruktor Buat(ComServer: TComServerObject; MyComClass: TMyComClass;
const ClassID: TGUID; const ClassName, Deskripsi: string;
Instancing: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
Akhir;
Sayangnya, meskipun ada kelas seperti itu, kami tidak dapat menggunakannya. Keterbatasan ini berasal dari implementasi pabrik kelas COM DELPHI sebagai berikut:
TComServer = kelas(TComServerObject)
Pribadi
. . . .
prosedur FactoryFree (Pabrik: TComObjectFactory);
prosedur FactoryRegisterClassObject(Pabrik: TComObjectFactory);
prosedur FactoryUpdateRegistry(Pabrik: TComObjectFactory);
prosedur Terakhir Dirilis;
akhir;
Masalahnya terletak pada fungsi-fungsi ini. Fungsi-fungsi ini memerlukan parameter bertipe TComObjectFactory, yang berarti implementasi server COM yang disediakan oleh Delphi harus digunakan. Maka kelas pabrik dari objek COM harus diturunkan dari TComObjectFactory tahu alasannya. Tanpa menggunakan antarmuka, misalnya implementasi berikut:
TComServer = kelas(TComServerObject)
Pribadi
. . . .
prosedur PabrikGratis(Pabrik: IClassFactory);
prosedur FactoryRegisterClassObject(Pabrik: IClassFactory);
prosedur FactoryUpdateRegistry(Pabrik: IClassFactory);
prosedur Terakhir Dirilis;
akhir;
Pada akhirnya, masalahnya terletak pada implementasi server COM dan pabrik kelas yang disediakan oleh Delphi. Sekarang tidak ada yang bisa saya lakukan. Setidaknya saya belum menemukan solusi yang baik mengimplementasikan COM server dll dan pabrik kelas kontrol ActiveX saya sendiri (sebenarnya saya membuatnya, rasanya sangat sederhana, beberapa metode Delph untuk mengimplementasikan COM server dapat digunakan secara langsung).