C++ Builder中各種資源的利用

工作單位: 煙臺南大街建行科技部

    在編寫程序的過程中,經常要用到各種資源。比如說,想給自己的程序換個自己的圖標,使用一些活潑的光標來增加趣味性,播放一些聲音和動畫文件,或者使用別人寫好的程序來實現某個功能。我們往往希望將這些資源直接放到EXE文件中以形成一個單獨的可執行文件,這就存在一個如何在運行時訪問和使用這些資源的問題。
    
  ----在編譯期間,這就要用到一種文件,以.rc結尾的資源定義文件。
    
  ----一:RC文件
    
  ---- rc文件是個文本文件,它的格式很簡單,按如下格式定義:
    
  ----資源標識符資源類型資源的路徑
    
  ----以下的rc文件定義了一個聲音資源,兩個光標資源,三個圖標資源和一個exe文件資源。
    
src1.rc:
  S1        WAV     wav1.Wav
  C1        CURSOR  cursor1.cur
  C2        CURSOR  cursor2.cur
  I1        ICON    icone1.ico
  I2        ICON    icone2.ico
  I3        ICON    icone3.ico
  unzip     EXEFILE  pkunzip.exe

    
  ----你可以將寫好的rc文件加到你
   的project(項目)中。你也可以手工將其編譯爲供程序直接使用的二進制資源文件(.res文件)。在BCB3.0中,可以使用命令行:brcc32 src1.rc src1.res。
    
  ----二:資源的使用
    
  ----下面,按照使用的簡繁程度,依次說明各類資源的使用方法。需要說明的是,下面講述的使用方法,在別的編譯環境下(BC, VC等)也是一樣的。
    
  ---- 1:建立一個新的項目
  ----啓動BCB3.0,選FILE- >new- >Application 建立一個新的項目。
    
  ----在project- >Add to Project中,加入寫好的src1.rc文件。當然,那些聲音、光標、圖標文件都應該存在。
    
  ----這時,我們有了一個空的窗體(Form)。
    
    
  ---- 2:能夠利用windows API函數直接訪問的資源有:
    
圖標   LoadIcon()
光標   LoadCursor()
加速表 LoadAccelerators()
位圖   LoadBitmap()
菜單   LoadMenu()
字符串 LoadString()

    
  ----前五個API函數使用方法都一樣,帶兩個參數。
    
  ----第一個參數指明資源的存放地,第二個參數爲rc文件中資源的標識。
    
  ----字符串LoadString除這兩個參數外,還有兩個參數,指明字符串緩衝區的地址和大小。
    
  ----下面的一小段程序示範了圖標和光標的使用。
    
  ----在Form上放置一個按紐,在其OnClick事件中加入以下代碼:
    
void __fastcall TForm1::Button1Click(Tobject *Sender)
{
   //將光標形狀改爲自己定義的:
  Screen- >Cursors[crDefault] = LoadCursor( Hinstance, "C1");
  //將圖標改爲自己定義的:
  Icon = new Ticon() ;
  Icon- >Handle = LoadIcon(Hinstance,"I1");
  Application- >Icon = Icon ;
}

  ----其中的Hinstance指示資源所在地爲執行文件。編譯執行後,點擊該按紐,光標和圖標都會換成新的。
    
  ---- 3:能夠通過windows API使用的資源
  ----對於聲音、動畫等文件,可以使用windows API函數播放。但是不象上面幾種資源,需要遵循一定的步驟。如下所示,依次調用FindResource, LoadResource, LockResource函數,來播放一個Wav聲音文件。
    
  ----(當然,獨立的聲音文件可以在運行時直接播放。我們這裏討論的是將wav文件編譯進EXE文件的情況)
    
  ----在Form上放置第二個按紐,在其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文件裝載在內存中,
    sndPlaySound函數要用SND_MEMORY參數
sndPlaySound(wav_handle, SND_MEMORY | SND_SYNC);
}

    
  ----編譯執行後,點擊該按紐,會播放一次聲音。
    
  ----對於動畫等文件,使用方式類似Wav文件。(BCB提供了一個Tanimate控件,可以播放無聲的Avi文件)
    
  ---- 4:不能直接通過windows API使用的資源    
  ----此種資源不能夠由windows API直接訪問和執行。但是,我們可以用一種變通的方法來使用它。
    
  ----下面示範如何使用pkunzip.exe,思路如下:程序運行時,將pkunzip.exe從EXE文件中分離出來,放在臨時目錄下,用ShellExecute()執行它。
    
  ----在FORM上放置第三個按紐,在放置兩個Edit ,用來輸入pkunzip.exe的參數。
    
void __fastcall TForm1::Button3Click(Tobject *Sender)
{
char exefile[100], tmppath[100] ;
    unsigned long ret ;
    //檢查pkunzip.exe是否已經存在
GetTempPath( 100, tmppath ) ;
    strcpy( exefile ,(AnsiString(tmppath)+
     AnsiString("/pkunzip.exe") ).c_str() ) ;
ret = GetFileAttributes( exefile ) ;
    if( ret == 0xffffffff )
     { //不存在,則分離出pkunzip.exe
          TResourceStream &rs = *new TResourceStream( (int)Hinstance, AnsiString("unzip"),"EXEFILE" ) ;
    rs.SaveToFile( AnsiString(exefile) ) ;
           delete &rs ;
   }
  //執行pkunzip.exe
// Edit1- >Text和Edit2- >Text分別爲運行時輸入的zip文件名和目標文件目錄。
ShellExecute(Hinstance, "open", exefile, AnsiString("-d ") + Edit1- >Text + " " + Edit2- >Text).c_str(), tmppath, SW_HIDE ) ;
        Application- >MessageBox("解壓縮完成", "OK", IDOK ) ;
}

    
  ----此種方法實際上是用時間和空間來換取便利性,有一定的參考價值。例如,DynaDoc的免費分發版本,就是將真正的執行程序壓縮後放在一個有解壓縮功能的“殼”中。運行時,首先是“殼”運行起來,將真正的執行程序解壓縮到臨時目錄,然後去運行它。如果你的程序含有大量的BMP,WAV文件,不妨一試,能讓你的程序減肥不少。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章