1.
form.Free - 釋放Form占用的所有資源。Free后,F(xiàn)orm指針不能再使用,除非對Form重新賦值。
form.Hide - 隱藏Form。可以調(diào)用form.Show再一次顯示。
form.close - 關(guān)閉Form,實(shí)際的結(jié)果取決于OnCloseQuery和OnClose,
如果OnCloseQuery的CanClose為False,不執(zhí)行任何操作,如果為True,
進(jìn)一步考察OnClose的Action的值:
caNone: 不執(zhí)行任何操作
caHide: 隱藏窗口,同form.Hide
caFree: 釋放Form占用的資源,同form.Free
caMinimize: Form最小化。
caFree最主要應(yīng)用于MDI(多窗體)中,因?yàn)樽哟绑w關(guān)閉時默認(rèn)的動作是Hide,即隱藏,所以如果希望其釋放所占用的資源時,就要設(shè)定關(guān)閉動作,也就是在OnClose事件中加一句Action:=caFree;
而Application.Terminate正如兄臺所說的是關(guān)閉整個應(yīng)用程序。
Create是從繼承下來的方法,作用是給對象實(shí)例分配內(nèi)存,語法為:
Formname:=Tformname.Create(Application); //參數(shù)Application表示此窗體的擁有者為Application。
Show是顯示已經(jīng)創(chuàng)建的窗口。語法為:
Formname.Show;
另外,告訴你:Show是無模式顯示窗體,ShowModal是模式顯示窗體。
創(chuàng)建form的順序:
1.formcreate
2.formactive
3.formshow
==========================
2.
implementation分割代碼的作用域。implementation防止外部引用單元涉及,任意單元如果訪問該單元,只能引用該單元的interface節(jié),對于implementation內(nèi)聲明但沒有在interface中聲明的函數(shù)或過程,其他引用該單元的單元都不能調(diào)用,同樣,implementation內(nèi)聲明的變量,只能在該單元內(nèi)被使用。
==========================
3.
FormDestroy 和 FormClose 有什么區(qū)別和聯(lián)系?
(1).窗口的所有資源真正釋放時調(diào)用 FormDestroy。當(dāng)你關(guān)閉窗口時,VCL會調(diào)用FormClose,如果你在FormClose里寫Action = caFree,那么VCL會繼續(xù)調(diào)用FormDestroy;如果你將Action的值賦為其它任何值,VCL不會真正釋放窗口資源(如果Action=caNone則什么事都不做,窗口保持原狀),這時就不會調(diào)用 FormDestroy 。
(2).看這個程序:
將Form2改為available,然后在TForm2.FormClose 寫 action := caFree; 在TForm2.FormDestroy 寫 Form2 := nil;
然后這樣使用Form2
if not Assigned(Form2) then
Form2 := TForm2.Create(Self);
Form2.Show;// Form2.ShowModal ;
第一種情況: 在FormClose中調(diào)用Form1.Close,則會調(diào)用到TForm.OnClose,其中又調(diào)用到了FormClose,所以就死遞歸了。一死遞歸,當(dāng)然就棧溢出(Stack Overflow)。
第二種情況: 在FormClose調(diào)用Form1.Free,這樣會調(diào)用TForm.Destroy,TForm.Destroy會判斷自己是否與Application.MainForm相同,如果是,則會將Application.MainForm置為nil,TForm.Destroy然后觸發(fā)FormDestroy,在FormDestroy中Form1被置成了nil。FormClose是由TForm.Close調(diào)用的,本來在FormClose之后,比較它自己是否Application.MainForm,如果是,就調(diào)用Application.Terminate結(jié)束應(yīng)用程序。但這時雖然Self還是非nil,它只是Close方法中的一個隱藏變量,而Application.MainForm已經(jīng)為nil,所以即使MainForm已經(jīng)不存在了,但應(yīng)用程序還是存在,只是看不見它了。Application本身也是一個窗口,但它的大小為0。所以只能用別的辦法來關(guān)閉應(yīng)用程序了(Ctrl+Alt+Del或在Delphi IDE中按Ctrl+F2)。
忠告:
盡量不要用Free方法來關(guān)閉窗體,尤其是主窗體,應(yīng)該用Close方法。在FormCreate, FormShow, FormActivate, FormCloseQuery, FormClose, FormDestroy各事件中不要調(diào)用關(guān)閉、釋放或銷毀窗體的方法。
不要在方法或事件中直接引用Form1這類全局實(shí)例變量,如果別人用下列方法創(chuàng)建窗體,用Form1變量就沒有作用了:
var
myFormVar: TForm1;
begin
myFormVar := TForm1.Create(Application);
myFormVar.Show;
// 用myFormVar用一些事
myFormVar.Close;
end;
因?yàn)檫@時候TForm1.FormClose中運(yùn)行的其實(shí)是myFormVar而不是Form1。
在FormDestroy中可以改成這樣:
if Self=Form1 then
Form1 := nil;
用這個方法來防止別的程序?qū)orm1的無意錯誤引用。
==================================
4.
用ord函數(shù)可以取得字符的ASCII碼的值
函數(shù)的參數(shù)是一個字符型 返回值是一個整型
若是要定義了一個string類型的變量
則要取這個變量中的字符ASCII碼則要用數(shù)組的形式去訪問
要取得字符串中的每個字符的ASCII碼值應(yīng)該這樣寫
var
Ansiretn,i:integer;
TestAnsi:string;
TestAnsi:='happy new year!';
For i:=0 To Length(TestAnsi) Do
ShowMessage(IntToStr(ord(TestAnsi[i])));
==============================
5.
tabcontrol從(Twincontrol)派生,只有一個頁頭在變,也就是說不管有多少頁,都是一個twincontorl.
pagecontrolc從(Twincontrol)派生,而且每個tabsheet也是從twincontrol派生,也就是說有多少頁就會生成多少個twincontrol對象。
上面主要是占用資源的區(qū)別。
另外從使用的方便程序上也有區(qū)別:如果每個頁面的內(nèi)容差不多的話用tabcontrol比較好。
如果每個頁面的內(nèi)容都不同用pagecontrol就比較方便,如果用tabcontrol的話控制每個頁面的控件顯示和隱藏以及控件位置,那會煩的不得了。
用TabControl也不一定要隱藏/顯示,所有"頁"都放到一獨(dú)立的Panel中,由此就有Panel1,Panel2...等等,保證他們一樣大,要顯示某"頁"時,只需要執(zhí)行如Panel1.BringToFront一類的代碼,不需要隱藏/顯示
=============================
6.
假設(shè)你在800*600的分辨率下設(shè)計(jì)的form,第一步:
先設(shè)置Form.scale:=false;
然后
inplementation
const
ScreenWidth: LongInt = 800; {I designed my form in 800x600 mode.}
ScreenHeight: LongInt = 600;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
scaled := true;
if (screen.width <> ScreenWidth) then
begin
height := longint(height) * longint(screen.height) div ScreenHeight;
width := longint(width) * longint(screen.width) div ScreenWidth;
scaleBy(screen.width, ScreenWidth);
end;
end;
下一步,要讓每個子控制的字體改變到合適的大小:
type
TFooClass = class(TControl); { needed to get at protected }
{ font property }
var
i: integer;
begin
for i := ControlCount - 1 downto 0 do
TFooClass(Controls[i]).Font.Size :=
(NewFormWidth div OldFormWidth) *
TFooClass(Controls[i]).Font.Size;
end;
====================================
7.
TClass1 = class
procedure func1; virtual;//virtual;這個是做什么的
end;
TClass2 = class(TClass1)
procedure func1; override;//override這個是做什么的
end;
virtual 的作用就是允許Tclass1的子類也可以有fun1的過程定義.
override 的作用就是告訴tclass1在子類(tclass2)中重新定義了fun1過程.
具體運(yùn)行的時候,
a: tclass1 ;
b: tclass2 ;
a.fun1 調(diào)用 tclass1的 fun1
b.fun1 調(diào)用 tclass2的 fun2
1). virtual翻譯過來就是虛方法,它自已可以實(shí)現(xiàn)也可以不實(shí)現(xiàn),主要給后代一個可以override的方法。以便子類和父類用相同的函數(shù)下實(shí)現(xiàn)不同的功能。
2). override就是子類用相同的函數(shù)名來做和父類不同的事,但不覆蓋父類方法,(還可以繼承父類的方法)函數(shù)名相同而不帶override字樣的函數(shù)不同。
=============================
8.
我希望做個啟動畫面,但如果在formcreate里show另一個form,就會出錯,為什么?
方法一:調(diào)用Showmodal函數(shù)來實(shí)現(xiàn)。Showmodal方式使一個窗口為激活窗口, 和Show相似,但它令窗口模式化?,F(xiàn)舉一例說明:
⒈開始一個新工程。給表格起名為MainForm,MainForm的單元起名為Main, 工程文件起名為Test。
⒉在MainForm中插入一個Button部件,將其Caption屬性設(shè)為“關(guān)閉”,為該部件的OnClick事件創(chuàng)建一個過程,并在過程的begin和end之間插入Close語句。
⒊在應(yīng)用程序添加一個表格,將這個表格起名為MoveForm,MoveForm 的單元起名為Move。
⒋為便于演示,在MoveForm中插入一個Label部件,設(shè)置其Caption 屬性為“歡迎進(jìn)入本系統(tǒng)”。
⒌建立兩個表格之間的關(guān)聯(lián)。在Unit Main的 implementation 中加入語句 uses move;
再為MainForm創(chuàng)建OnActivate事件。
procedure TMainForm.FormActivate(sender:TObject);
begin
MoveForm.Showmodal;
end;
⒍從Component模板的System類別中選擇一個計(jì)時器(Timer),添加入 MoveForm 表格中,設(shè)置其Interval屬性為3000(可根據(jù)需要自定義),再為其OnTimer事件添加語句
close;
加入一個Timer部件目的是用以控制閃現(xiàn)窗口顯示時間。在此,MoveForm顯示了3秒鐘后關(guān)閉,主窗口MainForm自動被激活。
⒎編譯、運(yùn)行程序,就能得到延遲為3秒的閃現(xiàn)窗口。
方法二:你可通過修改工程文件中的源代碼來實(shí)現(xiàn),這在Delphi 的編程中是很少見的?,F(xiàn)舉一例具體說明:
前四步同方法一。
⒌選擇View/Project Manager,擊Option按鈕,選擇結(jié)果Project Option 對話底部的Forms頁欄目。注意,MainForm和MoveForm是在Auto-create forms 列表中。選擇MoveForm并擊右鍵頭按鈕,把這個表格移到 Available forms 。 所有的
Delphi表格通過缺省方式自動在內(nèi)存中建立, 因此它們要消耗內(nèi)存和系統(tǒng)資源。在類似這里(程序運(yùn)行時創(chuàng)建一個表格)的情況下, 你應(yīng)該將表格從自動創(chuàng)建列表格中去掉。
⒍下一步修改工程的源代碼。選擇View/Project Source,修改begin和end之間的
語句如下:
程序清單Test.Dpr
program Test
uses
forms,
Main in ’MAIN.PAS’{MainForm},
Move in ’Move.PAS’{MoveForm}
{$R *.RES}
begin
MoveForm:=TMoveForm.Create(Application);{Create創(chuàng)建閃現(xiàn)窗口對象}
MoveForm.Show;
MoveForm.Update;
Application.CreateForm(TMainForm,MainForm);
MoveForm.Hide;
MoveForm.Free;{Free從內(nèi)存中釋放對象}
Application.Run;
end.
第一條語句創(chuàng)建了對象,該對象存在內(nèi)存中,但還不能看見, 為了讓它出現(xiàn)并更 新它的內(nèi)容,調(diào)用對象的Show和Update成員函數(shù):Show和Update。當(dāng)閃現(xiàn)窗口使用完后,用Hide函數(shù)將它隱藏起來,然后用Free函數(shù)釋放它所占據(jù)的內(nèi)存。
=======================
9.
請問delphi自定議函數(shù)中的result是不是和其它語言的return一樣?不過在其它語言中遇到return便會結(jié)束函數(shù).delphi中好像不是.請高手幫助提示下!!!
區(qū)別在與:
在c++中:
跳出一個函數(shù)用return (返回類型),在return的同時就跳出函數(shù)了, 無返回類型函數(shù) 直接return就跳出了。
但delphi不一樣: result中保存的是返回值,
但真正跳出函數(shù)要用exit, exit在退出函數(shù)的同時把result值返回, 如果是procedure,就沒有result
delphi中result一般做為函數(shù)的返回值,不做為退出條件,退出條件是樓上所說exit,abort等
給 result 賦值不會退出函數(shù)。
=======================
10.
TMainForm = class(TForm)
procedure mmiCloseAllClick(Sender: TObject);
public
procedure OpenTextFile(EditForm: TForm; Filename: string);
procedure OpenBMPFile(FileName: String);
procedure OpenRTFFile(RTFForm: TForm; FileName: string);
end;
這其中,mmiCloseAllClick和OpenTextFile這兩個在不同地方聲明的過程,使用有什么不同的地方?
它們在使用上沒有什么不同,只不過前者是定義在protected里的,后者定義在public里,它們在使用上的不同體現(xiàn)在子類對它們的繼承使用上和其它對等類對它們的引用上。
換句話講:如果沒有規(guī)定類函數(shù)/屬性的類型(我是指Public、Private...) ,那么默認(rèn)就是Protected。
=======================
11.
誰能告訴我繼承和派生的區(qū)別是什么??"子類"和"派生類"的區(qū)別是什么???
父子關(guān)系只能是一代間的 , 而祖先和子孫是可以隔代的;
a派生b b派生c 也可以說是:b繼承a c繼承b
那么b是a的繼承類,b,c是a的派生類,也是a的子類;
=======================
12.
對于對象來說,一個域就象一個變量。域可以是任何類型,包括類類型。(也就是說,域可以保存對象引用。)域通常是私有的。
要定義類的域成員,只需簡單地象聲明變量那樣聲明域。所有的域聲明必需出現(xiàn)在任何屬性或方法聲明之前。例如,下面的聲明創(chuàng)建了一個叫做TNumber的類,該類中除繼承自TObject的方法之外,僅有一個叫做Int的整數(shù)域成員。
type TNumber = class
Int: Integer;
end;
域的范圍是靜態(tài)的,即編譯時對域的引用是固定的。要明白這一含義,考慮如下代碼:
type
TAncestor = class
Value: Integer;
end;
TDescendant = class(TAncestor)
Value: string; //隱藏了繼承得到的Value域
end;
var
MyObject: TAncestor;
begin
MyObject := TDescendant.Create;
MyObject.Value := 'Hello!'; //錯誤
TDescendant(MyObject).Value := 'Hello!'; //正常工作
end;
盡管MyObject保存了TDescendant的一個實(shí)例,它聲明為TAncestor,但編譯器仍將MyObject.Value解釋為對TAncestor中聲明的整數(shù)域的引用。不過,在TDescendant實(shí)例對象中仍然存在兩個域,只是繼承得到的Value域被新的域隱藏而已,可以通過類型轉(zhuǎn)換訪問前者。
===================================
13.
內(nèi)存出錯的討論:"Access violation at address 地址 in Module '你的應(yīng)用'.
這種在Delphi的開發(fā)中普遍存在.
這種內(nèi)存訪問錯誤,往往是訪問了已經(jīng)Free掉的對象,或是訪問還沒有生成的對象.
如果這個地址為 0000000, 則一般為訪問還沒有創(chuàng)建的對象.
如果這個地址不為0 ,而是一個地址, 那可能是要訪問的對象已經(jīng)Free掉. 或是要訪問的對象是局部變量, 但還沒有創(chuàng)建.
如果是調(diào)用DLL中的函數(shù),則有可能
(1)?。模蹋毯瘮?shù)入口失敗.
(2)DLL中函數(shù)與調(diào)用處函數(shù)的調(diào)用約定不同(StdCall? )
聯(lián)系客服