



下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第 11 章用組件開發(fā)一致的界面什么能算是好的界面,標(biāo)準(zhǔn)是非常主觀的。許多商業(yè)應(yīng)用程序都跟隨著WinTel 標(biāo)準(zhǔn):灰色的按鈕和控件,白色的背景。對(duì)商務(wù)程序來說,這可能是個(gè)不錯(cuò)的主意,因?yàn)橥ㄟ^多年的熟悉使得這個(gè)界面在某種程度上較為舒服,但這是個(gè)好的界面嗎?AlanCooper 是Visual Basic之父,他建議“通過堅(jiān)持使他們(Microsoft和 Apple )各自獨(dú)立的開發(fā)者群體遵守既定的方針,他們偷偷摸摸地阻止了來自應(yīng)用者群體的革新。” Cooper,212 Cooper 認(rèn)為,“我并不鼓吹忽略界面風(fēng)格方面的指導(dǎo),從而導(dǎo)致界面出現(xiàn)混亂。我僅僅認(rèn)為應(yīng)該像參議員看待說客那樣來看待對(duì)界面風(fēng)格
2、的指導(dǎo),而絕不能像司機(jī)服從于交警那樣。立法者知道說客想要削減某項(xiàng)經(jīng)費(fèi),但說客并非來自于持有客觀態(tài)度的第三方。”Cooper,212在所有的條件下都是最好的界面可能并不存在,即使在一定的條件下,界面的設(shè)計(jì)仍然是高度主觀的。如果你能開發(fā)出像圖 11.1 所示的新 RealPlayer 那樣的界面,而且符合你的目的,那就很好了。如果你不擅長(zhǎng)創(chuàng)建獨(dú)一無二或非常有趣的圖形用戶界面,而且并沒有雇傭圖形設(shè)計(jì)者的預(yù)算, 那么可能會(huì)開發(fā)出與 WinTel 風(fēng)格類似的應(yīng)用程序。 對(duì)于商業(yè)目的而言,也許較為熟悉的風(fēng)格可以避免使用方面的障礙。圖 11.1 RealPlayer 8 使用了一些漂亮的圖形按鈕,并進(jìn)行了視
3、覺人類工程學(xué)方面的嘗試。還可以選用卡通標(biāo)志和斑馬條紋等外表只有一個(gè)問題不是主觀的,它也是本章的主題,那就是界面應(yīng)該是一致、連貫、完全的。不一致、不連貫、不完全,不考慮界面的風(fēng)格對(duì)用戶來說是不可容忍的。第 11 章示范了一些技術(shù),可用于簡(jiǎn)化開發(fā)并確保一致性,包括如何使用定制組件、組件模板和窗體繼承,以提供一致、連貫而完全的應(yīng)用程序。11.1定制組件創(chuàng)建定制組件很有趣,而且定制組件也很有用。首先,顯而易見的理由是可以重用已有的對(duì)象,并封裝新的或增強(qiáng)的特性;其次,它可以提供一致的效用。無須繪制組件時(shí)保證相同的尺寸、風(fēng)格、字體、顏色或措辭,可以對(duì)組件進(jìn)行定制以確保這些目標(biāo)。定制組件的三個(gè)C定制組件的三
4、個(gè) C 是一致性、連貫性和完備性。一致性意味著組件在你的應(yīng)用程序和其他地方的行為是一致的。一致性( Consistency )組件每次都表現(xiàn)出相同的行為和初始狀態(tài),才能提供一致性。對(duì)組件的行為或狀態(tài)進(jìn)行一次編程,則所有的組件實(shí)例都具有一致的外觀和行為。一致性并不追求數(shù)量,注意到這一點(diǎn)是很重要的。定制組件無須進(jìn)行大量的修改,即可提供一致性。即使組件只是重載了缺省的大小或形狀,創(chuàng)建一個(gè)定制組件也可確保一致性。有兩個(gè)直接的方法可以做到這一點(diǎn)。您可以子類化所有的需要微小修改的組件然后再安裝;或者快速地創(chuàng)建組件模板,這更容易一些(參考11.2 節(jié)“創(chuàng)建組件模板”)。連貫性( Coherency )一致性
5、是連貫的一個(gè)方面。如果對(duì)象不具有一致性,也會(huì)缺少連貫性。連貫性是對(duì)控制流和操作的邏輯性的度量,它要求語義上相似的操作具有一致的行為。定制控件和組件模板可用于提供更為連貫的行為流程。沒有一致性和連貫性,應(yīng)用程序不可能是完全的。完備性( Completeness)不一致、不完全的應(yīng)用程序看起來是不合邏輯且不正確的,這樣必定是不完備的。如果應(yīng)用程序不被用戶群體所接受,也不能說是完備的。完備性度量了應(yīng)用程序是否執(zhí)行了所要求的任務(wù)、結(jié)果是否正確、應(yīng)用程序是否具有合理的容錯(cuò)級(jí)別。如果程序給出正確卻不合時(shí)宜的回答,也是不完備的。而迅速的提供錯(cuò)誤的結(jié)果,仍然是錯(cuò)誤的。如果程序的行為毫無規(guī)律、不一致、或不合邏輯
6、,那么該程序是失敗的。即使程序有相應(yīng)的用戶群體,仍然可能失敗,因?yàn)橛脩羧后w可以拒絕使用該程序,或惡意共謀使用該程序提供錯(cuò)誤的或不合適宜的結(jié)果。為什么組件幫助你走向勝利組件是對(duì)象。每個(gè)對(duì)象都屬于某個(gè)類。這意味著有一組代碼需要測(cè)試、調(diào)試和擴(kuò)展。如果一個(gè)類已經(jīng)是完美的,那么每個(gè)實(shí)例都不會(huì)出錯(cuò)。這樣如果類滿足了 3C 標(biāo)準(zhǔn),那么類的每個(gè)實(shí)例都會(huì)滿足該標(biāo)準(zhǔn)。注意: “大而復(fù)雜的軟件系統(tǒng)需要設(shè)計(jì)師,以便開發(fā)者能夠朝著共同的目標(biāo)前進(jìn)?!盝acobsen,Booch,andRumbaugh62 。設(shè)計(jì)師是這樣的人,他形成解決方案的概念并向程序員說清設(shè)計(jì)意圖。即便開始時(shí)的進(jìn)度比通常慢,也要把事情做正確, 這將會(huì)
7、節(jié)省大量金錢和思考的時(shí)間,防止在最后才發(fā)現(xiàn)出軌。沒有經(jīng)驗(yàn)、缺乏技術(shù)的管理者可能認(rèn)為編寫組件接近于消磨時(shí)間,但這是面向?qū)ο蟮某绦蛟O(shè)計(jì)。以非面向?qū)ο蟮姆椒ㄈナ褂妹嫦驅(qū)ο蠊ぞ呤且粋€(gè)錯(cuò)誤。使用Delphi 編寫結(jié)構(gòu)化程序可以很快地到達(dá)beta 版,這在短期內(nèi)常常會(huì)使管理者高興,但可能使得處于beta 版的時(shí)間較長(zhǎng)。您的程序可能永遠(yuǎn)都脫離不了beta 版。迅速得到錯(cuò)誤的答案,仍然是錯(cuò)誤的。無論是否能確認(rèn)管理層會(huì)花大筆金錢來確保成功,都可以采取一些防御措施。從許多功能正確的組件來創(chuàng)建程序,可以盡可能少寫代碼而又能提高程序的正確性。重分解重分解是采取小的增量式改變的過程。組件可以一步就寫出來,創(chuàng)建全新而獨(dú)一
8、無二的東西,這樣做代價(jià)昂貴、風(fēng)險(xiǎn)較大而且浪費(fèi)時(shí)間;或者我們可以采取小的步驟,分層實(shí)現(xiàn)各種能力,這樣就不那么昂貴,風(fēng)險(xiǎn)較低而且快速。設(shè)計(jì)師的關(guān)鍵作用之一 找到和減少冒險(xiǎn)。如果沒有設(shè)計(jì)師,必須由程序員來完成該工作。管理者喜歡快速而廉價(jià)。那么很清楚,許多情況下最好的選擇就是對(duì)組件進(jìn)行小的修改,將增量式的改變分層添加到已有的組件中。為示范進(jìn)行這種小的修改所需代碼的合理數(shù)量,設(shè)計(jì)了下面的組件:unit UDBShortNavigator;/ UDBShortNavigator.pas - Toggles between short list of buttons/ and long list/ Copy
9、right (c) 2000. All Rights Reserved./ by Software Conceptions, Inc. Okemos, MI USA (800) 471-5890/ Written by Paul KimmelinterfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls,Forms, Dialogs,ExtCtrls, DBCtrls;typeTNavigatorButtonSet = ( nbsFull, nbsPartial );TDBShortNavigator = class(
10、TDBNavigator)private Private declarations FButtonSet : TNavigatorButtonSet;procedure SetButtonSet(const Value: TNavigatorButtonSet); protected Protected declarations public Public declarations published Published declarations property ButtonSet : TNavigatorButtonSet read FButtonSet write SetButtonSe
11、t;end;procedure Register;implementationprocedure Register;beginRegisterComponents(PKTools, TDBShortNavigator);end; TDBShortNavigator procedure TDBShortNavigator.SetButtonSet(const Value:TNavigatorButtonSet);constFULL_SET = nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete, nbEdit, nbPost, nbCance
12、l, nbRefresh;PARTIAL_SET = nbFirst, nbPrior, nbNext, nbLast;SETS : arrayTNavigatorButtonSet of TButtonSet = (FULL_SET,PARTIAL_SET);beginif( FButtonSet = Value ) then exit;FButtonSet := Value;VisibleButtons := SETSFButtonSet;end;end.TDBShortNavigator 繼承了 TDBNavigator ,添加了一個(gè) ButtonSet 特性。將該特性在 nbsFull
13、 和 nbsPartial 之間切換,即可顯示所有的導(dǎo)航按鈕或僅僅顯示基本的四個(gè)按鈕(如圖 11.2 所示)。圖 11.2 TDBShortNavigator 可以快速地在顯示部分或全部導(dǎo)航按鈕之間切換很顯然該組件并沒有多少代碼。而這正是我們所需要的。小的改變快速、便宜而且可靠。然而,有人可能認(rèn)為這是不重要或不相關(guān)的。由混沌理論可知,即使蛾的翅膀振動(dòng)一下也可能影響到很遠(yuǎn)的地方。那么我們可以考慮蛾困在Mark型計(jì)算機(jī)的中繼轉(zhuǎn)換開關(guān)中的情況。據(jù)說是COBOL 的發(fā)明者Grace Hopper 杜撰了 bug 這個(gè)詞,現(xiàn)在整個(gè)工業(yè)界都在使用它,連世界歷史上最重大的媒體事件之一Y2K 問題也是它的標(biāo)志
14、。并不是說上述的導(dǎo)航器子類在歷史上也能有這樣幸運(yùn)的角色;軼事能被記錄本來就是戲劇性的。小的事件能夠發(fā)揮值得記載的作用,并具有相當(dāng)?shù)挠绊?。千里之行,始于足下,高?jí)的系統(tǒng)正是由小塊的優(yōu)質(zhì)代碼所組成的。小的改變有什么好處除了本節(jié)開始所描述的好處之外,還包括快速、廉價(jià)、可靠等等,這些好處都是由小的、增量式的改變得到的。 TDBShortNavigator 這樣的組件有利于代碼的收斂。收斂是指所有該算法的代碼都聚集在一起;如果沒有最好的代碼,那么一個(gè)實(shí)例的代碼是次好的,代碼多于一個(gè)實(shí)例是較差的。發(fā)散是指出現(xiàn)算法的多個(gè)副本;這是最壞的情況。當(dāng)子類化TDBNavigator 這樣的組件來進(jìn)行小的改變時(shí),可以
15、促進(jìn)代碼的收斂。改變可見按鈕數(shù)量的所有代碼都包含在同一個(gè)地方。因此只有一個(gè)代碼段需要測(cè)試、調(diào)試和擴(kuò)展。如果要為按鈕定義三個(gè)狀態(tài),可以在同一地方快速而有效地修改代碼。注意: 您可能聽說過比其他的程序員多產(chǎn)一個(gè)數(shù)量級(jí)的程序員。也就是他個(gè)人的產(chǎn)量是其他人的十倍。這怎么可能呢?很顯然一個(gè)人不可能比程序員的平均打字速度快十倍。這是技巧與策略方面的問題。即使最好的程序員也不太可能在語法和程序編碼方面比平均程度強(qiáng)十倍;他只是使用了一些具有累積效應(yīng)的策略。其中必有一種策略傾向于編寫收斂的代碼。這種程序員可以比一般人快上十倍或更多,而且其代碼也可能好于平均的水平。我們提到過,修改并不重要。重要的是修改表示了什么
16、。像TDBShortNavigator這樣的組件就表明了編寫內(nèi)聚代碼的傾向。這種累積效應(yīng)往往分布在程序員的職業(yè)生涯或工程的生命周期中。采取好的策略編寫收斂的代碼,或編寫的代碼只具有算法的單一副本,這是一個(gè)策略。這可能是成為高產(chǎn)開發(fā)者的最佳途徑之一。有兩個(gè)習(xí)慣可促進(jìn)采用該策略,并逐漸使之成為一種第二天性。首先:考慮多次修改你的代碼。我們知道諺語“天才是1%的靈感加99%的汗水”,這意味著當(dāng)一個(gè)人思考解決方案時(shí),只有出現(xiàn)了非常好的機(jī)會(huì),靈感才能發(fā)揮作用。其次:當(dāng)發(fā)現(xiàn)重復(fù)出現(xiàn)的代碼時(shí),立即把涉及到的算法編寫為過程。隨著實(shí)踐的進(jìn)行,這種迭代式的修改會(huì)變得更加自然,如果隨時(shí)進(jìn)行修改,也更容易發(fā)揮作用。反
17、之,如果等到程序完成之后才進(jìn)行修改工作,可能會(huì)遇到困難。管理者和其他程序員可能不想立即投入很多時(shí)間進(jìn)行修改,而這時(shí)代碼已經(jīng)相互糾纏在一起以至于小的修改也可能引起代碼的混亂。組件化我們就繼續(xù)討論上一節(jié)的問題,如果你發(fā)現(xiàn)自己正在編寫處理組件內(nèi)部數(shù)據(jù)的代碼,那么最好子類化組件以封裝新的行為。 組件化的規(guī)則是: 如果代碼涉及到組件內(nèi)部的數(shù)據(jù),例如組件所擁有的對(duì)象列表,那么代碼實(shí)際上描述了組件的行為。對(duì)象的行為就是方法。通過將外部的、隱式的算法提升為方法,可以使代碼在類的層次上趨向于收斂。類不一定是組件;任何表示類行為的代碼都應(yīng)該作為方法合并到類中。有三個(gè)地方可以方便地重用代碼??梢宰宇惢ńM件在內(nèi)的
18、任何類,以重用代碼??梢远x組件模板,這是 Delphi 新近添加的功能,利用該方法可以很容易地在一個(gè)或多個(gè)組件中重用新的行為;而且能夠創(chuàng)建窗體或框架模板,這樣就可以重用整個(gè)窗體或框架及其所包含的組件。11.2創(chuàng)建組件模板首先將組件添加到數(shù)據(jù)模塊或窗體,設(shè)置它們的特性,創(chuàng)建事件處理程序,并編寫代碼。然后選定一個(gè)或多個(gè)組件,從 Component 菜單里選擇 Create Component Template 菜單項(xiàng)。所有被選中的組件、 事件處理程序、 以及相關(guān)的代碼, 都添加到了 VCL 面板的 Template 屬性頁上。選擇該組件模板并將其拖動(dòng)到任意的窗體或數(shù)據(jù)模塊上,即可重新創(chuàng)建包括代碼
19、在內(nèi)的各個(gè)組件。將模板添加到窗體或數(shù)據(jù)模塊后,可以修改其位置、大小和特性等,就像是分別添加的一樣。當(dāng)選擇 Create Component Template 菜單項(xiàng)時(shí), 會(huì)顯示 Component Template Information 對(duì)話框(見圖 11.3)。點(diǎn)擊 OK ,則接受缺省的組件名、面板屬性頁以及組件圖標(biāo),當(dāng)然也可以修改這些信息。 可以給模板組件命名所喜歡的名字, 將其放置在任何面板屬性頁上。如果輸入的屬性頁名字不存在, Delphi 將創(chuàng)建新的屬性頁。模板組件惟一的限制就是其圖標(biāo)必須是 24 24 像素位圖,與其他組件的圖標(biāo)類似。圖 11.3Component Templat
20、e Information 對(duì)話框定義組件模板編寫基本的組件相當(dāng)容易。創(chuàng)建組件模板甚至更容易。定義組件模板的步驟與創(chuàng)建窗體基本相同。增加組件,修改其特性,并編寫事件特性。像其他單元一樣,對(duì)窗體(或數(shù)據(jù)模塊)進(jìn)行單元測(cè)試。工作完成后,就可以創(chuàng)建組件模板,選擇組件,并將其添加到組件模板。注意: Delphi 組件模板存儲(chǔ)在Delphi 的 Bin 目錄下的二進(jìn)制文件Delphi.dct中。 Windows錯(cuò)誤地把該文件和FoxProDataBaseContainer文件類型關(guān)聯(lián)在一起??紤]第 3 章的 Edit 程序中對(duì) Edit 菜單編寫菜單。您可以花費(fèi)一些時(shí)間來查找所有的 Windows Se
21、ndMessage 代碼;而下一次在另一個(gè)程序里創(chuàng)建消息,并在應(yīng)用Edit 菜單時(shí),您還得做同樣的事情。從菜單資源模板重新創(chuàng)建菜單您可以選擇使用Insert Template 對(duì)話框中的Edit菜單,如圖11.4 所示。使用MenuDesigner 上下文菜單添加一個(gè)菜單的步驟如下:圖 11.4 Insert Template 對(duì)話框可以從存儲(chǔ)的資源中重新創(chuàng)建菜單。但并不包括代碼1從 VCL 的 Standard 屬性頁上選擇MainMenu 組件。2雙擊 MainMenu 圖標(biāo)向窗體添加菜單。3右擊MainMenu組件,顯示TMainMenu組件的組件編輯器菜單,并選擇MenuDesigne
22、r 菜單項(xiàng)(如圖11.5 所示)。這樣可以打開菜單編輯器,如圖11.4 的背景所示。4右擊鼠標(biāo),打開菜單編輯器的上下文菜單,并選擇Insert From Template 菜單項(xiàng),如圖 11.6 所示。5從 Insert Template 對(duì)話框中(如圖 11.4 所示),雙擊 Edit 菜單模板,以添加編輯菜單。這就是所有的工作。上述五個(gè)步驟將把 TMenuItem 組件添加到窗體類定義的開頭。使用菜單資源模板需要對(duì) OnClick 事件方法重新編寫代碼。更好的方法是使用組件模板,這可以包括代碼。圖 11.5點(diǎn)擊 TMainMenu 組件的組件編輯器菜單上的Menu Designer 菜單項(xiàng)
23、圖 11.6菜單設(shè)計(jì)器的上下文菜單,對(duì)于管理菜單資源模板很方便創(chuàng)建并安裝菜單組件模板組件模板是Delphi 新增的功能。使用菜單資源模板存儲(chǔ)菜單必須重新編寫代碼,而使用組件模板則不必如此。還使用上一節(jié)提到的 Edit 菜單,它是在第 3 章中實(shí)現(xiàn)的。我們現(xiàn)在把整個(gè)菜單和代碼都保存為組件模板。1對(duì) Edit 菜單編寫代碼(使用第3 章的例子,或步驟后列出的代碼)使控件呈現(xiàn)正確的行為。2用代碼測(cè)試Edit 菜單后,選擇包含Edit 菜單的 TMainMenu 組件并點(diǎn)擊Component| Create Component Template 菜單項(xiàng)。procedure TForm1.Edit1Cl
24、ick(Sender: TObject);begin/ CanUndo testUndo1.Enabled := Boolean(SendMessage(EM_CANUNDO, 0, 0 );end;procedure TForm1.Copy1Click(Sender: TObject);begin/ Copy menuprocedure TForm1.Cut1Click(Sender: TObject);begin/ Cut menuprocedure TForm1.Paste1Click(Sender: TObject);begin/ Paste menuend;procedure TFo
25、rm1.SelectAll1Click(Sender: TObject);begin/ select all textend;procedure TForm1.Undo1Click(Sender: TObject);begin/ Undo menuend;該代碼與第3 章中的類似。因此我們不再對(duì)細(xì)節(jié)進(jìn)行重復(fù)。現(xiàn)在我們已經(jīng)有了Edit菜單的組件模板,每次需要菜單、相應(yīng)的菜單項(xiàng)和代碼時(shí)就可以使用該模板。使用組件模板菜單現(xiàn)在已經(jīng)有了Edit 菜單模板,它可以像其他的組件一樣使用。要使用組件模板,從Template 屬性頁上選擇對(duì)應(yīng)的模板,像其他菜單一樣拖動(dòng)到窗體上。菜單組件及其擁有的TMenuIte
26、ms 、以前寫過的代碼都可以添加到任何窗體上,而無需測(cè)試,也不會(huì)產(chǎn)生任何混亂的情況。擴(kuò)展組件模板可以把組件模板看作組件類。當(dāng)創(chuàng)建組件模板時(shí)(如本節(jié)的前半部分的Edit 菜單),不要?jiǎng)h除它,當(dāng)需要新的行動(dòng)時(shí),可以對(duì)該模板進(jìn)行擴(kuò)展。添加新的行為可以擴(kuò)展已有的組件,最后我們有原來的和新的組件模板。假設(shè)現(xiàn)在有Edit 菜單,要對(duì)其定義Find 菜單項(xiàng)。使用組件面板的Dialogs 屬性頁上的TFindDialog 組件。按照下列步驟,即可添加Find 功能并創(chuàng)建新的組件模板。1把在本節(jié)開頭保存的模板拖動(dòng)到任意的窗體上。2從 Dialogs 屬性頁上拖動(dòng)TFindDialog 組件到同一個(gè)窗體。3在窗體
27、上,點(diǎn)擊Edit , Find 菜單項(xiàng),并添加代碼FindDialogl.Execute 。4為 TFindDialog.OnFind 事件添加事件方法, 并向事件處理程序添加一些代碼以提醒用戶實(shí)現(xiàn)查找行為。5選擇TMainMenu組件和FindDialog組件并單擊Component| Create ComponentTemplate菜單項(xiàng),把合并的控件和代碼添加到template屬性頁。TFindDialog組件可能的代碼如下。procedure TForm1.Find1Click(Sender: TObject);beginFindDialog1.Execute;end;procedur
28、e TForm1.FindDialog1Find(Sender: TObject);beginMessageDlg( Implement find behavior!, mtInformation, mbOK, 0 );end;警告: 當(dāng)存儲(chǔ)模板組件時(shí),確保使用惟一的名字。如果你使用已有的名字,那么 Delphi將提示你是否替換已有的模板,包括代碼在內(nèi)。這就是所需要的工作。通過將代碼分層添加到模板中,可以對(duì)完整的組件群體和提供功能的代碼創(chuàng)建精致的接口。然而使用組件面板也有一些缺點(diǎn)。組件面板并非真正的組件;它們只是寫入到二進(jìn)制文件 Delphi.dct 中的文本。它們提供了方便,但卻放棄了靈活性
29、?;貞泴?duì) SelectAll 菜單項(xiàng)的前一個(gè)實(shí)現(xiàn)。第 3 章開始部分列出的代碼中顯示的 ToDo 表明,事件方法需要進(jìn)行修改才能對(duì)其他類型控件做出合適的響應(yīng)。 在 SelectAll 當(dāng)前的實(shí)現(xiàn)中, 是無法響應(yīng) TComboBox 之類的控件的。不幸的是,如果你返回來完成 SelestAll 行為,可以創(chuàng)建新的模板。但這對(duì)包含菜單和 Find 對(duì)話框的復(fù)合模板沒有影響。原來模板不會(huì)有什么改變,衍生的模板將繼續(xù)使用 SelectAll 的舊版本。如果模板代碼能夠繼承,而且可以自動(dòng)更新有依賴關(guān)系的面板,那就太好了,但這并不是面向?qū)ο蟮睦^承,而是一種新型的資源流化機(jī)制。如果需要繼承,那就要?jiǎng)?chuàng)建新的類
30、并進(jìn)行子類化。但組件模板仍然是一種流行的方法,只會(huì)變得更好而已。對(duì)于可視化的建立多數(shù)或全部組件這個(gè)目標(biāo)來說,我們已經(jīng)不遠(yuǎn)了。刪除組件模板Component Templates包含在 Delphi.dct 文件中。該文件不像其他的組件庫,它并非軟件包的庫文件。因此無法像管理其他組件一樣管理組件目標(biāo)。為刪除組件目標(biāo),需要在組件面板上找到對(duì)應(yīng)的位置,并組件面板上下文菜單中點(diǎn)擊Properties 菜單項(xiàng)。參考圖11.7,從右邊的組件列表里選取要?jiǎng)h除的模板組件,然后點(diǎn)擊Delete 按鈕。圖 11.7 Palette Properties 對(duì)話框可用于刪除組件模板或隱藏組件提示:你不會(huì)意外地從圖11.
31、7 所示的Palette Properties對(duì)話框中刪除組件。如果選定了某個(gè)組件,Add 按鈕右側(cè)將出現(xiàn)一個(gè)Hide按鈕; 而如果組件實(shí)際上是一個(gè)模板,那么同一位置就出現(xiàn)Delete 按鈕。組件模板不同于組件,使用圖 11.7 所示的 Palette Properties 對(duì)話框只能隱藏組件。如果你刪除組件模板,也會(huì)刪除所有與之相關(guān)聯(lián)的代碼。把組件模板中的代碼保存到外部文件是個(gè)好主意,以防止意外刪除。關(guān)于組件模板的最后一個(gè)問題。 組件模板方便且易于使用, 但并非實(shí)際的組件。 以 Edit 菜單為例,模板比簡(jiǎn)單的資源菜單使用起來更加方便。雖然可以創(chuàng)建精巧的模板,但從長(zhǎng)遠(yuǎn)看來,將復(fù)雜的代碼和相互
32、交織的組件關(guān)系封裝到類的話將更為可取。11.3窗體模板與窗體繼承與組件模板相比,窗體模板出現(xiàn)得更早一些。我們知道窗體是由TComponent 子類化而來,但如果將窗體直接安裝到VCL 中,可能會(huì)出現(xiàn)不正確的行為;因此在Delphi的早期版本里發(fā)明了窗體模板來解決這個(gè)問題(更多的信息請(qǐng)參見第10 章的對(duì)話框組件部分) 。很快發(fā)現(xiàn),窗體一般帶有許多代碼,而且大多數(shù)應(yīng)用程序里會(huì)重復(fù)出現(xiàn)許多類型的窗體,很顯然的一個(gè)例子就是About對(duì)話框。 幾乎所有應(yīng)用程序都有該對(duì)話框。但只是意外DFM文件與VCL無法很好的協(xié)作,就需要開發(fā)者為每個(gè)應(yīng)用程序繪制一個(gè)About框并且添加必要的代碼來顯示該窗體嗎?答案是,
33、你不必如此。最后,我們可以把窗體添加到存儲(chǔ)庫中,存儲(chǔ)庫中的窗體可以直接使用、繼承和復(fù)制。注意: 在技術(shù)上,與窗體繼承相關(guān)的最大的困難可能就是,如何使DFM流機(jī)制正確地工作。為了深入了解DFM 流化機(jī)制, 看第 10 章的“對(duì)象流化與窗體繼承”一節(jié)。窗體繼承機(jī)制現(xiàn)在已經(jīng)工作得很好了。對(duì)于開發(fā)者來說,所有這些意味著又添加了一個(gè)強(qiáng)有力的方法來重用整個(gè)程序。下面的方法都可以促進(jìn)代碼與界面設(shè)計(jì)的重用,包括保存菜單資源,創(chuàng)建組件模板,將窗體添加到存儲(chǔ)庫并重用;當(dāng)然最強(qiáng)大的方法是創(chuàng)建新類。創(chuàng)建窗體模板窗體模板是保存并添加到存儲(chǔ)庫的窗體。在上一節(jié)中,我們還記得一個(gè)包含TMainMenu 組件的窗體, 其中有編
34、輯菜單,還包括查找功能; 我們把窗體添加為組件模板。通過把窗體添加到存儲(chǔ)庫中,然后把組件模板放置到窗體上,即可迅速地啟動(dòng)一個(gè)主窗體。向存儲(chǔ)庫添加窗體為實(shí)驗(yàn)創(chuàng)建窗體模板的過程,我們將包含TMainMenu 和 TFindDialog 的組件模板添加到空 白窗體上(如果你在上一節(jié)中沒有創(chuàng)建組件模板而還想繼續(xù)的話,只能先把TMainMenu和 TFindDialog 組件拖動(dòng)到空白窗體上)。按照下列步驟,可以將窗體添加到存儲(chǔ)庫(見圖11.8)。圖 11.8 MainForm 模板,其中包含 TMainMenu 和 TFindDialog 組件1右擊要添加為模板的窗體,以顯示窗體設(shè)計(jì)器上下文菜單。2選
35、擇 Add to Repository 菜單項(xiàng)。3填寫 Add To Repository 對(duì)話框,需要為模板窗體提供標(biāo)題和描述(見圖11.8),并選擇要加入的屬性頁,輸入作者信息和圖標(biāo)。4點(diǎn)擊OK按鈕。如果尚未保存文件,在添加到存儲(chǔ)庫之前Delphi將提示你保存文件。如果向Add To Repository對(duì)話框中的Page 組合框文本域中輸入并不存在的屬性頁名,Delphi將創(chuàng)建新的屬性頁。這是一個(gè)對(duì)窗體模板進(jìn)行組織的好方法?,F(xiàn)在,無論何時(shí)需要帶有主菜單的窗體,其中包括編輯和查找功能,只需選擇New ,Other 菜單項(xiàng),然后從 New Items 對(duì)話框的Forms 屬性頁上選擇對(duì)應(yīng)模板
36、(見圖File,11.9)。圖 11.9從 New Items 對(duì)話框選擇與目標(biāo)最為接近的窗體目標(biāo)存儲(chǔ)庫的維護(hù)大多數(shù)人都有一個(gè)用于存放物品的地方。存儲(chǔ)庫就是個(gè)存放物品的地方。最后您可能需要對(duì)存儲(chǔ)庫中的目標(biāo)重新進(jìn)行組織或刪除某些模板。Tools 菜單有一個(gè)Repository 菜單項(xiàng),可以打開Object Repository 對(duì)話框(見圖11.10)。對(duì)話框的左側(cè)列出了所有可以修改的 Repository 屬性頁, 包括 Forms 屬性頁, 其中有用戶定義窗體模板的。像 New 和 ActiveX等屬性頁是不可修改的。要增加、 刪除、重新命名符合條件的屬性頁,只需選擇相應(yīng)的屬性頁并點(diǎn)擊Add
37、 Page、Delete Page、Rename Page 中某個(gè)合適的按鈕。要從Objects 列表中編輯或刪除某個(gè)模板,在左側(cè)選擇包含該模板的頁并在右側(cè)的Objects 列表中點(diǎn)擊相應(yīng)的模板。例如要?jiǎng)h除上一節(jié)定義的 FormMain 模板,首先點(diǎn)擊左側(cè)Pages 列表框中的Forms 項(xiàng)。所有的窗體模板將在右側(cè)的 Objects 列表框中列出。找到MainForm 模板,單擊以選取它并點(diǎn)擊Delete Object按鈕(如圖11.10 所示,選定了Main Form 窗體)。圖 11.10Object Repository對(duì)話框NEW FORM也可以在Object Repository 中
38、選擇缺省的New Form 復(fù)選框, 用于表示在 Delphi 中點(diǎn)擊 File| New | Form 菜單項(xiàng)時(shí)將創(chuàng)建哪個(gè)窗體。缺省情況下并未選定NewForm 復(fù)選框,但很容易就可以將FormMain 作為默認(rèn)的新窗體(選取窗體的指令,請(qǐng)參見前面的章節(jié))。選取窗體后,選定圖11.10 所示的 New Form 復(fù)選框并點(diǎn)擊OK 按鈕。MAIN FORM當(dāng)創(chuàng)建新的可執(zhí)行應(yīng)用程序時(shí)例如當(dāng)Delphi 啟動(dòng)時(shí)缺省情況下主窗體是空白窗體。 另外,你還可以在Delphi中點(diǎn)擊 Tools | Repository 菜單項(xiàng)打開ObjectRepository 對(duì)話框。當(dāng)存儲(chǔ)庫被打開后, 選取所需的新窗
39、體作為主窗體并選定Main Form復(fù)選框(如圖 11.10 所示)。這樣,每次創(chuàng)建新應(yīng)用程序時(shí),將使用該窗體作為缺省的主窗體。向存儲(chǔ)庫添加工程可以將整個(gè)的工程添加到存儲(chǔ)庫。完整的工程由工程中的DPR 文件、所有的源代碼、窗體和數(shù)據(jù)模塊組成。如果要把一個(gè)或多個(gè)窗體定義為工程模板,可以使用Project 菜單將工程添加到存儲(chǔ)庫。要向存儲(chǔ)庫添加工程,首先選擇要添加工程,然后點(diǎn)擊Project | Add toRepository 菜單項(xiàng)。這時(shí)將顯示Add to Repository 對(duì)話框,它與窗體模板的情形類似(見圖 11.8),由于將添加所有窗體,所以不需要選擇添加哪個(gè)窗體。將工程添加到存儲(chǔ)庫
40、后, 點(diǎn)擊 File | New | Other 菜單項(xiàng), 然后從 New Items 對(duì)話框中選擇所需的工程,即可基于已有的工程啟動(dòng)一個(gè)新的工程??捎糜诜胖霉こ棠0宓暮玫胤绞?Projects 屬性頁,盡管在添加工程時(shí)也可以創(chuàng)建新的屬性頁。提示:如果要把缺省的工程從標(biāo)準(zhǔn)的可執(zhí)行程序改變?yōu)榇鎯?chǔ)庫中的某個(gè)工程,那么可以從Tools 菜單中打開對(duì)象存儲(chǔ)庫,并將相應(yīng)的工程設(shè)置為新的缺省工程。選定一個(gè)工程后,Objects 列表框下將出現(xiàn)New Project復(fù)選框。 選定該復(fù)選框,則對(duì)應(yīng)的工程將成為新的缺省工程。當(dāng)從 New Items 對(duì)話框中選擇一個(gè)工程模板時(shí), Delphi 將提示您為該工程輸
41、入路徑,這時(shí) Delphi 相應(yīng)創(chuàng)建該工程中所有的文件。要避免選擇創(chuàng)建工程模板時(shí)的原始路徑;如果這樣做你將覆蓋原來的存儲(chǔ)庫文件。也可以從Object Repository對(duì)話框中刪除工程模板。細(xì)節(jié)請(qǐng)參考前面,標(biāo)題為“存儲(chǔ)庫的維護(hù)”一節(jié)。使用模板窗體當(dāng)使用模板創(chuàng)建新窗體時(shí),有三種選擇??梢栽贜ew Items 對(duì)話框的Forms 屬性頁上選擇 Copy 、Inherit 或 Use 三者之一。缺省情況下,將選擇Copy 。您可以得到窗體的完整副本,但不會(huì)維護(hù)模板窗體與新窗體之間的進(jìn)一步的關(guān)系(如果選擇Use,那么實(shí)際上將修改存儲(chǔ)庫中的窗體模板;即,任何改變都會(huì)反映到窗體在存儲(chǔ)庫中的版本)。如果選
42、擇Inherit ,將繼承模板窗體,這里的繼承指的是面向?qū)ο蟮囊饬x。對(duì)窗體在存儲(chǔ)庫中版本的改變將反映到子窗體。考慮到主窗體含有Edit 菜單和 Find 對(duì)話框。 如果使用某個(gè)主窗體模板創(chuàng)建新的窗體,新窗體將子類化那個(gè)窗體。以后,再選擇該主窗體模板以及 Use 選項(xiàng),添加一個(gè)Replace 對(duì)話框,則所有的子窗體在下次編譯時(shí)將自動(dòng)具有Replace行為。由 DFM文件的內(nèi)容可以看出原始窗體、副本窗體、以及使用模板窗體創(chuàng)建的子窗體之間的不同。下面的片斷來自三個(gè)獨(dú)立的DFM 文件,分別演示了基于Use、Inherit 、Copy方式創(chuàng)建窗體時(shí)數(shù)據(jù)寫入DFM 文件的方式。這三個(gè)窗體都與窗體類TFor
43、mMain有關(guān)。object FormMain: TFormMainLeft = 435Top = 254Width = 418Height = 320Caption = Application Title Here上面列出的是實(shí)際的窗體。當(dāng)在 New Items 對(duì)話框的 Forms 屬性頁中選擇 Use 時(shí),將得到模板窗體。object FormMain1: TFormMain1Left = 435Top = 254Width = 418Height = 320Caption = Application Title Here當(dāng)選擇該窗體是從Copy 時(shí),得到的是TFormMain1 ,看上
44、去像是TFormMainTForm 子類化而來。所擁有的組件都被復(fù)制并流化到DFM的子類,但實(shí)際上文件中,但在模板和窗體副本之間不存在更進(jìn)一步的關(guān)系。inherited FormMain4: TFormMain4Caption = FormMain4PixelsPerInch = 120TextHeight = 16end上面列出的DFM 文件是從TFormMain 繼承時(shí)創(chuàng)建的。與前面的兩個(gè)DFM 文件不同,第一個(gè)詞不是object,而是 inherited 。這是個(gè)約定, 用于表示應(yīng)從祖先窗體讀取額外的流化信息。當(dāng)要對(duì)所有的祖先都作出持久性的改變時(shí),可修改原始窗體。若希望父窗體與子窗體之間
45、的改變互不影響,應(yīng)使用復(fù)制;如果要對(duì)窗體的行為與外觀在整個(gè)家族中定義并維護(hù)一個(gè)核心集合,則應(yīng)使用繼承。組件模板、窗體模板、工程模板是三種極好的方法,可用于在一組應(yīng)用程序中維護(hù)工程內(nèi)和工程間的一致性。一致性是連貫性的一個(gè)因素。即使應(yīng)用程序提供了某些前所未見的功能,如果交互界面是一致的,那么經(jīng)過適當(dāng)?shù)膶W(xué)習(xí)之后新的任務(wù)看起來也會(huì)更加連貫。在應(yīng)用程序被認(rèn)為具有完備性之前,它首先必須是一致和連貫的。另外,完備性還需要程序能夠合乎用戶的需求。11.4靜態(tài)與動(dòng)態(tài)的組件用法當(dāng)把窗體添加到應(yīng)用程序時(shí),將把一行代碼加入到DPR文件(工程源文件)中,以便在程序啟動(dòng)時(shí)自動(dòng)創(chuàng)建窗體。Application.Create
46、Form(TForm1, Form1);對(duì)于 Visual Basic 程序員或尚未完全掌握對(duì)象及動(dòng)態(tài)對(duì)象創(chuàng)建的用法的新程序員來說,這可以使得添加和使用窗體更為容易。對(duì)外行人來說, 這實(shí)際上使得Delphi 和 Visual Basic看起來很相似:創(chuàng)建窗體、運(yùn)行程序、調(diào)用show 或 show modal,然后用戶就可以使用窗體了。當(dāng)在窗體上繪制組件時(shí),也是同樣。好像是有魔力一樣,它們?cè)谶\(yùn)行時(shí)出現(xiàn)時(shí),自然的就具有設(shè)計(jì)時(shí)的狀態(tài)以及任何由自己編寫的代碼所定義的行為。Delphi 與 Visual Basic 之間的相似性在這里結(jié)束了。與 Visual Basic相比,Object Pascal(
47、 Delphi 的語言) 與 C+ 更為相似。 Delphi 像 Visual Basic 一樣易于使用, 并具有 C+ 的強(qiáng)大功能。這意味著新的程序員也能立即開始,而經(jīng)驗(yàn)豐富的老手則能夠創(chuàng)建非常復(fù)雜的應(yīng)用程序。Delphi 自動(dòng)創(chuàng)建窗體或在運(yùn)行時(shí)自動(dòng)創(chuàng)建組件時(shí),其行為是一致的。而且,已經(jīng)對(duì)流化機(jī)制編碼,知道如何解析組件引用、從 DFM 文件里讀出屬性、構(gòu)造對(duì)象。當(dāng) Delphi 自動(dòng)創(chuàng)建窗體和組件時(shí),與手工使用代碼來創(chuàng)建的方式是一致的。動(dòng)態(tài)創(chuàng)建窗體到現(xiàn)在為止,您可能已經(jīng)熟悉如何繪制程序所擁有的窗體了。有些程序員允許自動(dòng)創(chuàng)建所有的窗體,但這會(huì)使可執(zhí)行文件變得相當(dāng)大并降低程序的啟動(dòng)速度。大多數(shù)用
48、戶通常只使用某些核心功能,從來或很少使用其他功能。最終結(jié)果是用戶為一些從不使用的功能付出了性能方面的代價(jià)。好一些的方法是在需要的時(shí)候才創(chuàng)建窗體、數(shù)據(jù)模塊以及加載庫。這實(shí)際上是通過推遲堆內(nèi)存的分配以及窗體流數(shù)據(jù)的讀取,以便降低程序啟動(dòng)時(shí)一次性創(chuàng)建窗體的成本,該技術(shù)有個(gè)名字,可以稱之為惰性實(shí)例化(lazy instancing )。在 Project Options 對(duì)話框的Forms 屬性頁中,將窗體和數(shù)據(jù)模塊從auto create 欄移動(dòng)到 available 欄,即可推遲窗體的創(chuàng)建。雖然在啟動(dòng)時(shí)性能有所提高,但以后在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建窗體是要付出代價(jià)的;除非該功能對(duì)時(shí)間要求非常高或經(jīng)常使用,否
49、則在需要時(shí)動(dòng)態(tài)創(chuàng)建窗體比一次性創(chuàng)建所有的窗體更為可取。有兩種技術(shù)可用于創(chuàng)建惰性實(shí)例,分別討論如下。顯式構(gòu)造顯式構(gòu)造是指調(diào)用窗體構(gòu)造函數(shù)創(chuàng)建窗體,如何使用窗體,最后釋放創(chuàng)建窗體所用的內(nèi)存。Form := TForm.Create(self);tryif( Form.ShowModal = mrOK ) then/ doe herefinally Form.Free;end;如果把窗體作為模式對(duì)話框來顯示, 該技術(shù)工作得很好, 因?yàn)樵谡{(diào)用 ShowModal 時(shí)代碼的運(yùn)行是同步的。只要關(guān)閉窗體,內(nèi)存也就被釋放了。另外,您也可以顯示窗體并讓窗體在關(guān)閉時(shí)自行釋放內(nèi)存。TForm.Create(Self).Show;被創(chuàng)建的窗體需要一個(gè) OnClose 事件處理程序,以便進(jìn)行一些設(shè)置,這樣當(dāng)窗體關(guān)閉時(shí)它可以將自身從內(nèi)存中釋放出去。procedure TForm1.FormClose(Sender: TObject; var Action:TCloseAction);begi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年綠色照明項(xiàng)目合作計(jì)劃書
- 2025年絲絹紡織及精加工產(chǎn)品項(xiàng)目建議書
- 五年級(jí)數(shù)學(xué)(小數(shù)乘除法)計(jì)算題專項(xiàng)練習(xí)及答案
- 三年級(jí)數(shù)學(xué)計(jì)算題專項(xiàng)練習(xí)及答案集錦
- 右肺低分化腺癌護(hù)理查房
- 陜西青年職業(yè)學(xué)院《藥學(xué)專業(yè)創(chuàng)新創(chuàng)業(yè)拓展》2023-2024學(xué)年第二學(xué)期期末試卷
- 集寧師范學(xué)院《物流管理前沿講座》2023-2024學(xué)年第一學(xué)期期末試卷
- 集美大學(xué)誠毅學(xué)院《英語視聽說(四)》2023-2024學(xué)年第二學(xué)期期末試卷
- 青島工學(xué)院《機(jī)能實(shí)驗(yàn)學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 青島幼兒師范高等??茖W(xué)?!督ㄖo水排水》2023-2024學(xué)年第一學(xué)期期末試卷
- T-CSOE 0003-2024 井下套管外永置式光纜安裝要求
- 合肥鼎材科技有限公司光阻車間光刻膠生產(chǎn)線技術(shù)改造項(xiàng)目環(huán)評(píng)報(bào)告書
- 北師大版(2024)七年級(jí)下冊(cè)生物第6章 人體的營養(yǎng) 學(xué)情評(píng)估測(cè)試卷(含答案解析)
- 2025體育單招英語備考100個(gè)高頻名詞精講(精校打印版)
- 9.1.2 用坐標(biāo)描述簡(jiǎn)單幾何圖形(課件)-2024-2025學(xué)年新教材七年級(jí)下冊(cè)數(shù)學(xué)
- 精神科敘事護(hù)理案例分享
- 數(shù)學(xué)教師個(gè)人發(fā)展規(guī)劃
- 金屬加工機(jī)械制造行業(yè)分析報(bào)告
- 2025年陜西延長(zhǎng)石油集團(tuán)礦業(yè)公司招聘筆試參考題庫含答案解析
- 《論民本課件》課件
- 塔吊司機(jī)安全培訓(xùn)
評(píng)論
0/150
提交評(píng)論