一从EXE到OCX工程 此类转化有一个常用的也可以说较笨的的方法把EXE工程主Form上的所有元素和其事件处理程序都拷贝过来此法虽说稳妥但麻烦的一塌糊涂容易让人头大下面着重介绍一个比较快捷省事的办法通过类的继承来实现转化概括来说就是把EXE工程的主Form直接作为OCX工程的主Form并把其父类由TForm改为TActiveForm详细介绍如下 ()准备工作 在开始之前最好把EXE工程的所有文件如pasdfm(工程dpr等除外)拷到一个新的目录下如果不想这样做也可以把OCX工程保存到同一目录但不要和EXE工程重名以免覆盖生成一个ActiveForm(注意此保持空白不要往其上放任何组件)为了便于说明设其name为ActiveFormX单元文件存为ActiveFormXpas同时保存OCX工程假设原来主Form的name为frmMain单元文件为MainFormpas ()改变继承关系 打开MainFormpas找到TfrmMain类的声明部分把TfrmMain = class(TForm)改为TfrmMain = class(TActiveFormX) ()把frmMain作为工程的主Form 打开ActiveFormXpas找到initialization 部分如下所示 initialization TActiveFormFactoryCreate( ComServer TActiveFormControl TActiveFormX Class_ActiveFormX
OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL tmApartment); 把第五行中TActiveFormX改为TfrmMain这样OCX工程的主Form就成了原来EXE工程的主Form即TfrmMain ()属性声明 查看一下delphi源码可以看到下面的继承链条 TCustomForm>TCustomActiveForm>TActiveForm TCustomForm>TForm TForm的部分published属性在TActiveForm未被声明而这些属性存在于它们共同的父类TCustomForm中并且在public部分所以你如果在属性编辑器中改变了frmMain的这些属性delphi就会从当前类按TActiveFormX>TCustomActiveForm>TCustomForm顺序在published部分查找并设置这些属性而这三个父类published部分并未包含这些属性这样delphi将提示地址错误所以只要在TActiveFormX中声明这些属性问题即可解决以On开头的事件属性也是同样的道理打开ActiveFormXpas把以下代码拷到TActiveFormX的声明部分即可 published property Action; property Align; property AlphaBlend default False; property AlphaBlendValue default ; property BiDiMode; property BorderIcons; property BorderStyle; property ClientHeight; property ClientWidth; property TransparentColor default False; property TransparentColorValue default ; property CtlD; 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中有处理程序的声明一下就行了 ()更改事件连接 如果你在TfrmMain的OnPaint事件中写了代码可以发现这些代码是不会被执行的原因何在?打开ActiveFormXpas找到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了 二从OCX到EXE工程 ()OCX工程框架 综上所述OCX工程最好不要把ActiveForm作为主Form而另外生成一个普通Form作为主Form再按上面所说的方法进行处理然后其它的数据操作Form也为普通Form被主Form调用 ()转化到EXE工程 只要你按()做了问题就非常好办生成一个普通工程把OCX工程除ActiveForm以外的所有Form加进工程就行了ok搞定! |