网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Delphi
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.利用热键控制鼠标移动的一个程序.
.启动外部程序并等待它结束.
.解决了datatree的‘死节点’问题.
.DELPHI8操作符重载的例子.
.Delphi的组件读写机制(三).
.动态创建ClientDataSet的表定义.
.安装程序打包interbase的方法.
.利用Hook技术实现键盘监控.
.优化delphi5.0秘籍大曝光.
.由图像的灰度化看基本图像处理(1).
.在Delphi中开发使用多显示器的应.
.用DELPHI开发AUTHORWARE的u32.
.组件制作之五(托盘组件).
.技术人员的市场意识与市场人员的.
.拖拉打开文件.
.用DELPHI给OICQ动手术(二).
.Delphi图象截取编程示例(7).
.Delphi语言优化.
.delphi的属性property和消息处理.
.关于动态代理.

DELPHI实现activex控件的限制

发表日期:2006-2-4


  个人认为DELPHI实现activex控件的限制存在于DELPHIactivex控件的基类派生于TAutoObject如下:

TActiveXControl = class(TAutoObject,
    IConnectionPointContainer,
    IDataObject,
    IObjectSafety,
    IOleControl,
    IOleInPlaceActiveObject,
    IOleInPlaceObject,
    IOleObject,
    IPerPropertyBrowsing,
    IPersistPropertyBag,
    IPersistStorage,
    IPersistStreamInit,
    IQuickActivate,
    ISimpleFrameSite,
    ISpecifyPropertyPages,
    IViewObject,
    IViewObject2)

  ....

  ....

end;

 

DELPHI制作过activex控件的人都知道DELPHIactivex控件向导中必须指明控件包含的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轻量级控件(只实现IPersistStreamInitIOleControlIOleObjectIOleInPlaceActiveObjectIViewObjectExIOleInPlaceObjectWindowless这些接口的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;

可惜就算有这样的一个类我们也无法使用,这个限制来自于DELPHICOM类厂的实现如下:

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服务器的的方法可以直接使用)。
上一篇:VCL源码分析方法论 人气:3788
下一篇:Delphi中的线程类--之(2) 人气:4124
浏览全部Delphi的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