โดยส่วนตัวแล้ว ฉันคิดว่าข้อจำกัดในการใช้งานการควบคุม activex ของ DELPHI นั้นมีอยู่ในความจริงที่ว่าคลาสพื้นฐานของการควบคุม activex ของ DELPHI นั้นได้มาจาก TAutoObject ดังนี้
TActiveXControl = คลาส (TAutoObject,
IConnectionPointคอนเทนเนอร์,
ไอดาต้าออบเจ็กต์,
IObjectความปลอดภัย
ไอโอเลคอนโทรล,
IOleInPlaceActiveObject,
IOleInPlaceObject,
ไอโอเลอ็อบเจ็กต์,
การเรียกดู iperPROperty,
IPersistPropertyBag,
ไอเปอร์ซิสต์สตอเรจ,
IPersistStreamInit,
IQuickเปิดใช้งาน,
ISimpleFrameSite,
ISpecifyPropertyPages,
ไอวิวออบเจ็กต์,
ไอวิวออบเจ็กต์2)
-
-
จบ;
ใครก็ตามที่เคยใช้ DELPHI เพื่อสร้างตัวควบคุม Activex จะทราบดีว่าวิซาร์ดการควบคุม Activex ของ DELPHI จะต้องระบุตัวควบคุมฟอร์ม VCL ที่มีอยู่ในตัวควบคุม (ตัวควบคุม VCL ที่ได้รับจาก TWinControl) เพื่อให้การใช้งานต้องมีตัวควบคุมฟอร์ม VCL เพื่อสร้างตัวควบคุมฟอร์ม VCL นี้ ซึ่งพร้อมใช้งานได้ตลอดเวลา DELPHI ยังมีหน้าต่างหลักสำหรับการควบคุมอีกด้วย ดูรหัสด้านล่าง:
ขั้นตอน TActiveXControl.Initialize;
เริ่ม
สืบทอดเริ่มต้น;
FConnectionPoints := TConnectionPoints.Create (ตนเอง);
FControlFactory := โรงงานเป็น TActiveXControlFactory;
ถ้า FControlFactory.EventTypeInfo <> ไม่มีเลย
FConnectionPoints.CreateConnectionPoint (FControlFactory.EventIID,
ckSingle, EventConnect);
FPropertySinks := FConnectionPoints.CreateConnectionPoint (IPropertyNotifySink,
ckMulti ไม่มี);
FControl := FControlFactory.WinControlClass.CreateParented (หน้าต่างที่จอดรถ);
ถ้า csReflector ใน FControl.ControlStyle แล้ว
FWinControl := TReflectorWindow.Create (ParkingWindow, FControl) อย่างอื่น
FWinControl := FControl;
FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
เตรียมใช้งานการควบคุม;
จบ;
นี่เป็นข้อจำกัดของการนำ Activex Control ของ DELPHI ไปใช้ เราจะควบคุม ParkingWindow นี้ได้อย่างไร แม้ว่าเราจะสามารถควบคุมขนาดของ Activex Control ทั้งหมดและขยายได้มากเท่าใด ยิ่ง ActiveX Control มีขนาดเล็กลงเท่าใดก็ยิ่งดีเท่านั้น อย่างน้อยตอนนี้ DELPHI จะต้องใช้สิ่งที่คล้ายกับการควบคุมขนาดของแสง vc (ใช้เฉพาะ IPersistStreamInit เท่านั้น อินเทอร์เฟซ IOleControl, IOleObject, IOleInPlaceActiveObject, IViewObjectEx, อินเทอร์เฟซ IOleInPlaceObjectWindowless (ออบเจ็กต์ COM ของอินเทอร์เฟซเหล่านี้) เป็นเรื่องยากมาก ไม่ต้องพูดถึงการนำอินเทอร์เฟซไปใช้ตามความจำเป็น (ขึ้นอยู่กับว่ามีการใช้ตัวควบคุม activex ใน IE, Word หรืออื่น ๆ ) วิธีแก้ปัญหาหนึ่งไม่ได้มาจาก TAutoObject แต่มาจากการควบคุมแบบฟอร์มโดยตรงดังนี้:
TMyActiveXControl=คลาส(TMyControl,
//TMyControl เป็นคลาสทั่วไปหรือคลาสควบคุมฟอร์ม VCL
//อินเทอร์เฟซต่อไปนี้ไม่จำเป็นต้องได้รับและนำไปใช้เสมอไป สามารถรับและดำเนินการได้ตามความต้องการ
IConnectionPointคอนเทนเนอร์,
ไอดาต้าออบเจ็กต์,
IObjectความปลอดภัย
ไอโอเลคอนโทรล,
IOleInPlaceActiveObject,
IOleInPlaceObject,
ไอโอเลอ็อบเจ็กต์,
การท่องเว็บ IPerProperty,
IPersistPropertyBag,
ไอเปอร์ซิสต์สตอเรจ,
IPersistStreamInit,
IQuickเปิดใช้งาน,
ISimpleFrameSite,
ISpecifyPropertyPages,
ไอวิวออบเจ็กต์,
ไอวิวออบเจ็กต์2)
-
-
จบ;
แต่ถ้าเป็นเช่นนั้น จะเกิดปัญหาใหม่เกิดขึ้นได้อย่างไร เนื่องจากไม่มีวัตถุคลาสโรงงานที่เหมาะสม โรงงานคลาสของ DELPHI จึงมีความสัมพันธ์ดังต่อไปนี้:
-> TActiveXControlFactory -> TActiveFormFactory
และ TComObjectFactory ก็ถูกนำไปใช้เช่นนี้
TComObject = คลาส (TObject, IUnknown, ISupportErrorInfo)
- - - -
จบ;
TComClass = คลาสของ TComObject;
TComObjectFactory = คลาส (TObject, IUnknown, IClassFactory, IClassFactory2)
-
ตัวสร้างสร้าง (ComServer: TComServerObject; ComClass: TComClass;
const ClassID: TGUID; const ClassName คำอธิบาย: สตริง;
การสร้างอินสแตนซ์: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
จบ;
ตัวสร้างของคลาสแฟคทอรีต้องการพารามิเตอร์ ComClass และ TComObject ได้มาจาก TObject ดังนั้น หากเราไม่พบคลาสฐานแฟคทอรีที่เหมาะสมที่จะได้รับมา เว้นแต่จะมีการใช้งาน delphi ต่อไปนี้:
TMyComObject = คลาส (TMyControl, IUnknown, ISupportErrorInfo)
- - - -
จบ;
TMyComClass = คลาสของ TMyComObject;
TMyComObjectFactory = คลาส (TObject, IUnknown, IClassFactory, IClassFactory2)
-
ตัวสร้างสร้าง (ComServer: TComServerObject; MyComClass: TMyComClass;
const ClassID: TGUID; const ClassName คำอธิบาย: สตริง;
การสร้างอินสแตนซ์: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
จบ;
น่าเสียดาย แม้ว่าจะมีคลาสดังกล่าว เราก็ไม่สามารถใช้คลาสนี้ได้
TComServer = คลาส (TComServerObject)
ส่วนตัว
- - - -
ขั้นตอน FactoryFree (โรงงาน: TComObjectFactory);
ขั้นตอน FactoryRegisterClassObject (โรงงาน: TComObjectFactory);
ขั้นตอน FactoryUpdateRegistry (โรงงาน: TComObjectFactory);
ขั้นตอน LastReleased;
จบ;
ปัญหาอยู่ในฟังก์ชันเหล่านี้ ฟังก์ชันเหล่านี้จำเป็นต้องมีพารามิเตอร์ประเภท TComObjectFactory ซึ่งหมายความว่าต้องใช้เซิร์ฟเวอร์ COM ที่จัดทำโดย Delphi จากนั้นโรงงานคลาสของวัตถุ COM จะต้องได้รับมาจาก TComObjectFactory แนวคิดว่าทำไม โดยไม่ต้องใช้อินเทอร์เฟซ เช่น การใช้งานต่อไปนี้:
TComServer = คลาส (TComServerObject)
ส่วนตัว
- - - -
ขั้นตอน FactoryFree (โรงงาน: IClassFactory);
ขั้นตอน FactoryRegisterClassObject (โรงงาน: IClassFactory);
ขั้นตอน FactoryUpdateRegistry (โรงงาน: IClassFactory);
ขั้นตอน LastReleased;
จบ;
ท้ายที่สุดแล้ว ปัญหาอยู่ที่การใช้งานเซิร์ฟเวอร์ COM และคลาสแฟคทอรีที่ Delphi จัดหาให้ ตอนนี้ฉันยังทำอะไรไม่ได้เลย อย่างน้อยฉันก็ยังไม่พบวิธีแก้ปัญหาที่ดีในตอนนี้ ใช้ COM เซิร์ฟเวอร์ dll และโรงงานคลาสควบคุม ActiveX ของฉันเอง (จริง ๆ แล้วฉันสร้างมันขึ้นมา มันรู้สึกง่ายมาก วิธี Delph บางอย่างสำหรับการนำเซิร์ฟเวอร์ COM ไปใช้โดยตรงสามารถใช้ได้โดยตรง)