提出問題:使用CAnimateCtrl::Open( LPCTSTR lpszFileName )時,參數lpszFileName 是個字符串,表示AVI文件名。因此在分發應用程序時,除了分發可執行程序外,還必須單獨分發AVI文件。是否有辦法從資源中得到AVI文件?
在這個程序中,如果要從外部獲取文件是相當不方便的,萬一誰不小心將文件刪除或改名的話。。。。所以最好的方法是將文件作為資源存儲在可執行文件中。幸虧CAnimateCtrl類有一個成員函數 CAnimateCtrl::Open 以UINT為參數,也就是說,它UINT可以是資源的ID號。
但是如何將AVI文件放入EXE文件呢?這是需要技巧的。animation控件尋找AVI類型的資源,所以你要做的事情是在資源文件(.rc)中加入代碼:
IDR_MYANIMATION AVI DISCARDABLE "res\\myanim.avi"
事先必須定義IDR_MYANIMATION為一個整型數,(注意不能使用一個串名作為資源)並且AVI文件要放在工程目錄下的RES目錄中。資源編譯器會一個字節一個字節地將myanim.avi拷貝到可執行文件中,以便動畫控件能找到它。
另外,使用相同的方法可以將任何文件作為資源放入EXE文件。方法是:
IDR_MYFOOFILE FOO DISCARDABLE "res\\myanim.foo"
一旦在EXE文件中包含了foo類型文件,如何訪問它呢?那就需要自己寫一些代碼。首先,你必須調用FindResource函數來獲得資源句柄。
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource(hInst,
MAKEINTRESOURCE(IDR_MYFOOFILE), // ID
"FOO"); // type
ASSERT(hRsrc);
假設hRsrc非空,再調用兩個函數來獲得資源(FOO文件)的大小及數據本身。
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
ASSERT(lpRsrc);
現在,在內存中lpRsrc指向FOO文件,如果你想要象訪問普通磁盤文件一樣訪問這個內存,可以使用類庫的CMemFile,它將一塊存儲區域當作CFile來對待。
CMemFile file(lpRsrc, len);
file.Read(...); // etc.
你甚至可以象重載OnOpenDocument打開磁盤文件一樣用CDocument打開資源。