C++ Builder中各種資源的利用
2019-09-06 23:33:26
供稿:網(wǎng)友
工作單位: 煙臺(tái)南大街建行科技部
在編寫程序的過(guò)程中,經(jīng)常要用到各種資源。比如說(shuō),想給自己的程序換個(gè)自己的圖標(biāo),使用一些活潑的光標(biāo)來(lái)增加趣味性,播放一些聲音和動(dòng)畫文件,或者使用別人寫好的程序來(lái)實(shí)現(xiàn)某個(gè)功能。我們往往希望將這些資源直接放到EXE文件中以形成一個(gè)單獨(dú)的可執(zhí)行文件,這就存在一個(gè)如何在運(yùn)行時(shí)訪問和使用這些資源的問題。
----在編譯期間,這就要用到一種文件,以.rc結(jié)尾的資源定義文件。
----一:RC文件
---- rc文件是個(gè)文本文件,它的格式很簡(jiǎn)單,按如下格式定義:
----資源標(biāo)識(shí)符資源類型資源的路徑
----以下的rc文件定義了一個(gè)聲音資源,兩個(gè)光標(biāo)資源,三個(gè)圖標(biāo)資源和一個(gè)exe文件資源。
src1.rc:
S1/tWAV wav1.Wav
C1/tCURSOR cursor1.cur
C2/tCURSOR cursor2.cur
I1/tICON icone1.ico
I2/tICON icone2.ico
I3/tICON icone3.ico
unzip EXEFILE pkunzip.exe
----你可以將寫好的rc文件加到你
的project(項(xiàng)目)中。你也可以手工將其編譯為供程序直接使用的二進(jìn)制資源文件(.res文件)。在BCB3.0中,可以使用命令行:brcc32 src1.rc src1.res。
----二:資源的使用
----下面,按照使用的簡(jiǎn)繁程度,依次說(shuō)明各類資源的使用方法。需要說(shuō)明的是,下面講述的使用方法,在別的編譯環(huán)境下(BC, VC等)也是一樣的。
---- 1:建立一個(gè)新的項(xiàng)目
----啟動(dòng)BCB3.0,選FILE- >new- >Application 建立一個(gè)新的項(xiàng)目。
----在project- >Add to Project中,加入寫好的src1.rc文件。當(dāng)然,那些聲音、光標(biāo)、圖標(biāo)文件都應(yīng)該存在。
----這時(shí),我們有了一個(gè)空的窗體(Form)。
---- 2:能夠利用windows API函數(shù)直接訪問的資源有:
圖標(biāo) LoadIcon()
光標(biāo) LoadCursor()
加速表 LoadAccelerators()
位圖 LoadBitmap()
菜單 LoadMenu()
字符串 LoadString()
----前五個(gè)API函數(shù)使用方法都一樣,帶兩個(gè)參數(shù)。
----第一個(gè)參數(shù)指明資源的存放地,第二個(gè)參數(shù)為rc文件中資源的標(biāo)識(shí)。
----字符串LoadString除這兩個(gè)參數(shù)外,還有兩個(gè)參數(shù),指明字符串緩沖區(qū)的地址和大小。
----下面的一小段程序示范了圖標(biāo)和光標(biāo)的使用。
----在Form上放置一個(gè)按紐,在其OnClick事件中加入以下代碼:
void __fastcall TForm1::Button1Click(Tobject *Sender)
{
//將光標(biāo)形狀改為自己定義的:
Screen- >Cursors[crDefault] = LoadCursor( Hinstance, "C1");
//將圖標(biāo)改為自己定義的:
Icon = new Ticon() ;
Icon- >Handle = LoadIcon(Hinstance,"I1");
Application- >Icon = Icon ;
}
----其中的Hinstance指示資源所在地為執(zhí)行文件。編譯執(zhí)行后,點(diǎn)擊該按紐,光標(biāo)和圖標(biāo)都會(huì)換成新的。
---- 3:能夠通過(guò)windows API使用的資源
----對(duì)于聲音、動(dòng)畫等文件,可以使用windows API函數(shù)播放。但是不象上面幾種資源,需要遵循一定的步驟。如下所示,依次調(diào)用FindResource, LoadResource, LockResource函數(shù),來(lái)播放一個(gè)Wav聲音文件。
----(當(dāng)然,獨(dú)立的聲音文件可以在運(yùn)行時(shí)直接播放。我們這里討論的是將wav文件編譯進(jìn)EXE文件的情況)
----在Form上放置第二個(gè)按紐,在其OnClick事件中加入以下代碼:
void __fastcall TForm1::Button2Click(Tobject *Sender)
{
//定義資源塊
char *wav_handle ;
//裝入Wav文件
HRSRC h = FindResource(Hinstance,"S1","WAV");
HGLOBAL h1 = LoadResource(Hinstance, h);
wav_handle = (char *)LockResource(h1);
//播放Wav文件。由于Wav文件裝載在內(nèi)存中,
sndPlaySound函數(shù)要用SND_MEMORY參數(shù)
sndPlaySound(wav_handle, SND_MEMORY | SND_SYNC);
}
----編譯執(zhí)行后,點(diǎn)擊該按紐,會(huì)播放一次聲音。
----對(duì)于動(dòng)畫等文件,使用方式類似Wav文件。(BCB提供了一個(gè)Tanimate控件,可以播放無(wú)聲的Avi文件)
---- 4:不能直接通過(guò)windows API使用的資源
----此種資源不能夠由windows API直接訪問和執(zhí)行。但是,我們可以用一種變通的方法來(lái)使用它。
----下面示范如何使用pkunzip.exe,思路如下:程序運(yùn)行時(shí),將pkunzip.exe從EXE文件中分離出來(lái),放在臨時(shí)目錄下,用ShellExecute()執(zhí)行它。
----在FORM上放置第三個(gè)按紐,在放置兩個(gè)Edit ,用來(lái)輸入pkunzip.exe的參數(shù)。
void __fastcall TForm1::Button3Click(Tobject *Sender)
{
char exefile[100], tmppath[100] ;
unsigned long ret ;
//檢查pkunzip.exe是否已經(jīng)存在
GetTempPath( 100, tmppath ) ;
strcpy( exefile ,(AnsiString(tmppath)+
AnsiString("/pkunzip.exe") ).c_str() ) ;
ret = GetFileAttributes( exefile ) ;
if( ret == 0xffffffff )
{ //不存在,則分離出pkunzip.exe
/t TResourceStream &rs = *new TResourceStream( (int)Hinstance, AnsiString("unzip"),"EXEFILE" ) ;
rs.SaveToFile( AnsiString(exefile) ) ;
/t delete &rs ;
}
//執(zhí)行pkunzip.exe
// Edit1- >Text和Edit2- >Text分別為運(yùn)行時(shí)輸入的zip文件名和目標(biāo)文件目錄。
ShellExecute(Hinstance, "open", exefile, AnsiString("-d ") + Edit1- >Text + " " + Edit2- >Text).c_str(), tmppath, SW_HIDE ) ;
/tApplication- >MessageBox("解壓縮完成", "OK", IDOK ) ;
}
----此種方法實(shí)際上是用時(shí)間和空間來(lái)?yè)Q取便利性,有一定的參考價(jià)值。例如,DynaDoc的免費(fèi)分發(fā)版本,就是將真正的執(zhí)行程序壓縮后放在一個(gè)有解壓縮功能的“殼”中。運(yùn)行時(shí),首先是“殼”運(yùn)行起來(lái),將真正的執(zhí)行程序解壓縮到臨時(shí)目錄,然后去運(yùn)行它。如果你的程序含有大量的BMP,WAV文件,不妨一試,能讓你的程序減肥不少。