翻譯|其它|編輯:郝浩|2008-01-22 10:29:08.000|閱讀 1824 次
概述:
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
C++Builder3.0是Borland公司(現(xiàn)已更名為Insprise)于1998年推出的新一代基于C語(yǔ)言的RAD開發(fā)工具。C++Builder3.0的問(wèn)世,對(duì)廣大愛好C語(yǔ)言的用戶來(lái)說(shuō)不啻是個(gè)福音。因?yàn)橐酝赪indows下,沒(méi)有一種真正基于C語(yǔ)言的可視化編程語(yǔ)言。你如果想用VB或Delphi這一類可視化編程語(yǔ)言去編程,你就不得不去重溫一遍Basic或Pascal語(yǔ)言,沒(méi)有了像C語(yǔ)言一樣可以靈活應(yīng)用的指針,沒(méi)有了"++"、"――"這樣一類可愛的運(yùn)算,總之一切使用起來(lái)都不如C語(yǔ)言一樣得心應(yīng)手。現(xiàn)在這一切煩惱都不復(fù)存在了。C++Builder3.0不僅支持傳統(tǒng)的C語(yǔ)言,也支持Borland的OWL和Microsoft的MFC。可以這樣說(shuō),C++Builder3.0是目前Windows下功能最為強(qiáng)大的C語(yǔ)言編譯器。由于C++Builder3.0問(wèn)世不久,有關(guān)資料不是很多,下面結(jié)合筆者的使用情況,談?wù)剮c(diǎn)經(jīng)驗(yàn)、體會(huì)。
一、動(dòng)態(tài)調(diào)用窗體Form
在缺省情況下,由File/NewForm生成添加入項(xiàng)目文件中的窗體都具有"AutoCreate"(自動(dòng)創(chuàng)建)的特性。即只要程序運(yùn)行,該窗體就存在于內(nèi)存中了,不管當(dāng)前它是否被調(diào)用。具有這種特性的窗體一般適用于窗體屬性比較固定、經(jīng)常被調(diào)用的情況。其優(yōu)點(diǎn)是速度快,缺點(diǎn)是占用內(nèi)存。在實(shí)際程序設(shè)計(jì)中,會(huì)遇見大量類似對(duì)話框功能的窗體,它們用于顯示狀態(tài)或輸入信息,僅須在程序中調(diào)用一下,完成其功能就行了,無(wú)需常駐內(nèi)存。這時(shí)可以通過(guò)選擇Project/Options/Forms,將"Auto--Createforms"欄中相應(yīng)的窗體,如Form1,用">"鍵移動(dòng)到"Availableforms"欄中,并在程序需調(diào)用該窗體處,加入下列語(yǔ)句:
TForm1*myform=newTForm1(this);
myform->ShowModal();
deletemyform;
窗體Form1僅是在需要調(diào)用時(shí)才調(diào)入內(nèi)存,調(diào)用完成后,即用delete清除出內(nèi)存。這樣可減少程序?qū)?nèi)存資源的占用。
二、遍歷窗體控件的方法
要訪問(wèn)或修改窗體上的控件,方法很簡(jiǎn)單,以TEdit為例子:
Edit1->Text="";
Edit2->Text="";
但如果窗體上有十來(lái)個(gè)像Edit1這樣的控件,需要進(jìn)行相同的初始化,用上面的方法一個(gè)一個(gè)地進(jìn)行,豈不麻煩!所以有必要掌握遍歷窗體控件的方法。在介紹該方法之前,讓我們先了解一下窗體Form的Components和Controls屬性。參見表一。
表一
屬性類型說(shuō)明
ComponentCountInt目前Form上各類
控件的總數(shù)
ComponentsTCompont*目前Form上指向
所有控件的數(shù)組
ControlCountInt目前Form上某一子
區(qū)域上各類控件的總數(shù)
ControlsTControl*目前Form上指向某一子
區(qū)域上所有控件的數(shù)組
以圖一為例(圖略)說(shuō)明,F(xiàn)orm1的ComponentCount=6,而Panel1的ControlCount=4.,
其中:數(shù)組對(duì)象
Components[0]Panel1
Components[1]Label1
Components[2]Edit1
Components[3]Label2
Components[4]Edit2
Components[5]Button1
數(shù)組對(duì)象
Controls[0]Label1
Controls[1]Edit1
Controls[2]Label2
Controls[3]Edit2
下面這段代碼完成了對(duì)Panel1上所有TEdit控件的遍歷初始化。讀者稍加修改,即可對(duì)其它控件進(jìn)行遍歷。這里有一個(gè)小技巧,我們把需要進(jìn)行初始化的控件放置在了一Panel1上,與不需要初始化的控件區(qū)分開來(lái),這樣便于編程。
AnsiStringnamestring="TEdit";
for(inti=1;iControlCount;i++)
{
if(Panel1->Controls[i]->
ClassNameIs(namestring))
{
TEdit*p=dynamic_cast
(Panel1->Controls[i]);
P->Text="";
}
}
三、用Enter鍵控制焦點(diǎn)切換的方法
在Windows環(huán)境下,要使一個(gè)控件取得焦點(diǎn),可在該控件上用鼠標(biāo)單擊一下,或按Tab鍵將焦點(diǎn)移至該控件上。這種控制焦點(diǎn)切換的方法有時(shí)不符合用戶的習(xí)慣。就圖一而言,用戶就希望用Enter鍵,控制焦點(diǎn)由Edit1切換到Edit2。要實(shí)現(xiàn)這樣的功能需借助WinAPI函數(shù)SendMessage來(lái)完成。方法是:先設(shè)Form1的KeyPreview屬性為true,然后在Form1的OnKeyPress事件中加入如下的代碼。這樣,用戶就可以通過(guò)按Enter,鍵控制焦點(diǎn)按定義好的Taborder順序來(lái)移動(dòng)了!
void__fastcallTForm1::
FormKeyPress(TObject*Sender,char&Key)
{
if(Key==VK_RETURN)
{
SendMessage(this->Handle,WM_NEXTDLGCTL,0,0);
Key=0;
}
}
四、為TStringGrid的文字加上顏色
----TStringGrid是C++Builder提供給用戶的一種字符網(wǎng)格控件。美中不足的是,它沒(méi)有提供分別修改各單元字體顏色、大小的方法。其實(shí)要為TStringGrid實(shí)現(xiàn)這樣功能,只需在程序中稍加處理就行了。方法是自定義一個(gè)二維數(shù)組cellbuf,它的下標(biāo)與網(wǎng)格單元列行一一對(duì)應(yīng),用于存放各網(wǎng)格單元的顏色、文字等信息。
structCellStru
{
AnsiStringmsg;//文字信息
TColorcolor;//文字顏色
};
CellStrucellbuf[MAXCOL][MAXROW];
----初始化cellbuf后,再在字符網(wǎng)格控件StringGrid1的OnDrawCell響應(yīng)事件中,加入如下的代碼即可。
void__fastcallTForm1::StringGrid1DrawCell
(TObject*Sender,intCol,
intRow,TRect&Rect,TGridDrawStateState)
{
StringGrid1->Canvas->Font->
Color=cellbuf[Col][Row].color;
StringGrid1->Canvas->TextOut(Rect.Left+3,
Rect.Top+3,cellbuf[Col][Row].msg);
}
五、軟件封面的實(shí)現(xiàn)
----現(xiàn)代軟件設(shè)計(jì)的流行做法是,在程序運(yùn)行完成初始化之前,先調(diào)用一幅畫面做為封面,通常是1/4屏幕大小,顯示一下軟件的名稱、作者、版本等信息。要用C++Builder實(shí)現(xiàn)這樣的功能,方法很簡(jiǎn)單:①自定義一窗體類TSplashForm,將其設(shè)置成"透明窗口",即BorderIcons下的所有選項(xiàng)均置成false,BorderStyle=bsNone,F(xiàn)ormStyle=fsStayOnTop,Position=poScreenCenter;②在TSplashForm窗體上放置一TPanel(相當(dāng)于圖形的鏡框);③在TPanel上放置一TImage控件,調(diào)入所需要的圖形;④對(duì)WinMain函數(shù)稍加修改,加入如下所示代碼即可。需要指出的是,這段代碼通過(guò)函數(shù)FindWindow,搜索內(nèi)存中是否有窗口標(biāo)題為"Demo"應(yīng)用程序存在,若存在,則退出程序的運(yùn)行。該功能可防止程序的再次運(yùn)行。在某些場(chǎng)合這樣設(shè)計(jì)是必須的。
WINAPIWinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
try
{
if(FindWindow(NULL,"Demo")!=0)
{
Application->MessageBox
("程序已經(jīng)運(yùn)行!","警告",MB_ICONSTOP);
return0;
}
TSplashForm*splash=newTSplashForm(Application);
splash->Show();
splash->Update();
Application->Initialize();
Application->CreateForm(__classid(TForm1),&Form1);
splash->Close();
deletesplash;
Application->Run();
}
catch(Exception&exception)
{
Application->ShowException(&exception);
}
return0;
}
六、如何永久清除DBF中的已被刪除的記錄
用table->Delete()刪除的DBF記錄,并沒(méi)有真正從DBF數(shù)據(jù)庫(kù)中被刪除,而僅僅是做上了一個(gè)刪除標(biāo)記。如何實(shí)現(xiàn)類似dBase中的Pack命令的功能呢?請(qǐng)看下面的代碼。 table->Close();
for(;;)
try
{
table->Exclusive=true;
table->Open();
break;
}
catch(...)
{
}
if(DbiPackTable(table->DBHandle,table->
Handle,NULL,szDBASE,true)!=DBIERR_NONE)
Application->MessageBox("不能刪除記錄",
"錯(cuò)誤",
MB_ICONSTOP);
七、I/O端口讀寫的實(shí)現(xiàn)
細(xì)心的讀者會(huì)發(fā)現(xiàn),C++Builder不再支持如inportb()、outportb()一類I/O端口讀寫指令了。準(zhǔn)確地說(shuō),在Windows環(huán)境下,BorlandC++僅支持16位應(yīng)用程序的端口操作,對(duì)32位應(yīng)用程序的端口操作不再支持,而C++Builder開發(fā)出來(lái)的程序是32位的。我個(gè)人以為,這是C++Builder設(shè)計(jì)者的敗筆。因?yàn)镻C機(jī)中,I/O地址空間與內(nèi)存地址空間從來(lái)都是各自獨(dú)立的。看看Delphi,不就通過(guò)Port數(shù)組實(shí)現(xiàn)了對(duì)I/O端口的訪問(wèn)了嗎?搞不清楚為什么C++Builder就沒(méi)有提供類似的機(jī)制?下面這幾個(gè)函數(shù)是筆者從網(wǎng)上淘下來(lái)的,經(jīng)過(guò)驗(yàn)證,在Windows95環(huán)境下,的確可實(shí)現(xiàn)對(duì)I/O端口的讀寫。讀者可以借鑒使用。
voidoutportb(unsignedshort
intport,unsignedcharvalue)
{
//movedx,*(&port);
__emit__(0x8b,0x95,&port);
//moval,*(&value);
__emit__(0x8a,0x85,&value);
//outdx,al;
__emit__(0x66,0xee);
}
voidoutportw(unsignedshort
intport,unsignedshortintvalue)
{
//movedx,*(&port);
__emit__(0x8b,0x95,&port);
//movax,*(&value);
__emit__(0x66,0x8b,0x85,&value);
//outdx,ax;
__emit__(0xef);
}
unsignedcharinportb(unsignedshortintport)
{
unsignedcharvalue;
//movedx,*(&port);
__emit__(0x8b,0x95,&port);
//inal,dx;
__emit__(0x66,0xec);
//mov*(&value),al;
__emit__(0x88,0x85,&value);
returnvalue;
}
unsignedshortintinportw(unsignedshortintport)
{
unsignedshortintvalue;
//movedx,*(&port);
__emit__(0x8b,0x95,&port);
//inax,dx
__emit__(0xed);
//mov*(&value),ax
__emit__(0x66,0x89,0x85,&value);
returnvalue;
}
八、軟件的分發(fā)
在Windows下開發(fā)的應(yīng)用程序一般都比較龐大,程序的運(yùn)行往往離不開一大堆不知名的系統(tǒng)DLL文件。為了生成能脫離C++Builder環(huán)境、獨(dú)立運(yùn)行的應(yīng)用程序,讀者須對(duì)編譯器進(jìn)行一定的設(shè)置。方法是:置Project/Option/Packages/Runwithruntimepackages為Disable,置Project/Option/Linker/UsesdynamicRTL為Disable,重新編譯一遍程序,這樣生成的EXE文件就可以脫離C++Builder環(huán)境運(yùn)行了。但如果你的程序中應(yīng)用了數(shù)據(jù)庫(kù),僅有上述的操作是不夠的--因?yàn)椋氵€得安裝BDE(BorlandDatabaseEngineer)。BDE的安裝比較麻煩,讀者最好是用C++Builder3.0附帶的InstallShieldExpress來(lái)制作安裝盤,把應(yīng)用程序和BDE打包在一起。如果找不到,也可用Delphi3.0附帶的InstallShieldExpress來(lái)制作。InstallShield的使用方法,限于篇幅,不再介紹。有條件的讀者可上網(wǎng)查到有關(guān)資料。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:編程愛好者