程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> DELPHI實現activex控件的限制

DELPHI實現activex控件的限制

編輯:Delphi

個人認為DELPHI實現activex控件的限制存在於Delphi的activex控件的基類派生於TAutoObject如下:TActiveXControl = class(TAutoObject,

IConnectionPointContainer,
IDataObject,
IObjectSafety,
IOleControl,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObject,
IPerPropertyBrowsing,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
IVIEwObject,
IVIEwObject2) .... ....end;

  用DELPHI制作過activex控件的人都知道DELPHI的activex控件向導中必須指明控件包含的VCL窗體控件(從TWinControl派生的VCL控件),這樣就使得它的實現必須包含一個VCL窗體控件,而為了讓這個VCL窗體控件隨時可用Delphi還要為該控件提供一個父窗口。看下面代碼:

procedure TActiveXControl.Initialize;
begin inherited Initialize; FConnectionPoints := TConnectionPoints.Create(Self);
FControlFactory := Factory as TActiveXControlFactory;
if FControlFactory.EventTypeInfo <> nil then FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID, ckSingle, EventConnect);
FPropertySinks := FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink, ckMulti, nil);
FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow);
if csReflector in FControl.ControlStyle then FWinControl := TReflectorWindow.Create(ParkingWindow, FControl)
else FWinControl := FControl; FControlWndProc := FControl.WindowProc;
FControl.WindowProc := WndProc;
InitializeControl;
end;

 這就是DELPHI實現activex控件的限制,我們如何去控制這個ParkingWindow,就算能夠控制整個activex控件的體積以及膨脹了很多了,在internet上的activex控件越小越好,至少現在的Delphi要實現類似vc輕量級控件(只實現IPersistStreamInit,IOleControl,IOleObject,IOleInPlaceActiveObject,IViewObjectEx,IOleInPlaceObjectWindowless這些接口的COM對象)非常困難,更不要說要按需(根據activex控件的使用范圍是IE還是Word或者其他)實現接口了。一種解決方案就是不從TAutoObject派生而是直接從窗體控件派生如下: TMyActiveXControl=class(TMyControl,//TMyControl是一般的類也可以是VCL窗體控件類.//下面的接口並不總是需要派生和實現。可按需派生和實現 IConnectionPointContainer,

IDataObject,
IObjectSafety,
IOleControl,
IOleInPlaceActiveObject,
IOleInPlaceObject,
IOleObject,
IPerPropertyBrowsing,
IPersistPropertyBag,
IPersistStorage,
IPersistStreamInit,
IQuickActivate,
ISimpleFrameSite,
ISpecifyPropertyPages,
IVIEwObject,
IVIEwObject2) .... ....end;

  如果這樣,新的問題又產生了,如何注冊這個activex控件呢?因為沒有合適的類廠對象,Delphi的類廠是如下關系:

TComObjectFactory-->TTypedComObjectFactory-->TAutoObjectFactory -->TActiveXControlFactory-->TActiveFormFactory而TComObjectFactory是這樣實現的,TComObject = class(TObject, IUnknown, ISupportErrorInfo)。。。。End;
TComClass = class of TComObject;
TComObjectFactory = class(TObject, IUnknown, IClassFactory, IClassFactory2
)…..
constructor Create(ComServer: TComServerObject;
ComClass: TComClass;
const ClassID: TGUID;
const ClassName, Description: string;
Instancing: TClassInstancing;
ThreadingModel: TThreadingModel = tmSingle);
End;

類廠的構造函數要求ComClass這個參數,而TComObject是從TObject派生的,因此如我們根本找不到合適的類廠基類來派生,除非有下面的Delphi實現:

TMyComObject = class(TMyControl, IUnknown, ISupportErrorInfo)
。。。。
End;
TMyComClass = class of TMyComObject;
TMyComObjectFactory = class(TObject, IUnknown, IClassFactory, IClassFactory2
)
…..
constructor Create(ComServer: TComServerObject;
MyComClass: TMyComClass;
const ClassID: TGUID;
const ClassName, Description: string;
Instancing: TClassInstancing;
ThreadingModel: TThreadingModel = tmSingle);
End;

  可惜就算有這樣的一個類我們也無法使用,這個限制來自於Delphi對COM類廠的實現如下:

TComServer = class(TComServerObject)Private。。。。 procedure FactoryFree(Factory: TComObjectFactory);
procedure FactoryRegisterClassObject(Factory: TComObjectFactory);
procedure FactoryUpdateRegistry(Factory: TComObjectFactory);
procedure LastReleased;
end;

  問題就出在這幾個函數,這幾個函數要求參數是TComObjectFactory類型,也就是說要使用Delphi提供的COM服務器的實現,那麼COM對象的類廠就必須從TComObjectFactory派生,我沒想通這兒為什麼不使用接口,比如是如下實現:

TComServer = class(TComServerObject)Private
。。。。
procedure FactoryFree(Factory: IClassFactory);
procedure FactoryRegisterClassObject(Factory: IClassFactory);
procedure FactoryUpdateRegistry(Factory: IClassFactory);
procedure LastReleased;
end;

  追根到底問題出在Delphi提供的COM服務器的實現以及類廠的實現上了,這下就沒法了,至少我現在還沒有找到什麼好辦法,現在想到的就只有自己實現COM服務器dll以及自己的activex控件類工廠了(實際上也做了一個,感覺還是很簡單,有些delph實現COM服務器的的方法可以直接使用)。




  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved