delphi控件的寫法方式_第1頁(yè)
delphi控件的寫法方式_第2頁(yè)
delphi控件的寫法方式_第3頁(yè)
delphi控件的寫法方式_第4頁(yè)
delphi控件的寫法方式_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

delphi控件的寫法方式.doc 免費(fèi)下載

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

二、控件開發(fā)縱覽

通過(guò)開發(fā)上邊這個(gè)控件,我們已經(jīng)對(duì)Delphi控件開發(fā)有了基本的認(rèn)識(shí)。下面我們將系統(tǒng)的講述一下控件開發(fā)的知識(shí)。制作控件第一件事就是選擇適當(dāng)?shù)腄elphi對(duì)象類型作為父對(duì)象,以派生新的對(duì)象。子對(duì)象可以繼承父對(duì)象的全部非private部件,但不能擺脫不需要的部件。因此,所選父對(duì)象應(yīng)盡可能多地包含子對(duì)象所需的屬性、事件和方法,但不應(yīng)包含子對(duì)象不需要的東西。Delphi必須從Tcomponent或Tcomponent的子類派生。TComponent是所有Delphi控件的基點(diǎn),但若直接從TComponent派生新控件,很多東西就需要自己從頭做起。一般只有非可視控件才直接從TComponent派生。Delphi提供了若干專門用于制作控件(可視控件)的對(duì)象類型,都是從TControl和TWinControl派生而來(lái)。TControl的子類型用于非窗口式控件,TWinControl的子類型則用于窗口式控件。除非特殊需要,一般不直接從TControl和TWinControl派生新控件,而是從其子類型派生。這樣可以充分利用原有的屬性、事件和方法,減少很多工作量。在這些控件類型中,非通用的屬性、事件和方法都聲明為protected。這樣可以禁止控件用戶訪問(wèn),又能被子類型繼承和修改。在新控件中,可以簡(jiǎn)單地把繼承來(lái)的屬性和事件重新聲明為published,使控件用戶能在設(shè)計(jì)期通過(guò)對(duì)象編輯窗口訪問(wèn),也可以進(jìn)而修改屬性的默認(rèn)值和讀寫方式,或是重載(override)事件處理子過(guò)程和其他控件方法,以修改其中的程序代碼。重聲明可以放寬訪問(wèn)權(quán)限,但不能相反,例如,不可能把published屬性重聲明為private或protected。Delphi控件也是Delphi的類,所有的控件都有特定的結(jié)構(gòu)。一般控件包括三大組成部分:屬性、方法和事件,下面先介紹初學(xué)控件開發(fā)的最難懂的屬性部分,其他部分我們將在以后章節(jié)為大家介紹。屬性主要部分就是屬性的讀寫方法(或讀寫字段)。前面的例子用的是讀寫字段,也就是對(duì)屬性的讀寫都通過(guò)對(duì)字段的讀寫來(lái)完成。下面為大家講解一下讀寫方法的使用方法:TmyComponent=class(TComponent)Private

Fcount:Integer;

ProcedureSetCount(Avalue:Integer);Pulbished

PropertyCount:IntegerreadFcountwriteSetCount;End;這個(gè)例子中當(dāng)執(zhí)行MyComponent1.Count:=1;這樣的代碼時(shí),將會(huì)導(dǎo)致SetCount方法執(zhí)行,并且參數(shù)Avalue被指定為1;當(dāng)執(zhí)行I:=MyComponent1.Count;方法時(shí),會(huì)將Fcount的值返回給I。屬性的聲明語(yǔ)法允許屬性聲明的Read和Write部分用訪問(wèn)方法取代對(duì)象私有數(shù)據(jù)域。屬性的讀方法是不帶參數(shù)的函數(shù),返回同屬性相同類型的值。通常讀方法以Get開頭。屬性的寫方法總是帶一個(gè)參數(shù)的過(guò)程。寫方法常常以Set開頭。三、開關(guān)控件TlincoSwitch

