EXE工程和OCX工程的轉(zhuǎn)化

字號(hào):

1 從EXE到OCX工程此類轉(zhuǎn)化有一個(gè)常用的也可以說較笨的的方法,把EXE工程主Form上的所有元素和其事件處理程序都拷貝過來。此法雖說穩(wěn)妥,但麻煩的一塌糊涂。容易讓人頭大。下面著重介紹一個(gè)比較快捷省事的辦法,通過類的繼承來實(shí)現(xiàn)轉(zhuǎn)化。概括來說,就是把EXE工程的主Form直接作為OCX工程的主Form,并把其父類由TForm改為ActiveForm。詳細(xì)介紹如下。
    (1)準(zhǔn)備工作
    在開始之前,把EXE工程的所有文件如.pas、.dfm(工程.dpr等除外)拷到一個(gè)新的目錄下。如果不想這樣做,也可以把OCX工程保存到同一目錄,但不要和EXE工程重名,以免覆蓋。生成一個(gè)ActiveForm(注意:此保持空白,不要往其上放任何組件),為了便于說明,設(shè)其name為ActiveFormX,單元文件存為ActiveFormX.pas,同時(shí)保存OCX工程。假設(shè)原來主Form的name為frmMain,單元文件為MainForm.pas.
    (2)改變繼承關(guān)系
    打開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->TFormTForm的部分published屬性在TActiveForm未被聲明,而這些屬性存在于它們共同的父類TCustomForm中,并且在public部分。所以,你如果在屬性編輯器中改變了frmMain的這些屬性,delphi就會(huì)從當(dāng)前類按TActiveFormX->TCustomActiveForm->TCustomForm順序在published部分查找并設(shè)置這些屬性,而這三個(gè)父類published部分并未包含這些屬性。這樣,delphi將提示地址錯(cuò)誤。所以,只要在TActiveFormX中聲明這些屬性,問題即可解決。以O(shè)n開頭的事件屬性也是同樣的道理。打開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;對(duì)于上面所列的事件屬性,也不必全部都聲明。frmMain中有處理程序的聲明一下就行了。
    (5)更改事件連接
    如果你在TfrmMain的OnPaint事件中寫了代碼,可以發(fā)現(xiàn),這些代碼是不會(huì)被執(zhí)行的。原因何在?
    打開ActiveFormX.pas,找到TActiveFormX的Initialize過程,可以發(fā)現(xiàn)如下代碼:
    inherited Initialize; OnActivate := ActivateEvent;
    OnClick := ClickEvent;
    OnCreate := CreateEvent;
    OnDblClick := DblClickEvent;
    OnDeactivate := DeactivateEvent;
    OnDestroy := DestroyEvent;
    OnKeyPress := KeyPressEvent;
    OnPaint := PaintEvent;原來問題出在這里,OnPaint事件被delphi吃掉了,改成了執(zhí)行PaintEvent。怎么搞?
    把次行注釋掉吧,然后再寫一個(gè)你自己的OnPaint事件處理過程,不要忘了帶參數(shù)sender。
    如:procedure MyPaint(Sender:TObject);然后在TfrmMain的OnCreat事件中賦給OnPaint就行了。
    如:OnPaint:=MyPaint;
    上面列舉的幾個(gè)事件都和OnPaint類似。模仿OnPaint就ok了。
    2 從OCX到EXE工程
    (1)OCX工程框架
    綜上所述,OCX工程不要把ActiveForm作為主Form,而另外生成一個(gè)普通Form作為主Form,再按上面所說的方法進(jìn)行處理。然后其它的數(shù)據(jù)操作Form也為普通Form,被主Form調(diào)用。
    (2)轉(zhuǎn)化到EXE工程
    只要你按(1)做了,問題就非常好辦。生成一個(gè)普通工程,把OCX工程除ActiveForm以外的所有Form加進(jìn)工程就行了。ok,搞定