EXE工程和OCX工程的转化(2002/5/30 三金 版权所有) 1 从EXE到OCX工程 此类转化有一个常用的也可以说较笨的的方法,把EXE工程主Form上的所有 元素和其事件处理程序都拷贝过来。此法虽说稳妥,但麻烦的一塌糊涂。容易让 人头大。下面着重介绍一个比较快捷省事的办法,通过类的继承来实现转化。概 括来说,就是把EXE工程的主Form直接作为OCX工程的主Form,并把其父类由TForm 改为TActiveForm。详细介绍如下。 (1)准备工作 在开始之前,最好把EXE工程的所有文件如.pas、.dfm(工程.dpr等除外)拷到 一个新的目录下。如果不想这样做,也可以把OCX工程保存到同一目录,但不要和 EXE工程重名,以免覆盖。生成一个ActiveForm(注意:此保持空白,不要往其上 放任何组件),为了便于说明,设其name为ActiveFormX,单元文件存为 ActiveFormX.pas,同时保存OCX工程。假设原来主Form的name为frmMain,单元文件 为MainForm.pas. (2)改变继承关系 打开MainForm.pas,找到TfrmMain类的声明部分:把TfrmMain = class(TForm) 改为TfrmMain = class(TActiveFormX) (3)把frmMain作为工程的主Form 打开ActiveFormX.pas,找到initialization 部分,如下所示: initialization TActiveFormFactory.Create( ComServer, TActiveFormControl, TActiveFormX, Class_ActiveFormX, 1, '', OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL, tmApartment); 把第五行中TActiveFormX改为TfrmMain,这样OCX工程的主Form就成了原来EXE工程的 主Form,即TfrmMain。 (4)属性声明 查看一下delphi源码,可以看到下面的继承链条: TCustomForm->TCustomActiveForm->TActiveForm TCustomForm->TForm TForm的部分published属性在TActiveForm未被声明,而这些属性存在于它们共同的父 类TCustomForm中,并且在public部分。所以,你如果在属性编辑器中改变了frmMain的 这些属性,delphi就会从当前类按TActiveFormX->TCustomActiveForm->TCustomForm顺 序在published部分查找并设置这些属性,而这三个父类published部分并未包含这些属 性。这样,delphi将提示地址错误。所以,只要在TActiveFormX中声明这些属性,问题 即可解决。以On开头的事件属性也是同样的道理。打开ActiveFormX.pas,把以下代码拷 到TActiveFormX的声明部分即可。 published property Action; property Align; property AlphaBlend default False; property AlphaBlendValue default 255; property BiDiMode; property BorderIcons; property BorderStyle; property ClientHeight; property ClientWidth; property TransparentColor default False; property TransparentColorValue default 0; property Ctl3D; property UseDockManager; property DefaultMonitor; property DockSite; property DragKind; property DragMode; property Enabled; property ParentFont default False; property FormStyle; property HelpFile; property Icon; property Menu; property ObjectMenuItem; property ParentBiDiMode; property Position; property Visible; property WindowState; property WindowMenu; property OnCanResize; property OnClose; property OnCloseQuery; property OnConstrainedResize; property OnDockDrop; property OnDockOver; property OnEndDock; property OnGetSiteInfo; property OnHide; property OnHelp; property OnMouseWheel; property OnMouseWheelDown; property OnMouseWheelUp; property OnResize; property OnShortCut; property OnShow; property OnStartDock; property OnUnDock; 对于上面所列的事件属性,也不必全部都声明。frmMain中有处理程序的声明一下就 行了。 (5)更改事件连接 如果你在TfrmMain的OnPaint事件中写了代码,可以发现,这些代码是不会被执行 的。原因何在?打开ActiveFormX.pas,找到TActiveFormX的Initialize过程,可以发 现如下代码: inherited Initialize; OnActivate := ActivateEvent; OnClick := ClickEvent; OnCreate := CreateEvent; OnDblClick := DblClickEvent; OnDeactivate := DeactivateEvent; OnDestroy := DestroyEvent; OnKeyPress := KeyPressEvent; OnPaint := PaintEvent; 原来问题出在这里,OnPaint事件被delphi吃掉了,改成了执行PaintEvent。怎么搞? 把次行注释掉吧,然后再写一个你自己的OnPaint事件处理过程,不要忘了带参数sender。 如:procedure MyPaint(Sender:TObject); 然后在TfrmMain的OnCreat事件中赋给OnPaint就行了。如:OnPaint:=MyPaint; 上面列举的几个事件都和OnPaint类似。模仿OnPaint就ok了。 2 从OCX到EXE工程 (1)OCX工程框架 综上所述,OCX工程最好不要把ActiveForm作为主Form,而另外生成一个普通Form 作为主Form,再按上面所说的方法进行处理。然后其它的数据操作Form也为普通Form, 被主Form调用。 (2)转化到EXE工程 只要你按(1)做了,问题就非常好办。生成一个普通工程,把OCX工程除ActiveForm 以外的所有Form加进工程就行了。 ok,搞定!
更好更多文章尽在三金主页-天铭心草堂 http://vip.6to23.com/tianmingxin
本文地址:http://com.8s8s.com/it/it5592.htm