شخصيًا، أعتقد أن القيود المفروضة على تنفيذ DELPHI لعنصر تحكم activex موجودة في حقيقة أن الفئة الأساسية لعنصر تحكم activex الخاص بـ DELPHI مشتقة من TAutoObject على النحو التالي:
TActiveXControl = فئة (TAutoObject،
إي كونيكشن بوينت كونتينر,
كائن معرفاتا,
آي أوبجيكت سيفتي،
إيول كنترول,
إيولينبلايسأكتيفوبجيكت،
IoleInPlaceObject,
كائن إيولي,
إيبيربروبيرتيBrowsing,
إيبيرسيست بروبرتي باج,
إيبيرسيستستوراج,
إيبيرسيست ستريمينيت،
إي كويك أكتيفيتي،
موقع إيسيمبل فريم,
إيسبيسيفيبروبرتيباجيس،
إيفيووبجيكت،
إيفيووبجيكت2)
....
....
نهاية؛
يعرف أي شخص استخدم 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(IPropertyNotifySink,
ckMulti، nil);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
إذا كان csReflector في FControl.ControlStyle ثم
FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) آخر
FWinControl := FControl;
FCControlWndProc := FControl.WindowProc;
FCControl.WindowProc := WndProc;
this.InitializeControl;
نهاية؛
هذا هو الحد من تطبيق DELPHI للتحكم في activex. كيف يمكننا التحكم في ParkingWindow هذا؟ على الأقل تحتاج DELPHI الآن إلى تحقيق شيء مشابه للتحكم في حجم الضوء (يتم تنفيذ IPersistStreamInit فقط. تعتبر واجهات IOleControl وIOleObject وIOleInPlaceActiveObject وIViewObjectEx وIOleInPlaceObjectWindowless (كائنات COM) صعبة للغاية، ناهيك عن تنفيذ الواجهة عند الطلب (اعتمادًا على ما إذا كان عنصر تحكم activex مستخدمًا في IE أو Word أو غيرها). أحد الحلول ليس الاشتقاق من TAutoObject ولكن مباشرة من عنصر تحكم النموذج كما يلي:
TMyActiveXControl=class(TMyControl,
//TMyControl هي فئة عامة أو فئة تحكم في نموذج VCL.
// لا يلزم دائمًا اشتقاق الواجهات التالية وتنفيذها. يمكن استخلاصها وتنفيذها حسب الطلب
إي كونيكشن بوينت كونتينر,
كائن معرفاتا,
آي أوبجيكت سيفتي،
إيول كنترول,
إيولينبلايسأكتيفوبجيكت،
IoleInPlaceObject,
كائن إيولي,
إيبيربروبرتيبرويزينج,
إيبيرسيست بروبرتي باج,
إيبيرسيستستوراج,
إيبيرسيست ستريمينيت،
إي كويك أكتيفيتي،
موقع إيسيمبل فريم,
إيسبيسيفيبروبرتيباجيس،
إيفيووبجيكت،
إيفيووبجيكت2)
....
....
نهاية؛
ولكن إذا كان الأمر كذلك، تنشأ مشكلة جديدة كيفية تسجيل عنصر التحكم activex هذا؟ نظرًا لعدم وجود كائن مصنع فئة مناسب، فإن مصنع فئة DELPHI لديه العلاقة التالية:
-->TActiveXControlFactory-->TActiveFormFactory
ويتم تنفيذ TComObjectFactory بهذه الطريقة،
TComObject = فئة (TObject، IUnknown، ISupportErrorInfo)
. . . .
نهاية؛
TComClass = فئة TComObject؛
TComObjectFactory = فئة (TObject، IUnknown، IClassFactory، IClassFactory2)
…..
إنشاء المنشئ (ComServer: TComServerObject؛ ComClass: TComClass؛
const ClassID: TGUID؛ const ClassName، الوصف: سلسلة؛
Instancing: TClassInstancingModel: TThreadingModel = tmSingle);
نهاية؛
يتطلب مُنشئ مصنع الفئة المعلمة ComClass، ويتم اشتقاق TComObject من TObject، لذلك، إذا لم نتمكن من العثور على فئة أساسية مناسبة لمصنع الفئة للاشتقاق منها، ما لم يكن هناك تطبيق دلفي التالي:
TMyComObject = فئة (TMyControl، IUnknown، ISupportErrorInfo)
. . . .
نهاية؛
TMyComClass = فئة TMyComObject؛
TMyComObjectFactory = class(TObject, IUnknown, IClassFactory, IClassFactory2)
…..
إنشاء المنشئ (ComServer: TComServerObject؛ MyComClass: TMyComClass؛
const ClassID: TGUID؛ const ClassName، الوصف: سلسلة؛
Instancing: TClassInstancingModel: TThreadingModel = tmSingle);
نهاية؛
لسوء الحظ، حتى لو كان هناك مثل هذه الفئة، لا يمكننا استخدامها. يأتي هذا القيد من تطبيق DELPHI لمصنع فئة COM على النحو التالي:
TComServer = فئة (TComServerObject)
خاص
. . . .
الإجراء FactoryFree(Factory: TComObjectFactory);
الإجراء FactoryRegisterClassObject(Factory: TComObjectFactory);
الإجراء FactoryUpdateRegistry(Factory: TComObjectFactory);
الإجراء الأخير؛
نهاية؛
تكمن المشكلة في هذه الوظائف. تتطلب هذه الوظائف أن تكون المعلمات من النوع TComObjectFactory، مما يعني أنه يجب استخدام تطبيق خادم COM الذي توفره دلفي، ثم يجب أن يتم اشتقاق مصنع الفئة لكائن COM من TComObjectFactory أحسب لماذا دون استخدام واجهة، على سبيل المثال، التنفيذ التالي:
TComServer = فئة (TComServerObject)
خاص
. . . .
الإجراء FactoryFree(Factory: IClassFactory);
الإجراء FactoryRegisterClassObject(Factory: IClassFactory);
إجراء FactoryUpdateRegistry(Factory: IClassFactory);
الإجراء الأخير؛
نهاية؛
في النهاية، تكمن المشكلة في تنفيذ خادم COM ومصنع الفئات الذي توفره دلفي. والآن لا يمكنني فعل أي شيء. على الأقل لم أجد أي حل جيد حتى الآن تنفيذ ملف dll لخادم COM ومصنع فئة التحكم ActiveX الخاص بي (لقد قمت بالفعل بإنشاء واحد، يبدو الأمر بسيطًا للغاية، يمكن استخدام بعض أساليب Delph لتنفيذ خوادم COM مباشرة).