用過(guò)Delphi1(好古老的東東呀?。┑娜讼嘈哦加浀眠@個(gè)開關(guān)控件,不知道當(dāng)初Borland為什么把這么一個(gè)在開發(fā)普通應(yīng)用程序中應(yīng)用不到的工控控件放到Delphi中,而且在Delphi2及其以后的版本中再也沒有見過(guò)它的身影。讓我們懷著懷舊的心情把這位“開國(guó)元老”請(qǐng)出來(lái)吧!1、建立位圖資源文件:用ImageEditor建立一個(gè)Res文件,并在文件中分別建立下面兩個(gè)位圖,并分別命名為SWITCHON、SWITCHOFF。保存此Res到控件單元所在目錄下。2、寫控件代碼。unitLincoSwitch;interfaceuses

SysUtils,Classes,Controls,Graphics,Windows;type

TLincoSwitch=class(TCustomControl)

private

FIsOn:Boolean;

FPicOn:Graphics.TBitmap;

FPicOff:Graphics.TBitmap;

procedureFSetIsOn(AValue:Boolean);

protected

procedureClick;override;

procedurePaint;override;

public

constructorCreate(AOwner:TComponent);override;

destructorDestroy;override;

published

propertyIsOn:BooleanreadFIsOnwriteFSetIsOn;

propertyOnClick;

propertyOnKeyDown;

propertyOnKeyPress;

propertyOnKeyUp;

propertyOnCanResize;

propertyOnDblClick;

propertyOnMouseDown;

propertyOnMouseMove;

propertyOnMouseUp;

propertyOnMouseWheel;

propertyOnResize;

end;procedureRegister;implementation{$R*.res}procedureLoadBitmapFromRes(ABitmapId:string;ABitmap:Graphics.TBitmap);begin

ABitmap.LoadFromResourceName(hInstance,ABitmapId);//從資源文件中讀取位圖end;constructorTLincoSwitch.Create(AOwner:TComponent);begin

inheritedCreate(AOwner);

FPicOn:=Graphics.TBitmap.Create;

FPicOff:=Graphics.TBitmap.Create;

LoadBitmapFromRes('SWITCHON',FPicOn);

LoadBitmapFromRes('SWITCHOFF',FPicOff);

Invalidate;end;destructorTLincoSwitch.Destroy;begin

FPicOn.Free;

FPicOff.Free;

inherited;end;procedureTLincoSwitch.Click;begin

IsOn:=notIsOn;//改變按鈕的狀態(tài)

Invalidate;

inherited;end;procedureTLincoSwitch.Paint;begin//畫開關(guān)圖案

ifIsOnthen

StretchBlt(Canvas.Handle,0,0,self.Width,self.Height,FPicOn.Canvas.Handle,

0,0,FPicOn.Width,FPicOn.Height,SRCCOPY)

else

StretchBlt(Canvas.Handle,0,0,self.Width,self.Height,FPicOff.Canvas.Handle,

0,0,FPicOff.Width,FPicOff.Height,SRCCOPY);end;procedureTLincoSwitch.FSetIsOn(AValue:Boolean);begin

FIson:=AValue;

Invalidate;end;procedureRegister;begin

RegisterComponents('Linco',[TLincoSwitch]);end;end.3、代碼分析

(1)、因?yàn)槲覀円诳丶砻嫔蠈粹o的圖案畫出來(lái),所以我們選擇TcustomControl做為父類控件,因?yàn)樗袀€(gè)Canvas屬性,我們可以利用Canvas在控件表面作圖。不選用Tcontrol的原因是因?yàn)樗泻芏辔覀儾恍枰膶傩?。?)、ABitmap.LoadFromResourceName(hInstance,ABitmapId);是從資源文件中讀取Id為AbitmapId的位圖,關(guān)于資源文件的使用請(qǐng)參考其他相關(guān)資料。注意代碼中的“{$R*.res}”,它的作用是將資源文件編譯到程序文件中,如果沒有這個(gè)預(yù)編譯條件,程序?qū)?huì)出現(xiàn)錯(cuò)誤。(3)、StretchBlt是將位圖畫到畫板上,使用方法請(qǐng)參考MSDN。(4)、我們?yōu)榭丶黾恿薎sOn屬性。這個(gè)布爾屬性用來(lái)表示開關(guān)的狀態(tài)(開/關(guān))。從propertyIsOn:BooleanreadFIsOnwriteFSetIsOn;我們可以看出這個(gè)屬性是個(gè)可讀可寫的屬性。當(dāng)讀這個(gè)屬性時(shí)會(huì)將FisOn的值返回給調(diào)用者,而寫屬性時(shí)則會(huì)調(diào)用FsetIsOn方法,并將賦給屬性的值做為參數(shù)傳遞給FsetIsOn。在FsetIsOn方法中,有如下實(shí)現(xiàn)代碼:

