C++ Builder (簡稱BCB)是Borland公司繼Delphi之后開發的又一個通用的Client/Server結構的開發工具。C++ Builder的集成開發環境(IDE)比Delphi溶入了更多的Windows 95控制元件,可以建立的對象更為詳細,添加了許多Delphi所沒有的控件。作為32位的Windows環境下的快速開發工具(RAD),C++ Builder基于最流行的面向對象的程序設計(OOP)語言C++,采用領先的數據庫技術,并結合使用了圖形用戶界面(GUI)的先進特性和設計思想,使得C++ Builder成為目前繼Visual Basic、Delphi之后在32位Windows環境下最具有吸引力的開發工具?,F在C++ Builder 4業已上市。
筆者曾使用C++ Builder 3.1參與開發了本校的網上教務管理系統,對其數據庫控件的強大功能深有感觸,開發之余,用其開發了一個常見的文件分裂工具——文件分離者。見圖1:
此類工具在網上極為常見,不要以為做起來十分困難,讀完下面的編程過程,你也可以動手編一個。
筆者首先聲明:我的處女作還十分粗糙,進一步完善的地方還很多,僅僅作為學習編制此類軟件的一種方法,更主要的是”教”你學習C++ Builder。
進入C++ Builder,IDE已經為你準備了一個工作臺Form1,請按下面步驟進行:
1. 添加各種控件
在Win32工具條上用鼠標單擊PageControl控件,然后在Form1上單擊,Form1上即出現PageControl1控件 ;鼠標右鍵單擊PageControl1控件,選擇New Page,PageControl1上出現TabSheet1控件,如法炮制,產生所需的TabSheet2、TabSheet3控件。
2. 在TabSheet1上添加控件
單擊TabSheet1使它成為活動控件,在其上面添加四個Label控件、兩個Edit控件、兩個Button控件(都在Standard工具條),目錄列表框DirectoryListBox1、驅動器列表框DriveComboBox1、文件列表框FileListBox1、文件過濾組合框FilterComboBox1各一個(都在Win3.1工具條)。最后在Win32工具條上選擇UpDown控件添加到TabSheet1上。
3. 修改TabSheet1上各控件屬性(Properties)
在Object Inspector中修改各控件的屬性,修改的屬性見下表:
控件
屬性
屬性值
label2
caption
選擇大?。?
label3
caption
選擇要分裂的文件:
label4
caption
m
directorylistbox1
dirlabel
label1
filelist
filelistbox1
drivecombobox1
dirlist
directorylistbox1
filtercombobox1
filelist
filelistbox1
bitbtn1
caption
分裂
glyph
c:\progrem files\common files\borland shared\images\buttons\arrow3r.bmp
bitbtn2
caption
退出
kind
bkignore
updown1
positon
1
associate
edit2
edit2
text
1
tabsheet1
caption
分裂文件
filelistbox1
fileedit
edit1
單擊FilterComboBox1的Filter屬性,在Filter Editor中添加下表中的內容:
all files (*.*)
*.*
zip(*.zip)文件
*.zip
bmp(*.bmp)文件
*.bmp
word(*.doc)文件
*.doc
文本文件(*.txt)
*.txt
4. 修改完上述屬性后的TabSheet1如圖:
5.添加程序代碼
?。?) 雙擊BitBtn1按鈕,加入下列代碼:
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
AnsiString filename,fileexename,fileinfo ;
int exenamelength,FileHandle,FileLength, ;
char *Buffer ;
int handle ,I ;
int size,ReadFileSize,FileRemainder ;
int N,Remainderflag ;
size=StrToInt(Edit2->Text) ;//指定分裂文件的大小
FileHandle = FileOpen(FileListBox1->FileName, fmOpenRead) ;//打開指定的文件
filename=Edit1->Text ;//獲得原文件名
fileexename=ExtractFileExt(FileListBox1->FileName) ;//獲得文件擴展名
FileLength = FileSeek(FileHandle,0,2) ; //獲得文件長度
ReadFileSize=size*1024*1024 ;//每次讀取指定的字節數
N=FileLength/ReadFileSize ;//文件被分裂后生成othername文件的個數
FileRemainder=FileLength%(size*1024*1024) ;//文件被分裂后生成FileRemainder文件的大小
FileSeek(FileHandle,0,0) ;
Buffer=new char[ReadFileSize+1] ;//存放每次讀取原文件指定字節的緩沖區
if(N<=5&&N>0){
for(i=1 ;i<=N ;i++){
switch(i){
case 1: //生成Othername1文件
if((handle=FileCreate(“Othername1”))>0){
FileRead(FileHandle, Buffer,ReadFileSize) ;
if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)
Application->MessageBox(“Othername1 Write not suclearcase/" target="_blank" >ccessful !”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
break ;
case 2: //生成Othername2文件
if((handle=FileCreate(“Othername2”))>0){
FileRead(FileHandle, Buffer,ReadFileSize) ;
if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)
Application->MessageBox(“Othername2 Write not successful !”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
break ;
case 3: //生成Othername3文件
if((handle=FileCreate(“Othername3”))>0){
FileRead(FileHandle, Buffer,ReadFileSize) ;
if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)
Application->MessageBox(“Othername3 Write not successful !”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
break ;
case 4: //生成Othername4文件
if((handle=FileCreate(“Othername4”))>0){
FileRead(FileHandle, Buffer,ReadFileSize) ;
if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)
Application->MessageBox(“Othername4 Write not successful !”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
break ;
case 5: //生成Othername5文件
if((handle=FileCreate(“Othername5”))>0){
FileRead(FileHandle, Buffer,ReadFileSize) ;
if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)
Application->MessageBox(“Othername5 Write not successful !”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
break ;
}
}
if(FileRemainder>0){ //生成FileRemainder文件
Remainderflag=1 ;
FileRead(FileHandle, Buffer,FileRemainder) ;
if((handle=FileCreate(“FileRemainder”))>0){
if(FileWrite(handle, Buffer,FileRemainder)!=FileRemainder)
Application->MessageBox(“FileRemainder Write not successful”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
}
else
Remainderflag=0 ;
//----------生成ExeNameFile.txt信息文件---------------
if((handle=FileCreate(“ExeNameFile.txt”))>0){
if(Remainderflag==1)
fileinfo=“,”+filename+”,”+IntToStr(N)+”,”+”Y”+”,” ;
else
fileinfo=“,”+filename+”,”+IntToStr(N)+”,”+”N”+”,” ;
exenamelength=fileinfo.Length() ;
Buffer=new char[exenamelength+1] ;
Buffer=fileinfo.c_str() ;
if(FileWrite(handle,Buffer,exenamelength)!=exenamelength)
Application->MessageBox(“ExeNameFile Write not successful”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(handle) ;
}
FileClose(FileHandle) ;
}
else{
Application->MessageBox(“請增加文件大小”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
FileClose(FileHandle) ;
}
}
?。?) 雙擊BitBtn2按鈕,加入下列代碼:
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
Application->Terminate() ;
}
6. 在TabSheet2上添加控件
單擊TabSheet1使它成為活動控件,在其上面添加兩個Label控件、一個Edit控件、兩個Button控件,目錄列表框DirectoryListBox2、驅動器列表框DriveComboBox2、文件列表框FileListBox2、文件過濾組合框FilterComboBox2各一個。
7.修改TabSheet2上各控件屬性(Properties)
在Object Inspector中修改各控件的屬性,修改的屬性見下表:
控件
屬性
屬性值
label5
caption
選擇要合成的exenamefile.txt文件:
directorylistbox2
dirlabe2
label6
filelist
filelistbox2
drivecombobox2
dirlist
directorylistbox2
filtercombobox2
filelist
filelistbox2
bitbtn3
caption
合成
kind
bkyes
bitbtn4
caption
退出
kind
bkignore
filelistbox2
fileedit
edit3
tabsheet2
caption
合成文件
單擊FilterComboBox2的Filter屬性,在Filter Editor中添加下表中的內容:
ExtNameFile文件(*.txt)
*.txt
7. 修改完上述屬性后的TabSheet2如圖:
8.添加程序代碼
(1)雙擊BitBtn3按鈕,加入下列代碼:
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
AnsiString copystr ;
AnsiString filename,flag,filepath ;
AnsiString openedfile ;
int FileHandle,size ;
int ReadFileSize=256 ;
char *Buffer ;
if(AnsiCompareStr(Edit2->Text,”ExeNameFile.txt”)==0){
FileHandle = FileOpen(FileListBox2->FileName,fmOpenRead) ;//打開ExeNameFile.txt文件
FileSeek(FileHandle,0,0) ;//文件指針移到文件開始處
Buffer=new char[ReadFileSize+1] ;
FileRead(FileHandle, Buffer,ReadFileSize) ;
filename=copy(Buffer,1,2) ; //得到文件名
size=StrToInt(copy(Buffer,2,3)) ; //othername文件的數目
flag=copy(Buffer,3,4) ; //FileRemainder文件是否存在
filepath=ExtractFileDir(FileListBox1->FileName) ;//得到文件路徑
if(flag=='Y'){ //FileRemainder文件存在
copystr=“copy othername* /b + FileRemainder /b “+ filename+” /b” ;//執行Dos命令將文件合成
system(copystr.c_str()) ;
}
else{
copystr=“copy othername* /b “+ filename+” /b” ;
system(copystr.c_str()) ;
}
}
else
Application->MessageBox(“請選擇ExeNameFile.txt文件!”,”確認!”,MB_OK+MB_DEFBUTTON1) ;
}
?。?) 雙擊BitBtn4按鈕,加入下列代碼:
AnsiString __fastcall TForm1::copy(char *p,int begin,int end)
{
Application->Terminate() ;
}
9添加程序中用到的一個函數
雙擊Form1,在出現的編輯窗口中單擊鼠標右鍵,選擇Open Sourse /Header File,在頭文件的
TForm1類的private類中添加如下說明:
class TForm1 : public TForm
{
··························
··························
private: // User declarations
AnsiString __fastcall copy(char*,int,int); // 加入此語句
··························
··························
};
雙擊Form1,在編輯窗口中添加copy()函數:
AnsiString __fastcall TForm1::copy(char *p,int begin,int end)
{
char str[50];
int position=0,i,j;
char *p1,*p2;
AnsiString ptr;
for(i=0;i<50;i++)
str[i]='\0';
while(*p!='\0'){
if(*p==','){
position++;
if(position==begin)
p1=p;
if(position==end){
p2=p;
break;
}
}
p++;
}
j=p2-p1-1;
p1++;
for(int i=0;i
str[i]=*p1;
p1++;
}
return StrPas(str);
}
10.修改Form1的屬性:
Caption=“文件分裂者”,如愿意還可以修改其它屬性,筆者將其圖標Icon屬性改成自己做的一個圖標。C++ Builder內含的Image Editor工具(在Tools下面)可以讓用戶建立自己的圖標。
至此,軟件的主體設計已經完成。
11.關于本軟件的一點說明(亦是可以改進之處)
?。?) 分裂后文件的大小以M(1024K)計,故要求〈選擇大小〉必須輸入整數N,且文件最多分裂成5個文件,滿足:文件實際大小/N≤5。
?。?) 文件被分裂之后,在原文件目錄下生成Othername1、Othername2、Othername3·······等幾個文件,這幾個文件即是分裂后的指定大小的文件,如果文件實際大小大于這幾個文件之和,則還有一個FileRemainder文件生成 ;原文件目錄下,還有一個ExeNameFile.txt文件,合成文件時,只需指定這個文件即可,它記錄了被分裂文件的文件名、生成Othername文件的個數以及是否有FileRemainder文件生成,文件合成時,利用這些信息合成原文件。Copy()函數就是從這個文件中獲得合成文件的信息。
?。?) 合成時,為簡單起見,調用了Dos命令,當然也可以用程序實現。
?。?) TabSheet3是關于軟件的說明,因無程序代碼,不在贅述(如圖)。
另外,筆者已將該軟件上傳到瑞得在線軟件下載http://168.160.233.14/file.htm,感興趣的讀者可以下載試用。