程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 組件制作之二(一個簡單組件的制作過程)

組件制作之二(一個簡單組件的制作過程)

編輯:Delphi
接下來要動手來做一個組件了,我想了一個計數器組件,功能方面是比較簡單的,但這不是本章的重點,這一章的重點是說明一個組件的制作全過程。在其中可以學到很多組件制作的技巧,當然這些也是我從書上學得的。好了,開始制作吧:
  
   
  
  這是一個可以計數的組件,為了簡單,我以秒為單位,當開始時,他就從0開始增加,並顯示出來,到3600時,它又回到0,如此循環。當然它也可以停止,暫停,繼續。另外,他還有一個時間事件,即可以設定每隔多少時間來觸發這個事件,這倒是一個好的功能,我們可以設半個小時觸發事件,在事件處理函數中來一個聲音,然後睡個覺,半個小時後,就由這個聲音來提醒你起床了。
  
   
  
  我們一開始不要新建組件單元,而是把它當成一個工程中的一個類來應用,這樣更易於調試,於是我們新建一個工程,又新建一個空白單元用於放置這個類
  
   
  
  一,確定父類:
  
   
  
  接下來給這個類起名叫TTimeCount,那麼它的父類應該是什麼呢,它要能顯示出來,得有一個容量來讓他顯示,TPanel是個不錯的選擇,我看了一下源碼,發覺TPanel什麼也沒有做,只是把它的父類TCustomPanel的屬性顯化出來(這個等一下講),TCustomPanel把好多的屬性聲明為Protected,為他的子類提供了選擇,他的子類如果要使這些屬性能在對象察看器中看到,可以在Published重新聲明一下,如果不想,則不用去理會他。而我們的計數器組件正好不用那麼多屬性,正好合適。於是我決定用TCusomPanel為父類
  
  類建立如下:
  
  TTimeCount=class(TCustomPanel)
  
    private
  
    protected
  
    public
  
    published
  
  end;
  
   
  
  二,確定成員,方法和屬性和事件
  
   
  
  FCount; 只讀私有成員,保存計數值
  
  FActive:Boolean; /確定是否發生類的時間間隔事件
  
  FInterval:TInterval; 這個可以設置時間事件觸發間隔,本來用整型值會好一些,但會了學習起見,這裡用了一個枚舉形的,在Type中聲明如下:
  
  TInterval=(TenM,TwentyM,ThirtyM,FortyM,FiftyM,SixtyM);
  
  分別表示十分鐘到六十分鐘。
  
  TimeLen,TimeNum:integer;這兩個用在類的時間事件發生的確定上,與外界隔絕。
  
  FTimeOut:TNotifyEvent;時間間隔事件的方法指針,通過調度方法實現他與外部的處理函數關聯。
  
   
  
  我們要它能以秒為單位來計數,則要涉及到時間的應用,所以就有了這個最重要的成員:
  
  FTimer:TTimer;
  
  這個成員對象要在類構造函數中實例化它,並賦與他的屬性值,還要在析構函數在釋放它。
  
  如下: 
  
   //構造函數,繼承父類的構造函數,並初始化類中的成員。
  
  constructor TTimeCount.Create(AOwner:TComponent);
  
  //創建時間控件並設置相關的參數
  
    procedure CreateTimer;
  
    begin
  
        FTimer:=TTimer.Create(self);
  
        FTimer.Enabled:=False;
  
        FTimer.Interval:=1000;
  
        FTimer.OnTimer:=FTimerTimer;
  
    end;
  
  begin
  
    inherited Create(AOwner);
  
    CreateTimer;
  
  end;
  
  //析構函數,先釋放時間控件,再繼承父類的析構函數
  
  destructor TTimeCount.Destroy;
  
  begin
  
    FTimer.Free;
  
    inherited Destroy;
  
  end;
  
  構造函數中還要設置該組件的外觀和默認值,這裡把它刪去,到源代碼再貼出來。
  
  其中
  
  FTimerTimer;是很重要的函數,在該類中有聲明:
  
  procedure FTimerTimer(Sender:Tobject);//時間控件的事件處理函數
  
  在這個處理函數中,實現了計數值的遞增並顯示到容器中,此外,還在判斷類的時間事件是否有足夠條件觸發了,如果有則調用DoTimeOut;過程,這個就是事件的調度函數啦:
  
  //事件調度函數,將外部的事件處理函數和該類的事件方法指針聯系起來
  
  procedure TTimeCount.DoTimeOut;
  
  begin
  
    if Assigned(FTimeOut) then
  
       FTimeOut(Self);
  
  end;
  
   
  
  而屬性則是根據私有成員來設定了:
  
  public
  
  property Count:Integer read FCount default 0; //計數值的只讀屬性,這個屬性不能聲明在Published中,因為它是只讀的,只在程序運行時通過它來得到計數值。
  
  published
  
      property Interval:TInterval read FInterval write SetInterval Default TenM;
  
      property Active:boolean read FActive write SetActive default false;
  
      property OnTimeOut:TNotifyEvent read FTimeOut write FTimeOut;
  
   
  
  此外還有幾個自定義方法即
  
  procedure pause; //暫停計數
  
  procedure Resume;//從暫停的計數開始計數。
  
  procedure stop;//停止
  
  procedure start;//開始計數
  
  都比較簡單。
  
   
  
  三,父類屬性的顯化:
  
   
  
  TCustomPanel及其父類有好多的屬性設為Protected,使其子類可以有更靈活的選擇,是否把這些屬性顯示到對象察看器中,如果想,則到Published中重新聲明這些屬性就可以,我參考了一下TPanel的源碼,並按需要選擇了其中的一些屬性聲明到Published中,注意哦,事件也是屬性,只要你把它顯化出來,就可以設置處理事件了。
  
   
  
  四.以下是計數組件的源碼,相信有了上面的講解,應該不會很難了:
  
   
  
  unit CountUnit;
  
   
  
  interface
  
   
  
  uses
  
    SysUtils,Classes,Graphics,Controls,ExtCtrls;
  
   
  
  type
  
  //用於設置時間事件發生的間隔
  
    TInterval=(TenM,TwentyM,ThirtyM,FortyM,FiftyM,SixtyM);
  
   
  
    TTimeCount=class(TCustomPanel)
  
    private
  
      FTimer:TTimer;
  
      FCount:integer;  //只讀私有成員,計數值
  
      FInterval:TInterval; //時間事件發生的間隔
  
      FActive:Boolean; //決定是否發生間隔事件
  
      TimeLen:Integer;//發生事件的時間長度,以秒為單位。
  
      TimeNum:integer;//計數值,和TimeLen一起有用,以判斷是否事件該發生了
  
      FTimeOut:TNotifyEvent;//事件的方法指針
  
      procedure SetInterval(I:TInterval);
  
      procedure SetActive(A:boolean);
  
      procedure FTimerTimer(Sender:Tobject);//時間控件的事件處理函數
  
    protected
  
      procedure DoTimeOut;dynamic; //調度方法,用於關聯事件。
  
    public
  
      procedure pause; //暫停計數
  
      procedure Resume;//從暫停的計數開始計數。
  
      procedure stop;//停止
  
      procedure start;//開始計數
  
      constructor Create(AOwner:TComponent);override;
  
      destructor  Destroy;override;
  
      property Count:Integer read FCount; //計數值的只讀屬性
  
    published
  
      property Interval:TInterval read FInterval write SetInterval Default TenM;
  
      property Active:boolean read FActive write SetActive default false;
  
      property OnTimeOut:TNotifyEvent read FTimeOut write FTimeOut;
  
      //顯式祖先類的一些屬性在對象察看器中
  
      property BevelInner;
  
      property BevelOuter;
  
      property BevelWidth;
  
      property Color;
  
      property Font;
  
      property PopupMenu;
  
      property ShowHint;
  
      property TabOrder;
  
      property TabStop;
  
      property Visible;
  
      property OnClick;
  
      property OnDblClick;
  
      property OnMouseDown;
  
      property OnMouseMove;
  
      property OnMouseUp;
  
    end;
  
   
  
  implementation
  
  //構造函數,繼承父類的構造函數,並初始化類中的成員。
  
  constructor TTimeCount.Create(AOwner:TComponent);
  
  //創建時間控件並設置相關的參數
  
    procedure CreateTimer;
  
    begin
  
        FTimer:=TTimer.Create(self);
  
        FTimer.Enabled:=False;
  
        FTimer.Interval:=1000;
  
        FTimer.OnTimer:=FTimerTimer;
  
    end;
  
  //以下是設置外觀的
  
    procedure setVIEw;
  
    begin
  
      Width:=100;
  
      Height:=50;
  
      Color:=$000000;
  
      Font.Color:=$FFFFFF;
  
      Font.Size:=14;
  
      Font.Style:=[fsBold,fsUnderline];;
  
      BevelOuter := bvLowered      ;
  
      Caption:='0';
  
    end;
  
  begin
  
    inherited Create(AOwner);
  
    FCount:=0;
  
    FInterval:=TenM;
  
    FActive:=False;
  
    TimeLen:=600;//十分鐘,六百秒
  
    TimeNum:=0;
  
    CreateTimer;
  
    setVIEw;
  
  end;
  
  //析構函數,先釋放時間控件,再繼承父類的析構函數
  
  destructor TTimeCount.Destroy;
  
  begin
  
    FTimer.Free;
  
    inherited Destroy;
  
  end;
  
  //設置時間事件發生間隔,財時要賦相應的間隔秒數
  
  procedure TTimeCount.SetInterval(I:TInterval);
  
  begin
  
    if FInterval<>I then
  
    begin
  
      FInterval:=I;
  
      case FInterval of
  
      TenM: TimeLen:=600;
  
      TwentyM:TimeLen:=1200;
  
      ThirtyM: TimeLen:=1800;
  
      FortyM: TimeLen:=2400;
  
      FiftyM:TimeLen:=3000;
  
      SixtyM:TimeLen:=3600;
  
      end;
  
    end;
  
  end;
  
   
  
  procedure TTimeCount.SetActive(A:boolean);
  
  begin
  
    if FActive<>A then
  
    begin
  
        FActive:=A;
  
        TimeNum:=0;
  
    end;
  
  end;
  
   
  
  procedure TTimeCount.pause;
  
  begin
  
   if FTimer.Enabled then
  
    FTimer.Enabled:=False;
  
  end;
  
   
  
  procedure TTimeCount.Resume;
  
  begin
  
    if not FTimer.Enabled then
  
      FTimer.Enabled:=True;
  
  end;
  
   
  
  procedure TTimeCount.stop;
  
  begin
  
    FTimer.Enabled:=False;
  
    FCount:=0;
  
    TimeNum:=0;
  
    caption:='0'
  
  end;
  
   
  
  procedure TTimeCount.start;
  
  begin
  
    if (not FTimer.Enabled)and(TimeNum=0) then
  
       FTimer.Enabled:=True;
  
  end;
  
   
  
  //最重要的時間函數,用於調用該類的事件觸發高度函數。
  
  //以及在容器中顯示計數值
  
  procedure TTimeCount.FTimerTimer(Sender:TObject);
  
  begin
  
    inc(FCount);
  
    if (FCount mod 3600)=0 then FCount:=0;
  
    Caption:=InttoStr(FCount);//這個就是顯示計數值
  
    inc(TimeNum);
  
    if (TimeNum=TimeLen)and(FActive) then
  
    begin
  
         DoTimeOut;
  
         TimeNum:=0;
  
    end;
  
  end;
  
  //事件調度函數,將外部的事件處理函數和該類的事件方法指針聯系起來
  
  procedure TTimeCount.DoTimeOut;
  
  begin
  
    if Assigned(FTimeOut) then
  
       FTimeOut(Self);
  
  end;
  
   
  
  end.
  
   
  
  五,組件注冊安裝與刪除。
  
   
  
  組件類編寫完畢,接著就要測試了,這個從略,可以在剛才的工程中動態創建它,設置相應屬性,指定時間事件,看看是否正確。上面是經過測試的。
  
  到確定正確後,就要來看看裝組件的步驟了:
  
   
  
  首先,我們要把組件單元放在一個指定的文件夾中,以便以後管理,和IDE統一指定路徑。
  
  我在Delphi目錄下新建了MyCom文件夾,用來存放組件單元
  
  然後選:
  
  Component—>New Component; 
  
  啟動Component Wizard
  
  在Ancestor type(父類):中填TCustomPanel
  
  Class Name(你的組件類名)中填:TimeCount
  
  Palette Page,默認為Samples,我就用這個吧,當然也可以自己創建一個。
  
  Unit File Name(組件類所在的單元名),就寫TimeCount吧。
  
  Search Path(搜索路徑),必須把上面所建的文件夾路徑包含進去,編譯時才能能過。
  
                        點擊旁邊的”…”按鈕,出現一個對話框,裡面的編輯框旁邊又有一個”…“按鈕,點擊它出現浏覽文件夾框,在其中選中上面建的文件夾的路徑,點確定,再點OK,回去New Component;。
  
                        這時再點下面的OK就行啦,出現代碼如下:
  
  unit TimeCount;
  
   
  
  interface
  
   
  
  uses
  
   messages, SysUtils,Classes,Graphics,Controls,ExtCtrls;
  
   
  
  type
  
    TTimeCount=class(TCustomPanel)
  
    private
  
    published
  
    public
  
    published   
  
    end;
  
   
  
  procedure Register;
  
   
  
  implementation
  
   
  
  procedure Register;
  
  begin
  
    RegisterComponents('Samples', [TTimeCount]);  //注冊控件用的函數,自動幫你生成
  
  end;
  
  end.
  
  這時再把上面的組件類替換掉這個類就行啦(當然上面的注冊函數可要保留呀)。然後保存到上面所建的文件夾中。
  
   
  
  接著就要安裝組件了,點Component->install Component
  
  對話框中第一項Unit file Name,是組件單元.pas文件的路徑名字。其他只要按缺省。
  
             記得第三項的。。Delphi7Libdclusr.dpk,這個就是存放組件的包名,等一下刪除組件時用到的
  
                     接下來點OK,就可以了,看看Samples是不是有了一個新組件啦。
  
                      
  
   不過面板上的組件圖標似乎不好看,應該給他一個新的圖標了:
  
   但之前應該把它先從面板刪除,File->Open…打開dclusr.dpk.
  
  選中其中的Contains下的TimeCount.pas,點上面的Remove。將其刪除
  
  然後再點Compile,重新將包編譯一次。就行啦。Samples上的新組件就消失了。
  
   
  
  接下來是做組件圖標:
  
  打開Image Eidtor,新建一個DCR文件,在其中建一個24×24的位圖,畫上你喜歡的圖標,將位圖的名字起為組件類名一樣,而且用大寫,即:TTIMECOUNT
  
  將DCR文件起名為組件類所在單元名一樣,而且大寫,即:TIMECOUNT。
  
  保存文件到單元所在的文件夾中,
  
  最後依上面的方法再裝一次,看是不是有一個漂亮的圖標啦
  
   
  
   
  
  六,講完了,大家應該有一個清楚的概念了吧,其中涉及到了好多的技巧。在以後的篇章中將不再講這些內容了,只把主要精力花在組件實現技術上。因為我們這個組件還是比較簡單,沒有涉及到多少高級的主題。但沒有關系,跟著我慢慢地做下來,你們會了解組件制作的方方面面的。 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved