[發(fā)表于2002年第11/12期《電腦報(bào)》軟件星空版,,連載兩期。]
“聰明的程序員用Delphi,!”現(xiàn)在,,真是有越來(lái)越多的人開始用Delphi了。不過(guò),,高手畢竟是少數(shù),,像我這樣的菜鳥可謂遍地都是,,哈哈,。既然是菜鳥自然就有一大堆很菜的問(wèn)題,什么這個(gè)怎么設(shè)置,、那個(gè)怎么寫的……所以,,以下我就以我所積累的那一點(diǎn)點(diǎn)經(jīng)驗(yàn)和論壇上常見的小問(wèn)題作一個(gè)總結(jié)性發(fā)言(全場(chǎng)熱烈鼓掌!哎,,這鮮花我就收下了,,那個(gè)什么爛番茄就不要扔上來(lái)了嘛)
==系統(tǒng)應(yīng)用篇==
A.Delphi自代了大量的常用控件,如Delphi5就有一百多了,,而今年出的Delphi6更是Delphi5的1.5倍,。這么多控件,就是在1024*768的分辨率下也無(wú)法全部顯示他們的組件面板,,而每次要按那兩顆小按鈕來(lái)顯示更多的面板,,真是非常不方便!但通過(guò)添加下面那一個(gè)注冊(cè)表鍵值就能實(shí)現(xiàn)組件面板自動(dòng)展開:
[HKEY_CURRENT_USER\Software\Borland\Delphi\X.0\Extras]
"AutoPaletteSelect"="1"
(注:X.0表示你的Delphi的版本號(hào),;如果沒(méi)有Extras主鍵則新建即可,,下同)
B.每次新建窗體,然后設(shè)置其字體、大小……真是好麻煩的,!那就再添加一個(gè)以下的鍵值,,讓系統(tǒng)自動(dòng)來(lái)設(shè)置吧:
[HKEY_CURRENT_USER\Software\Borland\Delphi\X.0\FormDesign]
"DefaultFont"="宋體,9,_"
(注:_表示空格,也可以用Bold(粗體)等代替)
C.自定義工作環(huán)境,,讓它更加適合自己,。
•設(shè)置工具欄。在Delphi的工具欄右鍵單擊,,選Customize,,然后挑選需要的按鈕拖到工具上,把不要的拖出來(lái),。我常用的是:Standard工具欄下的Open,、Open Project、Save,、Save All,、Undo、Redo,;Debug工具欄下的Pause,、Add Watch、Program Reset,、Run,;Desktop工具欄下的Save Current Desktop、Set Debug Desktop,;Component Palette工具欄,。
•設(shè)置窗口布局。為了能跟高效的編寫程序,,合理的布置各個(gè)窗口是很重要的,。我常用的窗口有:Object Inspector、Project Manager(View|Project Manager),、Watch List(Run|Add Watch...) ,,具體的停放位置如圖1。
[圖1]
設(shè)置好各個(gè)窗體后按Desktop工具欄上的Save Current Desktop按鈕保存,。
•設(shè)置顯示顏色,。讓代碼的顏色更符合自己的習(xí)慣,有利于編寫時(shí)思維的清晰,。Tools|Editor Options打開Editor Properties,,選Color標(biāo)簽頁(yè),設(shè)置代碼顏色,。以下僅解釋一下幾個(gè)常用的:
Whitespace:空白處,,即背景,;
Comment:注釋;
Reserved word:保留字,;
String:字符串,;
Number:數(shù)字;
Execution Point:正在執(zhí)行的當(dāng)前行(即F7步入時(shí)所到達(dá)的那一行),;
Enabled break:斷點(diǎn),;
Error line:錯(cuò)誤發(fā)生行;
D.掌握一些Delphi編程中的快捷鍵,,能夠極大程度的提高效率,,還不會(huì)讓你因?yàn)檫^(guò)多無(wú)聊的設(shè)置等而感到厭煩,現(xiàn)在如果不用這些快捷鍵,,我會(huì)很不適應(yīng)這樣的編程的,!以下我就介紹一下我常用的幾個(gè)快捷鍵:
Esc : 選擇當(dāng)前選中組件的容器(通常是Panel,GroupBox或Form等);
Ctrl+方向鍵 :將所選組件移動(dòng)一個(gè)像素,;
Ctrl+Shift+方向鍵 :將所選組件移動(dòng)一大格(類似Fireworks中按住Shift再用方向鍵移動(dòng)時(shí)的效果),;
Shift+方向鍵 :調(diào)整選中組件的大小,每次一像素,;
Shift+選中組件 :按住Shift鍵再用鼠標(biāo)點(diǎn)擊組件,,可以同時(shí)選擇多個(gè)組件;
Ctrl+鼠標(biāo)左鍵 :在procedure中掉用其他的函數(shù)(如一個(gè)自定義的過(guò)程),,在這個(gè)調(diào)用處按住Ctrl會(huì)發(fā)現(xiàn)當(dāng)鼠標(biāo)移上去的時(shí)候變成了一個(gè)類似超鏈接的格式,,鼠標(biāo)單擊就能直接轉(zhuǎn)到所調(diào)用的此函數(shù)的實(shí)現(xiàn)部分。這個(gè)功能我可是用的最多了,,讓我找模塊變得非常方便,!
Ctrl+Shift+C :在一個(gè)對(duì)象中聲明了一個(gè)方法,然后把光標(biāo)放到它的上面,,按下Ctrl+Shift+C就可以為他的實(shí)現(xiàn)建立一個(gè)基本框架,,如:
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
procedure Mine;
end;
把光標(biāo)放到procedure Mine這行,按下Ctrl+Shift+C,,下面這段代碼將自動(dòng)插入到單元中:
procedure TForm1.Mine;
begin
end;
==窗體操作篇==
在有多個(gè)窗體的程序中,Delphi默認(rèn)是將它們?cè)诔绦騿?dòng)時(shí)全部創(chuàng)建(只是都隱藏了,,只顯示一個(gè)主窗體),,這樣,那些暫時(shí)不必要啟動(dòng)的窗體就占用了許多內(nèi)存空間,。所以我們需要在菜單Project|Options...的Forms標(biāo)簽頁(yè)下,,將那些暫時(shí)不要啟動(dòng)的窗體從“Auto-create forms”下轉(zhuǎn)移到“Available forms”中。這樣,,這些窗體的創(chuàng)建和釋放就需要代碼來(lái)實(shí)現(xiàn)了,。
A.兩種創(chuàng)建窗體方法之比較,。對(duì)于這些非自動(dòng)創(chuàng)建的窗體,我們必須在Show之前Creat(Self)或Create(Application),,將其創(chuàng)建,。如Form2.Creat(Self)和Form2.Create(Application),可是,,它們兩個(gè)到底有什么區(qū)別呢,?其實(shí)兩者區(qū)別不大,
但如果Owner是屬于別的窗口或控件的話,,當(dāng)它的Owner被釋放的時(shí)候,,該Owner所擁有的也會(huì)被釋放。關(guān)鍵的區(qū)別是由誰(shuí)來(lái)管理該窗體的資源,。用第一種方法創(chuàng)建,,該窗體的資源由編程者來(lái)負(fù)責(zé)管理;用第二種方法創(chuàng)建,,該窗體的資源由Application來(lái)管理,。
B.幾種窗體的釋放方法。既然是為了節(jié)約內(nèi)存,,那么用完了的窗體就應(yīng)該“搬出”內(nèi)存,。在這里我列舉幾個(gè)大同小異的方法:
(1)
procedure TForm1.Button1Click(Sender :TObject);
begin
......
if Form2 = nil then
Form2:=TForm2.Create(Application);
Form2.ShowModal;
......
end;
procedure TForm2.close(Sender: TObject; var Action: TCloseAction);
begin
ModalResult := mrNone;
Action := caFree;
Form2 := nil;
end;
(2)
procedure TForm1.Button1Click(Sender :TObject);
begin
if not Assigned(Form2) then
begin
Application.CreateForm(TForm2,Form2);
try
Form2.ShowModal;
finally
Form2.Free;
Form2 := nil;
end;
end
else
Form2.ShowModal;
end;
(3)
procedure TForm2.Button1Click(Sender :TObject);
begin
Form2.Close;
Form2.Release;
end;
==控件使用篇==
A.大名鼎鼎的RXLib控件包是由三位俄羅斯高手編寫的,非常的出色,!不過(guò),,內(nèi)容太多了,要用好也不容易,。我在此拿RxRichEdit簡(jiǎn)單地說(shuō)幾點(diǎn),。
•好多人都問(wèn)RxLib怎么安裝,似乎的確有點(diǎn)復(fù)雜,,呵呵,,所以我也順便說(shuō)一下:
運(yùn)行rxinst.exe將RxLib先安裝到\Program Files\Borland\Delphi5(或6)\RX文件夾下,然后打開Delphi,,選File\Open...,,將RXCTL5.DPK、RXDB5.DPK,、RXBDE5.DPK分別打開后按compile,,繼續(xù)打開:DCLRX5.DPK、DCLRXDB5.DPK和DCLRXBD5.DPK,,將這三個(gè)分別按compile后按install就可以了:-)
•AllowObjects屬性,。Win98下默認(rèn)設(shè)置為True,右鍵菜單沒(méi)有問(wèn)題,,但設(shè)為False時(shí)快捷菜單會(huì)連續(xù)出現(xiàn)兩次,;Win2000下,,設(shè)為True時(shí)會(huì)使右鍵菜單無(wú)法彈出,而False時(shí)卻顯示正常,。所以,,為了系統(tǒng)的兼容性,需要判斷當(dāng)前OS版本:
procedure TFormMain.FormCreate(Sender: TObject);
var
OSVI:OSVERSIONINFO;
......
begin
OSVI.dwOSVersionInfoSize:=sizeof(OSVERSIONINFO);
GetVersionEx(OSVI);
case OSVI.dwPlatformId of
1:RxRichEdit1.AllowObjects:=true;
2:RxRichEdit1.AllowObjects:=false;
end;
.......
end;
但我不知這個(gè)屬性為什么會(huì)有這么一個(gè)問(wèn)題,,還望高手指點(diǎn),。
•OnURLClick事件。RXRichEdit有自動(dòng)將網(wǎng)頁(yè)地址轉(zhuǎn)為超鏈接格式,,但具體的行為還是要自己寫代碼的,,不然這些地址就成了個(gè)空殼了:
procedure TFormMain.RXRichEdit1URLClick(Sender: TObject; const URLText: String; Button: TMouseButton);
begin
if Button = mbLeft then
ShellExecute(Handle, nil, PChar(URLText), nil, nil, SW_SHOW);
end;
B.為了節(jié)約內(nèi)存,優(yōu)化運(yùn)行,,我們總是動(dòng)態(tài)創(chuàng)建組件,。可當(dāng)用完之后,,如果不及時(shí)徹底的將其從內(nèi)存中清理出去,,那就有違我們的初衷了??稍趺?#8220;殺死”所創(chuàng)建的組件? 比如創(chuàng)建了一個(gè)Edit控件,現(xiàn)在想讓它消失,,但用Edit.Free后,調(diào)用Edit.Text卻仍然存在……我們知道,,光Free是不行的,,這只是將Edit所指向的內(nèi)存空間釋放了,但是指針并沒(méi)有設(shè)定為nil,,當(dāng)調(diào)用Edit.Text時(shí),,Delphi仍然會(huì)根據(jù)Edit提供的指針訪問(wèn)已經(jīng)釋放的內(nèi)存區(qū)域,所以會(huì)產(chǎn)生Access Violation ....錯(cuò)誤,。所以我們需要在Free后Edit:=nil或者FreeAndNil(只在Delphi5下有效)將指針nil掉,,才能保證以后的正常運(yùn)行。
C.將各控件的提示文本顯示于狀態(tài)行上,。這個(gè)可用Application的OnHint事件,,但由于Application為不可件對(duì)象,因此可以采用如下方法:
......
public
procedure DisplayHint(Sender: TObject); //聲明一個(gè)方法用于顯示提示文本
end;
......
procedure TForm1.DisplayHint(Sender: TObject); //實(shí)現(xiàn)部分
begin
StatusBar1.SimpleText := GetLongHint(Application.Hint);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnHint := DisplayHint;
end;
這樣顯示在狀態(tài)欄里的文本和提示框(就是那個(gè)自動(dòng)出現(xiàn)的黃色小框)里的是一樣的,。如果想要在狀態(tài)欄里的提示文本更加詳細(xì)怎么辦,?其實(shí),只要控件的Hint屬性這樣寫:MyHint|It‘s just a MyHint!,,就可以讓“|”前的內(nèi)容顯示在提示框(Help Hint box)里,“|”的后面的內(nèi)容顯示在狀態(tài)欄里了,。
D.ListView使用中的一些要點(diǎn),。以下以一個(gè)兩列的ListView為例,。
→增加一行:
with ListView1 do
begin
ListItem:=Items.Add;
ListItem.Caption:=‘第一列內(nèi)容‘;
ListItem.SubItems.Add(‘第二列內(nèi)容‘);
end;
→清空ListView1:
ListView1.Items.Clear;
→得到當(dāng)前被選中行的行的行號(hào)以及刪除當(dāng)前行:
For i:=0 to ListView1.Items.Count-1 Do
If ListView1.Items[i].Selected then //i=ListView1.Selected.index
begin
ListView1.Items.Delete(i); //刪除當(dāng)前選中行
end;
當(dāng)然,ListView有OnSelectItem事件,可以判斷選擇了哪行,用個(gè)全局變量把它賦值出來(lái),。
→讀某行某列的操作:
Edit1.Text := listview1.Items[i].Caption; //讀第i行第1列
Edit2.Text := listview1.Items[i].SubItems.strings[0]; //讀第i行第2列
Edit3.Text := listview1.Items[i].SubItems.strings[1]; //讀第i行第3列
以次類推,,可以用循環(huán)讀出整列。
→將焦點(diǎn)上移一行:
For i:=0 to ListView1.Items.Count-1 Do
If (ListView1.Items[i].Selected) and (i>0) then
begin
ListView1.SetFocus;
ListView1.Items.Item[i-1].Selected := True;
end;
不過(guò)在Delphi6中,,ListView多了一個(gè)ItemIndex屬性,,所以只要
ListView1.SetFocus;
ListView1.ItemIndex:=3;
就能設(shè)定焦點(diǎn)了。
==其他==
•為了優(yōu)化軟件,,使其精益求精,,當(dāng)用到數(shù)組時(shí)經(jīng)常采用動(dòng)態(tài)數(shù)組。在聲明時(shí),,如:A : array of string,,然后在使用數(shù)組之前,SetLength(A,3)設(shè)置數(shù)組長(zhǎng)度為3,,即A[0],A[1],A[2],,這樣就可以了。當(dāng)需要擴(kuò)大數(shù)組長(zhǎng)度時(shí),,再一次:SecLength(A,5),,那么,就增加了A[3]和A[4],,而前面的A[0],A[1],A[2]里的值不會(huì)清空,;同樣,如果SecLength(A,3)后再SecLength(A,1)的話,,就只剩A[0]了,,A[1]和A[2]自動(dòng)被清除內(nèi)存。注意:動(dòng)態(tài)數(shù)組是從“0”開始的,,所以SetLength(A,1)后High(A)=0的?。?BR> 最后當(dāng)不再用這個(gè)動(dòng)態(tài)數(shù)組了,,而程序還沒(méi)有要退出,,那為了節(jié)省內(nèi)存用:A:=nil來(lái)釋放掉這個(gè)數(shù)組,這下真正達(dá)到了“綠色環(huán)保”:)
•“怎么獲取當(dāng)前程序運(yùn)行的路徑”這個(gè)問(wèn)題經(jīng)常能夠在論壇上看到,。的確,,這個(gè)函數(shù)在編程中不時(shí)的要用到的。其實(shí)有好幾個(gè)函數(shù)都能達(dá)到這個(gè)效果:
→GetCurrentDirectory():WinAPI函數(shù),,具體用法如下:
var
MyCurrentDir:Array[0..144] of Char; //存儲(chǔ)當(dāng)前絕對(duì)路徑
begin
GetCurrentDirectory(SizeOf(MyCurrentDir),MyCurrentDir); //取得當(dāng)前絕對(duì)路徑,最后得到的格式如:C:\WINDOWS\SYSTEM
MyCurrentDir:=MyCurrentDir+‘\MySoftName.exe‘;
end;
→GetCurrentDir():GetCurrentDirectory經(jīng)過(guò)Delphi封裝后的一個(gè)函數(shù),,用法簡(jiǎn)單:MyCurrentDir:=GetCurrentDir。最后得到的格式如:C:\WINDOWS\SYSTEM
還有就是可以直接得到路徑的函數(shù):ExtractFilePath(ParamStr(0))、ExtractFilePath(Application.exename)等,。
•系統(tǒng)的關(guān)機(jī),、重新啟動(dòng)等操作的消息。這也是一個(gè)常有人問(wèn)的問(wèn)題,,在此我也順便在提一下:
關(guān)機(jī):ExitWindowsEx(EWX_SHUTDOWN,32);
重新啟動(dòng):ExitWindowsEx(EWX_REBOOT,32);
注銷:ExitWindowsEx(EWX_LOGOFF,32);
關(guān)閉電源:ExitWindowsEx(EWX_POWEROFF,32);
•在Delphi中,,除了使用#39外,要在程序中(如ShowMessage中)顯示“單個(gè)單引號(hào)”要如何處理,?‘‘‘和‘‘‘‘‘都會(huì)出現(xiàn)編譯錯(cuò)誤,。其實(shí),是四個(gè)單引號(hào)表示一個(gè)單引號(hào),,也就是是 ‘‘‘‘,,第二個(gè)和第三表明這是一個(gè)“‘”,第一個(gè)和第四個(gè)是表明這是一個(gè)字符型,。呵呵,,很有趣哦:)
•ShowMessage中的漢化問(wèn)題。ShowMessage中的按鈕都是E文的,,讓人很不舒服,。其實(shí)經(jīng)過(guò)我們的一番DIY,也能把它們都弄成中文的,。
首先要保存當(dāng)前的工程,,然后選Project|Languages|Add...,出現(xiàn)Add Language對(duì)話框,,選擇你要漢化的工程(也可以自定義文件夾),,Next;選最后一項(xiàng)“中文(中國(guó))”,,Next,;Next;Next,;Finish,;OK;然后就出現(xiàn)了Translation Manager對(duì)話框,,在左邊選“中文(中國(guó))|Resource Scripts|Projet1_DRC(這個(gè)具體要看你的工程文件名)”,,然后右邊的列表里找到“Const_SMsgDlgOK”項(xiàng),將其的“中文(中國(guó))(translated)”格改為“確定”(原為OK),,保存后退出,。這下,再運(yùn)行一下程序,,哈哈,,是不是就是中文按鈕啦!
不過(guò),ShowMessage這種類型的信息對(duì)話框非常簡(jiǎn)單了,,可以在系統(tǒng)調(diào)試期間顯示給開發(fā)人員一些過(guò)程信息,。但由于過(guò)于簡(jiǎn)單,,所以我建議在軟件的正式版中不要使用這樣的對(duì)話框。而且,最好用MessageBox代替ShowMessage以減小軟件的體積,,例如,,同樣一個(gè)DLL文件,采用MessageBox 編譯后的DLL文件大小為58K,,而ShowMessage后就變成了301K?。?/P>