FIson:=AValue;

Invalidate;首先將Fison設(shè)置為參數(shù)傳遞來(lái)的值,然后調(diào)用

Invalidate;要求重畫控件,以告訴用戶控件的狀態(tài)已經(jīng)改變,這一點(diǎn)是使用寫字段無(wú)法做到的。(5)

FPicOn:Graphics.TBitmap;FPicOff:Graphics.TBitmap;是聲明兩個(gè).Tbitmap類型變量以保存控件的開關(guān)兩種狀態(tài)的圖案。(6)

procedureClick;override;procedurePaint;override;分別是覆蓋父類中相應(yīng)的調(diào)度方法。當(dāng)控件被鼠標(biāo)單擊時(shí),Click方法會(huì)被調(diào)用,我們將在Click中改變控件的開關(guān)狀態(tài);Paint方法則在用戶調(diào)用

Invalidate方法或控件發(fā)生重畫時(shí)調(diào)用,我們一般在這個(gè)方法繪制控件的圖案。(7)、TcustomControl中又很多事件處理句柄。比如OnClick、OnKeyDown等,但是它把他們聲明成了Protected保護(hù)級(jí)別,所以我們?cè)贠bjectInspector中看不到他們,如果我們要他們可以在ObjectInspector中被用戶編輯的話,只要在Published中重新聲明他們即可,不用寫他們的讀寫方法,只要使用:Property

屬性名;這樣的方法就可以。比如這個(gè)例子中的:PropertyOnclick;思考題:1、

做一個(gè)有特效的按鈕控件,當(dāng)鼠標(biāo)按下時(shí)按鈕是一個(gè)紅色邊框的空心圓,當(dāng)鼠標(biāo)松開時(shí)按鈕是一個(gè)淡綠色邊框的空心圓。2、

對(duì)于父類控件中為protected的屬性,如果想將它在子類控件中公布,應(yīng)該怎么做?請(qǐng)思考Delphi為什么要將一些屬性設(shè)為protected級(jí)別?四、對(duì)特定字符串敏感的Edit控件我們這個(gè)控件將演示控件的自定義事件的書寫。這個(gè)控件有一個(gè)類型為string的SensitiveText屬性,當(dāng)用戶在輸入框中輸入的文字為InvalidText時(shí)就會(huì)觸發(fā)OnSensitiveText事件。按照慣例,我先把源碼展示給大家:unitTextSenseEdit;interfaceuses

SysUtils,Classes,Controls,StdCtrls;type

TSensitiveTextEvent=procedure(AText:string)ofobject;//方法指針

TTextSenseEdit=class(TEdit)

private

FSensitiveText:string;

FOnSensitiveText:TSensitiveTextEvent;

procedureSetSensitiveText(AValue:string);

protected

procedureChange;override;

public

published

propertySensitiveText:stringreadFSensitiveTextwriteSetSensitiveText;

propertyOnSensitiveText:TSensitiveTextEventreadFOnSensitiveTextwriteFOnSensitiveText;

end;procedureRegister;implementationprocedureRegister;begin

RegisterComponents('Linco',[TTextSenseEdit]);end;procedureTTextSenseEdit.Change;begin

inherited;

ifText=SensitiveTextthen

ifAssigned(OnSensitiveText)then

OnSensitiveText(Text);end;procedureTTextSenseEdit.SetSensitiveText(AValue:string);begin

FSensitiveText:=AValue;end;end.代碼解釋:(1)、SensitiveText屬性的添加方法大家已經(jīng)熟悉了,這里不多解釋。(2)、正如大家猜測(cè)的,Change方法正是編輯框文字發(fā)生變化時(shí)的調(diào)度方法,它將引起OnChange事件。我們可以在這個(gè)方法中監(jiān)控編輯框文字發(fā)生的變化,當(dāng)文字等于SensitiveText就觸發(fā)OnSensitiveText事件(具體的實(shí)現(xiàn)方法在后邊解釋)。(3)、Delphi中的控件的事件機(jī)制是通過(guò)方法指針來(lái)實(shí)現(xiàn)的。聲明方法指針的格式為:方法指針名稱=procedure(參數(shù)列表)ofobject;聲明事件屬性的方法與聲明普通屬性的方法相同。在我們這個(gè)例子中,我們首先聲明一個(gè)FOnSensitiveText:TSensitiveTextEvent;私有變量,然后propertyOnSensitiveText:TSensitiveTextEventreadFOnSensitiveTextwriteFOnSensitiveText;聲明事件屬性。這樣注冊(cè)控件后,當(dāng)用戶把控件放到窗體中后,就會(huì)在ObjectInspector中Evnets頁(yè)中出現(xiàn)OnSensitiveText事件,我們就可以像使用其他事件一樣使用這個(gè)事件了。

但是我們現(xiàn)在只是聲明了一個(gè)事件屬性,并沒有書寫任何代碼來(lái)激發(fā)這個(gè)事件。我們應(yīng)該在合適的時(shí)候激發(fā)此事件,顯而易見我們應(yīng)該在Change方法中激發(fā)此事件:procedureTTextSenseEdit.Change;begin

inherited;

ifText=SensitiveTextthen

ifAssigned(OnSensitiveText)then

OnSensitiveText(Text);end;當(dāng)ifText=SensitiveText時(shí)就判斷控件使用者是否為OnSetSensitiveText寫代碼了(準(zhǔn)確的說(shuō)是是否為OnSetSensitiveText事件句柄賦值了),如果寫代碼了則調(diào)用OnSetSensitiveText(Text);來(lái)激發(fā)OnSetSensitiveText事件,并把控件的Text傳遞給方法的Avalue參數(shù)。正如“方法指針”這個(gè)名字一樣,被聲明為方法指針類型的變量可以當(dāng)作方法使用,用來(lái)激發(fā)事件。VCL已經(jīng)為我們預(yù)定義了一些常用的事件句柄,我們直接拿來(lái)使用:TnotifyEvent,TmouseEvent,TmouseMoveEvent,TkeyPressEvent等,具體可以參考VCL源碼。思考題:做一個(gè)支持累加運(yùn)算的文本編輯框控件,用戶可以在編輯框中輸入正整數(shù)。當(dāng)用戶按回車時(shí),如果編輯框中輸入的不是正整數(shù)(為負(fù)數(shù)、小數(shù)或一般字符串)則觸發(fā)控件的OnError事件;如果輸入的是正整數(shù),則開始計(jì)算從1到用戶輸入的那個(gè)正整數(shù)中所有整數(shù)的和(用1+2+3+……這種累加的辦法實(shí)現(xiàn),不要用(1+n)*n/2這種直接計(jì)算的方法),并且在計(jì)算工程中如果發(fā)現(xiàn)計(jì)算的中間結(jié)果位數(shù)是5,則觸發(fā)OnTailFive事件。五、復(fù)合控件復(fù)合控件是Delphi控件中非常重要的一種控件,復(fù)合控件就是將兩個(gè)或兩個(gè)以上的控件重新組合成一個(gè)新的控件。例如TspinEdit、TlabeledEdit、TDBNavigator等就是復(fù)合控件,TDBNavigator其實(shí)就是在一個(gè)Panel放上若干個(gè)Button而已。制作一個(gè)復(fù)合控件時(shí),我們一般從TwinControl派生控件。我們這次做的控件是擁有一個(gè)Edit編輯框和一個(gè)Button按鈕的復(fù)合控件,在用戶在編輯框中輸入文字的過(guò)程中,Button將隨時(shí)顯示編輯框中文字的長(zhǎng)度。我們把控件的源碼先展示給大家。unitEditButton;interfaceuses

SysUtils,Classes,Controls,StdCtrls,Messages;type

TEditButton=class(TWinControl)

private

FEdit:TEdit;

FButton:TButton;

FText:string;

procedureFSetText(AValue:string);

procedureOnEditChange(Sender:TObject);

protected

procedureWMSize(varMsg:TMessage);messageWM_SIZE;

public

constructorCreate(AOwner:TComponent);override;

destructorDestroy;override;

published

propertyText:stringreadFTextwriteFSetText;

end;procedureRegister;implementationprocedureRegister;begin

RegisterComponents('Linco',[TEditButton]);end;constructorTEditButton.Create(AOwner:TComponent);begin

inherited;

FEdit:=TEdit.Create(nil);

FEdit.Parent:=self;

FEdit.Top:=0;

FEdit.Left:=0;

FEdit.Height:=Height;

FEdit.Width:=Widthdiv2;

FEdit.OnChange:=OnEditChange;

FButton:=TButton.Create(nil);

FButton.Parent:=self;

FButton.Top:=0;

FButton.Left:=Widthdiv2;

FButton.Height:=Height;

FButton.Width:=Widthdiv2;end;destructorTEditButton.Destroy;begin

FEdit.Free;

FButton.Free;

inherited;end;procedureTEditButton.FSetText(AValue:string);begin

FEdit.Text:=AValue;end;procedureTEditButton.OnEditChange(Sender:TObject);begin

FButton.Caption:=IntToStr(Length(FEdit.Text));end;procedureTEditButton.WMSize(varMsg:TMessage);begin

FEdit.Height:=Height;

FEdit.Width:=Widthdiv2;

FButton.Left:=Widthdiv2;

FButton.Height:=Height;

FButton.Width:=Widthdiv2;end;end.代碼解釋:(1)、我們首先定義了兩個(gè)變量

FEdit:TEdit;

FButton:TButton;

分別代表復(fù)合控件中的文字編輯框和按鈕。(2)所謂復(fù)合控件說(shuō)簡(jiǎn)單一點(diǎn)就是在一個(gè)共同的基板上將組成復(fù)合控件的各個(gè)控件(可以叫做子控件)畫出來(lái)。所以我們?cè)跇?gòu)造函數(shù)中建立各個(gè)子控件,然后分別設(shè)定它們的位置等屬性。以文字編輯框?yàn)槔篎Edit:=TEdit.Create(nil);的作用是建立編輯框控件。如果Create的參數(shù)指定為nil,則子控件在設(shè)計(jì)狀態(tài)是可以響應(yīng)用戶的操作的;而如果設(shè)定為self(即設(shè)定子控件的父控件為基板),則子控件在設(shè)計(jì)時(shí)時(shí)不可響應(yīng)用戶操作的,如果設(shè)定為self則析構(gòu)函數(shù)中就不用Fedit.Free來(lái)銷毀對(duì)象了,對(duì)象會(huì)自動(dòng)銷毀。

FEdit.Parent:=self;的作用是設(shè)定子控件的父控件,如果沒有這一句則控件是無(wú)法顯示的。

FEdit.Top:=0;

FEdit.Left:=0;

FEdit.Height:=Height;

FEdit.Width:=Widthdiv2;這四句是設(shè)定控件在基板上的相對(duì)位置的,這里的Top,Left不是相對(duì)于窗體的,而是相對(duì)于基板的。

FEdit.OnChange:=OnEditChange;則是設(shè)定編輯框控件的OnChange(文字改變事件)的處理句柄為OnEditChange;(1)

用戶有可能在設(shè)計(jì)時(shí)或運(yùn)行時(shí)通過(guò)代碼改變控件的大小,這時(shí)控件中子控件的順序就會(huì)變得亂七八糟,所以需要相應(yīng)控件的WM_SIZE事件(控件大小發(fā)生變化的事件)重新設(shè)定子控件的位置,大小等。函數(shù)WMSize的作用就是這樣的。安裝控件后發(fā)現(xiàn)控件已經(jīng)可以正確運(yùn)行了,但是還有一個(gè)問(wèn)題,就是這個(gè)控件沒有了Onclick,Onchange等必須的屬性。我們只要為控件增加事件處理句柄屬性,然后把事件處理句柄屬性的讀寫方法都指向子控件的事件處理句柄屬性即可。例如我們?yōu)榭丶黾覱nClick事件,這個(gè)事件發(fā)生在用戶單擊按鈕時(shí),我么只要在Pulished部分增加如下代碼:property

OnClick:

TnotifyEventreadGetOnClickwriteSetOnClick在Private中增加如下方法聲明:functionGetOnclick:TnotifyEvent;procedureSetOnclick(AValue:TnotifyEvent);這兩個(gè)方法的實(shí)現(xiàn)分別為:function

TeditButton.GetOnclick:TnotifyEvent;begin

result:=Fbutton.Onclick;end;procedureTeditButton.SetOnclick(AValue:TnotifyEvent);begin

Fbutton.OnClick:=Avalue;end;思考題:1、做一個(gè)模仿播放器中的操作按鈕的復(fù)合控件,控件由三個(gè)按鈕組成,分別是“播放”、“暫?!?、“停止”,請(qǐng)按照正常的邏輯關(guān)系,處理這三個(gè)按鈕的可用/不可用關(guān)系。(提示:可以參考TDBNavigator的源代碼)六、控件手拉手――控件關(guān)聯(lián)的實(shí)現(xiàn)控件的關(guān)聯(lián)在Delphi中也是很常見的,我們可以設(shè)定一個(gè)控件的某個(gè)屬性指向另一個(gè)控件。比如我們?cè)诖绑w上放上Tedit,TpopupMenu兩個(gè)控件,然后設(shè)定Tedit的PopupMenu屬性為TpopupMenu控件,運(yùn)行后在Tedit點(diǎn)擊右鍵就會(huì)彈出剛才設(shè)定的那個(gè)TpopupMenu菜單,也就是說(shuō)Tedit,TpopupMenu聯(lián)手完成了任務(wù)。再比如TDBEdit控件的DataSource屬性就可以指向一個(gè)TdataSource控件,這樣就可以在TDBEdit控件中顯示TdataSource輸出的某個(gè)字段的值了。

下面我們將寫一個(gè)簡(jiǎn)單的實(shí)現(xiàn)控件關(guān)聯(lián)的控件。這個(gè)控件派生于Tedit,它可以與一個(gè)Tlabel控件關(guān)聯(lián),在控件的編輯框中輸入文字時(shí),與它關(guān)聯(lián)的Tlabel控件的文字將隨著它而變化。代碼如下:unitMyEdit;interfaceuses

SysUtils,Classes,Controls,StdCtrls;type

TMyEdit=class(TEdit)

private

FLinkLabel:TLabel;

procedureFSetLinkLabel(AValue:TLabel);

protected

procedureNotification(AComponent:TComponent;Operation:TOperation);

override;

procedureChange;override;

public

published

propertyLinkLabel:TLabelreadFLinkLabelwriteFSetLinkLabel;

end;procedureRegister;implementationprocedureRegister;begin

RegisterComponents('Linco',[TMyEdit]);end;procedureTMyEdit.Change;begin

inherited;

ifLinkLabel<>nilthen

LinkLabel.Caption:=Text;end;procedureTMyEdit.FSetLinkLabel(AValue:TLabel);begin

FLinkLabel:=AValue;

ifAValue<>nilthen

FLinkLabel.FreeNotification(self);end;procedureTMyEdit.Notification(AComponent:TComponent;

Operation:TOperation);begin

inherited;

if(Operation=opRemove)and(AComponent=LinkLabel)then

LinkLabel:=nil;end;end.代碼解釋:(1)、我們只要將控件的任意一個(gè)屬性的類型設(shè)定為另外一個(gè)控件的類名稱,那么我們就可以在控件的ObjectInspector中將這個(gè)屬性指向那個(gè)控件(或那個(gè)控件的派生控件)的一個(gè)實(shí)例。比如本例中我們?cè)黾恿薒inkLabel屬性,它的類型為Tlabel,所以我們就可以把LinkLabel屬性指向一個(gè)標(biāo)簽控件。(2)、請(qǐng)注意FsetLinkLabel中的這段代碼:ifAValue<>nilthenFLinkLabel.FreeNotification(self);如果我們將控件關(guān)聯(lián)屬性指向了一個(gè)控件,可是后來(lái)又將被指向的控件刪除了,那么我們的控件關(guān)聯(lián)屬性是不會(huì)自動(dòng)刪除的,這樣就會(huì)造成控件關(guān)聯(lián)屬性指向的控件不存在的現(xiàn)象。我們必須自動(dòng)感知被關(guān)聯(lián)控件的刪除并重新設(shè)定控件關(guān)聯(lián)屬性為不指向任何控件,這樣就避免了錯(cuò)誤的發(fā)生。FLinkLabel.FreeNotification(self);的作用就是這樣的。它調(diào)用控件的FreeNotification方法(在Tcomponent中定義)向被指向的控件注冊(cè)一個(gè)“消息”,當(dāng)被指向控件被刪除時(shí),會(huì)向所有向他注冊(cè)的控件發(fā)送一個(gè)它被刪除的消息,此時(shí)向他注冊(cè)的控件就會(huì)觸發(fā)Notification方法,這樣我們就可以自動(dòng)感知被指向控件的狀態(tài)了。這是設(shè)計(jì)模式中Observer(觀察者)模式的典型應(yīng)用。既然向他注冊(cè)的控件就會(huì)觸發(fā)Notification方法,我們就覆蓋父類的Notification方法,寫出如下的代碼:

if(Operation=opRemove)and(AComponent=LinkLabel)then

LinkLabel:=nil;這句話的意思是:如果控件被刪除并且被刪除的控件(因?yàn)槲覀兊目丶赡芟蚨鄠€(gè)控件注冊(cè)了消息)是LinkLabel,那么我們就設(shè)定LinkLabel屬性不指向任何控件。(3)覆蓋父類的Change調(diào)度方法。在此方法里為連接的LinkLabel的Caption賦值就達(dá)到我們的目的了。思考題:1、做一個(gè)Label控件,給它增加一個(gè)DataSource屬性,該屬性可以指向一個(gè)TdataSource類型的控件,它有一個(gè)GetRecordCount方法。當(dāng)調(diào)用此方法時(shí),就在Label控件中顯示這個(gè)DataSource對(duì)應(yīng)的數(shù)據(jù)集中的記錄的條數(shù)。對(duì)話框控件的制作Delphi中有很多對(duì)話框組件,例如TopenDialog、TfontDialog等。這些控件的特點(diǎn)就是雖然是不可視控件,但是在運(yùn)行時(shí)都有一個(gè)可視化的效果,比如TopenDialog的可視化效果就是一個(gè)打開對(duì)話框。我們這次將開發(fā)一個(gè)日期對(duì)話框控件,當(dāng)我們調(diào)用控件的Execute方法(不一定非要使用Execute方法,不過(guò)大部分對(duì)話框控件都是使用這個(gè)方法,我們也就按照慣例來(lái)了)時(shí),就會(huì)彈出一個(gè)可以選擇日期的對(duì)話框,我們選擇一個(gè)日期后,點(diǎn)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論