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

組件制作之一(概念)

編輯:Delphi
作為組件制作的開始,應該了解一些概念,我以為這些概念是非常重要的,將可以作為以後實踐的理論基礎。
  
  ?
  
  一,?組件的簡要層次結構。一般情況下,VCL的組件可以從Tcomponent為開始。其最明顯的特征就是它的屬性可以在設計時通過對象察看器來操縱,另外,他還能擁有其他組件。
  
  從Tcomponent下,分出非可視組件和可視組件。
  
  非可視組件如TOPenDialog,TTimer,TTable等,這些組件因為繼承自Tomponent,所以也就繼承了在設計時可以被操縱的特性。
  
  可視化組件始自TControl,是它引入了可視化屬性和方法,使繼承自它的類都有了這些可視化特性。
  
  TControl又分出兩類組件類型:從TWinControl(窗口控件)自下的控件,和從TGraphicControl(圖形控件)自下的控件。繼承自TWinControl的控件將windows控件進行封裝,所以擁有Windows控件的很多特性,比如可以得到焦點,有唯一的句柄,用戶可以通過發送消息與這些控件進行交互等。而繼承自TGraphicControl的控件,也是可見的,但沒有句柄,可以稱之為圖形控件,比如TLabel,TBevel,都是Delphi畫出來的,並不占用系統資源。
  
  二,屬性 先看一個簡單的屬性定義:
  
   TsomeObj=class
  
  ??????????Private
  
  ????????????FCount:integer;
  
  ??????????Protected
  
  ????????????Procedure?SetCount(value:Integer);
  
  ??????????published
  
   ??Property?count:integer?read?FCount?write?SetCount?default?0;//屬性定義
  
  ??????????End;
  
  ????該屬性從私有成員FCount讀出值,而靠SetCount方法設置值到私有成員FCount。
  
  屬性的優勢在於可以很直觀進行讀寫,而又不同於私有成員。因為屬性可以通過寫訪問方法來保護私有成員:
  
   Procedure?TsomeBoj.SetCount(value:Integer);
  
  ??????????Begin
  
  ?????????????If?FCount<>value?then
  
  ?????????????????FCount:=value;
  
  ??????????End;
  
  ????其中屬性定義中的Default 0並不是默認值(即對象察看器顯示的值),默認值要在組件類的構造函數中設定。而Default有這樣的作用,決定DFM文件中是否要保存該屬性的值,比如上面為Default?0,即當該屬性值為0時,則該屬性不會被保存到DFM中,如果該屬性值不為0,則該屬性會被保存到DFM中。另外屬性定義還有一個關鍵字為
  
  NoDefault,設置了這個關鍵字,比如
  
  Property?count:integer?read?FCount?write?SetCount?NoDefault;
  
  則無論它的值是什麼,都會被寫到DFM文件中。
  
  ?
  
  屬性可以有如下幾種類型,下面只給出簡單介紹,而這些類型的屬性,會在組件制作時詳細的運用:
  
  簡單類型屬性:如上面定義的,加一個例子
  
   Property?text:string?read?Ftext?write?SetText;
  
  枚舉類型屬性:TEnumtype=(Enum1,Enum2,Enum3);
  
  ??????????????FEnumtype:TEnumtype;
  
  ??????????????Property?Enumtype:TEnumtype?read?FEnumtype?write?FEnumtype;
  
  ??  在對象察看器中看來就是下拉列框選擇值。
  
  集合類型屬性:Tset=(set1,set2,set3);
  
  ??????????????Tsets=set?of??Tset;
  
  ??????????????Fsets:Tsets;
  
  ??????????????Property?sets:Tsets?read?Fsets?write?Fsets;
  
  在對象察看器中看來,就是列出幾個選項分別設置真假。比如TForm的BorderIcons屬性即是。
  
  對象類型屬性:一個屬性是一個對象,而這個對象必須派生自Tpersistent或者他之下的類,才能在對象察看器中可以展開它,並設置它裡面的屬性。
  
  ????數組類型屬性:數組屬性如果要在對象察看器中看見,需要有自己的屬性編輯器(如果不想在對象察看器看當然就不用啦),是比較高級的組件,在後來的組件制作再來介紹,會更直觀一些。這裡只給出它的定義形式:
  
     property?Selected[Index:?Integer]:?Boolean?read?GetSelected?write?SetSelected;
  
  三,事件:事件其實是一種特殊的屬性,他是指針類型,指向一個事件方法類型。當有特定的事件發生時,它就會關聯到一段執行代碼。
  
   下面以一個例子來講解事件是怎麼發生的。
  
  ??????????我們先定義一個鼠標點下事件的鼠標事件類型,它其實就是方法指針:
  
   type?TMouseEvent?=?procedure?(Sender:?TObject;?Button:?TMouseButton;?Shift:?TShiftState;?X,?Y:?Integer)?of?object;
  
  ??????????又定義一個私有成員:鼠標事件類型的,即一個方法指針類型
  
  ??????????FonMouseDown:TMouseEvent
  
  ??????????最後定義一個屬性:類要通過這個屬性將外部的事件處理函數和FonMouseDown關聯在一起:
  
  ??????????onMouseDown:TMouseEvent?read?FonMouseDown?write?FonMouseDown;
  
   當有鼠標左鍵點擊的,系統會向窗口會發送WM_LBUTTONDOWN;消息
  
   Delphi?可以截獲這個消息,如下定義消息函數:
  
  ??????????procedure?WMLButtonDown(var?Message:?TWMLButtonDown);?message?WM_LBUTTONDOWN;
  
  ??????????在這個消息處理函數中調DOMouseDown,DoMouseDown又調?用了MouseDown
  
  ?????????在這個函數裡面才到了最重要的部分
  
  ?????????該函數是這樣的:
  
  procedure?TControl.MouseDown(Button:?TMouseButton;Shift:?TShiftState;?X,?Y:?Integer);
  
  begin
  
  ?  ?if?Assigned(FOnMouseDown)?then?FOnMouseDown(Self,?Button,?Shift,?X,?Y);
  
  end;
  
  而我們先來看看用戶外部是怎麼操作的,
  
  他自己定義一個SomeobjMouseDown;?是一個事件處理函數,必須和TMouseEvent的形式一樣:
  
  Procedure?SomeobjMouseDown(Sender:?TObject;?Button:?TMouseButton;
  
  ??Shift:?TShiftState;?X,?Y:?Integer);
  
  然後他這樣賦值:someobj.onMouseDown:=SomeobjMouseDown;
  
  當賦值以後,類內部其實是通過onMouseDown屬性,將SomeobjMouseDown;與FonMouseDwon關聯在一起,也就是說,MouseDown方法中調用了FOnMouseDown(Self,?Button,?Shift,?X,?Y);其實就等於調用了Procedure?SomeobjMouseDown(Sender:?TObject;?Button:?TMouseButton;Shift:?TShiftState;?X,?Y:?Integer);
  
  所以用戶就可以在這個自定義的事件方法中寫自己的代碼,當事件發生時,該類的調度機制就會自動調用這個事件方法啦
  
  也許有人會問,為什麼從消息處理函數要調用DoMouseDown,DoMouseDown又調用MouseDown,然後再調用事件方法呢。為什麼不直接在消息處理函數WMLButtonDown中調用呢,其實它這樣的做的目的是要進行一些保護判斷,以及一些消息附加值的轉換,使這些值看起來更加直觀。
  
  好了,事件就講了這裡,不知道你們明白了沒有,可能是我的表達能力不行,但沒有關系,到真正做的時候,大家應該能明白了。
  
  四,組件制作步驟:有了上面的基本概念,其實制作簡單組件已經不是什麼問題了,而要做真正的組件,還需要有一個正確過程,我們以後學做組件,也會順著這個過程來做。主要如下:
  
  1,?確定一個祖先類。怎麼確定,可以根據上面組件的簡要層次結構來確定。如果你想做非可視化組件,可以從繼承TComponent開始。如果想做可視要可視化組件,可以從TControl的子類開始。
  
  2?創建組件的單元,這個在制作組件時再說,不過是在IDE裡面做幾個操作而已。
  
  3?給組件寫屬性,方法,事件,成員,等。這些在上面己有詳細說明,是寫組件的核心部分,事實上也是後面實踐的主要內容。
  
  4測試,安裝組件和寫幫助,這個內容比較次要,後面的例子會講怎麼樣安裝,包括單個單元,或用包的形式安裝。而寫幫助,己超出范圍,這裡就不說了。
  
  ?
  
  關於組件基本概念就到這裡講完了,接下來就是實踐了,有了上面的知識,實踐起來也不是很難,很多東西都在上面了,而一些高級的特性,會在以後慢慢說的。
  
  ?
  
  下一篇是做一個簡單的組件,其實只用到了這裡講到了一些基本原理,而最重要的是給出了一個完整的組件制作過程。到了以後難度更大的組件,則重點會在代碼的實現上,其他則從略了
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved