19.2.2.2 創(chuàng)建事件
事件是部件的很重要的部分。事件是部件必須響應(yīng)的系統(tǒng)事件與響應(yīng)事件的一段代碼的聯(lián)接。響應(yīng)代碼被稱為事件處理過程,它總是由部件用戶來編寫。通過使用事件,應(yīng)用開發(fā)者不需要改變部件本身就能定制部件的行為。作為部件編寫者,運用事件能使應(yīng)用發(fā)者定制所有的標(biāo)準(zhǔn)Delphi部件。要創(chuàng)建事件,應(yīng)當(dāng)理解:
● 什么是事件
● 怎樣實現(xiàn)標(biāo)準(zhǔn)事件
● 怎樣定義自己的事件
1. 什么是事件
事件是聯(lián)接發(fā)生的事情與某些代碼的機制,或者說是方法指針,一個指向特定對象實例的特定方法的指針。從部件用戶的角度,事件是與系統(tǒng)事件(如OnClick)有關(guān)的名稱,用戶能給該事件賦特定的方法供調(diào)用。例如,按鈕Buttonl有OnClick方法,缺省情況下Delphi在包含該按鈕的窗體中產(chǎn)生一個為ButtonlClick的方法,并將其賦給OnClick。當(dāng)一個Click事件發(fā)生在按鈕上時,按鈕調(diào)用賦給OnClick的方法ButtonlClick:
部件用戶將事件看作是由用戶編寫的代碼,而事件發(fā)生時由系統(tǒng)調(diào)用的處理辦法。
從部件編寫者角度事件有更多的含義。最重要的是提供了一個讓用戶編寫代碼響應(yīng)特定事情的場所。
要編寫一個事件,應(yīng)當(dāng)理解:
● 事件和方法指針
● 事件是屬性
● 事件處理過程類型
● 事件處理過程是可選的
、 事件是方法指針
Delphi使用方法指針實現(xiàn)事件。一個方法指針是指向特定對象實例的特定方法的特定指針。作為部件編寫者,能將方法指針作為一種容器。你的代碼一發(fā)現(xiàn)事情發(fā)生,就調(diào)用由用戶定義的方法。
方法指針的工作方式就象其它的過程類型,但它們保持一個隱含的指向?qū)ο髮嵗闹羔。所有的控制都繼承了一個名為Click的方法,以處理Click事件。Click方法調(diào)用用戶的Click事件處理過程。
procedure TControl.Click;
begin
if Assigned(OnClick ) then OnClick( Self );
end;
如果用戶給Control的OnClick事件賦了處理過程(Handle),那鼠標(biāo)點按Control時將導(dǎo)致方法被調(diào)用。
、 事件是屬性
部件采用屬性的形式實現(xiàn)事件。不象大多數(shù)其它屬性,事件不使用方法來使實現(xiàn)read和write部分。事件屬性使用了相同類型的私有對象域作為屬性。按約定域名在屬性名前加“F”。例如OnClick方法的指針,存在TNotifyEvent類型FOnClick域中。OnClick事件屬性的聲明如下:
type
TControl=class ( TComponent )
private
FOnClick: TNofiFyEvent; { 聲明保存方法指針的域 }
protected
property OnClick: TNotifyEvent read FOnClick write FOnClick;
end;
象其它類型的屬性一樣,你能在運行時設(shè)置和改變事件的值。將事件做成屬性的主要好處是部件用戶能在設(shè)計時使用Object Inspector設(shè)置事件處理過程。
⑶ 事件處理過程類型
因為一個事件是指向事件處理過程的指針,因此事件屬性必須是方法指針類型,被用作事件處理過程的代碼,必須是相應(yīng)的對象的方法。
所有的事件方法都是過程。為了與所給類型的事件兼容,一個事件處理過程必須有相同數(shù)目和相同類型的相同順序的參數(shù)。Delphi定義了所有標(biāo)準(zhǔn)事件處理過程的方法類型,當(dāng)你創(chuàng)建自己的事件時,你能使用已有的事件類型,或創(chuàng)建新的。雖然不能用函數(shù)做事件處理過程,但可以用var參數(shù)得到返回信息。
在事件處理過程中傳遞var參數(shù)的典型例子是TKeyPressEvent類型的KeyPressed事件。TKeyPressEvent定義中含有兩個參數(shù)。一個指示哪個對象產(chǎn)生該事件。另一個指示那個鍵按下:
type
TKeyPressEvent=procedure( Sender: TObject; var key: char) of Object;
通常key參數(shù)包含用戶按下鍵的字符。在某些情況下,部件的用戶可能想改變字符值。例如在編輯器中強制所有字符為大寫,在這種情況下,用戶能定義下列的事件處理過程:
procedure TForml.EditlKeyPressed( Sender: TObject; var key: char);
begin
key := Upcase( key );
end;
也可使用var參數(shù)讓用戶覆蓋缺省的處理。
⑷ 事件處理過程是可選的
在為部件創(chuàng)建事件時要記住部件用戶可能并不編寫該事件的處理過程。這意味著你的部件不能因為部件用戶沒有編寫處理代碼而出錯。這種事件處理過程的可選性有兩個方面:
、 部件用戶并非不得不處理事件
事件總是不斷地發(fā)生在Windows應(yīng)用程序中。例如,在部件上方移動鼠標(biāo)就引起Windows發(fā)送大量的Mouse-Move消息給部件,部件將鼠標(biāo)消息傳給OnMouseMove事件。在大多數(shù)情況下,部件用戶不需要關(guān)心MouseMove事件,這不會產(chǎn)生問題,因為部件不依賴鼠標(biāo)事件的處理過程。同樣,自定義部件也不能依賴用戶的事件處理過程。
② 部件用戶能在事件處理過程寫任意的代碼
一般說來,對用戶在事件處理過程中的代碼沒有限制。Delphi部件庫的部件都支持這種方式以使所寫代碼產(chǎn)生錯誤的可能性最小。顯然,不能防止用戶代碼出現(xiàn)邏輯錯誤。
相關(guān)推薦:2010年9月計算機等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |