摘要: 本文通過在VC中將外部swf格式文件內(nèi)嵌為VC的內(nèi)部資源,使其在程序運(yùn)行過程中從資源動(dòng)態(tài)釋放到臨時(shí)文件,從而實(shí)現(xiàn)VC對(duì)Flash動(dòng)畫的播放。
引言
Flash動(dòng)畫由于可以很方便地把用戶的想象通過動(dòng)畫顯現(xiàn)出來,使原本只屬于專業(yè)制作人員的動(dòng)畫制作變的異乎尋常的快捷、方便。由于Flash制作的動(dòng)畫在層次、內(nèi)容、表現(xiàn)形式等諸多方面均比較出色,因此在網(wǎng)絡(luò)上得到迅猛的發(fā)展,更有不少廠商用Flash在互聯(lián)網(wǎng)上做起了廣告和產(chǎn)品演示,效果絲毫不比視頻的差,而體積則要小的多。Flash不僅在網(wǎng)絡(luò)上有廣泛的應(yīng)用,在普通的應(yīng)用程序中也可以借助Flash實(shí)現(xiàn)一些VC、Delphi等編程語言所難以實(shí)現(xiàn)的特效,比如在一些演示版的程序中完全可以將程序運(yùn)行前的閃屏用Flash來制作。本文下面將通過對(duì)內(nèi)嵌資源的動(dòng)態(tài)釋放來實(shí)現(xiàn)VC對(duì)Flash動(dòng)畫的播放,并給出了部分實(shí)現(xiàn)代碼。
嵌資源的動(dòng)態(tài)釋放
Flash動(dòng)畫在此是作為程序的一個(gè)模塊,雖然也可以以文件的形式作為一個(gè)外部資源來使用,但為了避免因外部模塊遺失而造成程序的非正常運(yùn)行,可將由Flash 5.0預(yù)先制作好的swf格式的文件以資源的形式打包到應(yīng)用程序中去,而在程序運(yùn)行時(shí)再將其從資源恢復(fù)到文件,使用完畢再通過程序?qū)⑵鋸拇疟P刪除。
在導(dǎo)入資源時(shí)由于swf格式文件并非VC的標(biāo)準(zhǔn)資源,所以在導(dǎo)入時(shí)需要在"Resource type"欄指定資源類型"SWF",特別需要注意的是在此必須要包含引號(hào)。加入到資源后可以通過資源視圖看到導(dǎo)入的SWF資源是以二進(jìn)制形式保存的,一但加入就不能再通過資源視圖對(duì)其進(jìn)行編輯了。
在使用SWF資源前首先要將其動(dòng)態(tài)從應(yīng)用程序中釋放到文件中才可對(duì)資源做進(jìn)一步的使用??上韧ㄟ^宏MAKEINTRESOURCE()將資源標(biāo)識(shí)號(hào)IDR_SWF轉(zhuǎn)換成字符串Name,再分別通過FindResource()、LoadResource()函數(shù)查找、裝載該資源到內(nèi)存:
CString Type="swf";
HRSRC res=FindResource (NULL,Name,Type);
HGLOBAL gl=LoadResource (NULL,res);
當(dāng)資源加載到內(nèi)存后,還要通過對(duì)資源內(nèi)存的鎖定來返回指向資源內(nèi)存的地址的指針,并籍此實(shí)現(xiàn)資源從內(nèi)存到磁盤的保存,至于存盤的操作則由文件函數(shù)CreateFile()、和WriteFile()來完成:
LPVOID lp=LockResource(gl); //返回指向資源內(nèi)存的地址的指針。
CString filename="Temp.swf"; //保存的臨時(shí)文件名
// CREATE_ALWAYS為不管文件存不存在都產(chǎn)生新文件。
fp= CreateFile(filename ,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
DWORD a;
//sizeofResource 得到資源文件的大小
if (!WriteFile (fp,lp,SizeofResource (NULL,res),&a,NULL))
return false;
CloseHandle (fp); //關(guān)閉句柄
FreeResource (gl); //釋放內(nèi)存
通過上述代碼,可將SWF資源從應(yīng)用程序中提取并釋放到臨時(shí)文件Temp.swf中,在此后只對(duì)此臨時(shí)文件操作,與程序內(nèi)嵌資源無關(guān)。
Flash動(dòng)畫的播放
swf格式的Flash動(dòng)畫通常主要應(yīng)用在網(wǎng)頁上,也就是說IE瀏覽器本身可以支持Flash動(dòng)畫的播放。這樣就不必再單獨(dú)編寫用于播放swf文件的代碼,從而大大減少編程的工作量。在VC ++ 6.0中新增了一個(gè)從CView派生的、用于處理網(wǎng)頁的視類CHtmlView,由于該類是以Internet Explorer為后臺(tái)支持,因此在創(chuàng)建工程時(shí)只需在最后一步指定視類從CHtmlView派生就可以使程序不編一行代碼而具備IE瀏覽器的網(wǎng)頁顯示能力。
程序剛生成的時(shí)候缺省的連接主頁是為微軟公司的主頁,需要對(duì)此修改,使程序在執(zhí)行時(shí)立即顯示剛才提取出來的Flash臨時(shí)文件Temp.swf。顯示缺省主頁的代碼是在視類的初始化函數(shù)中進(jìn)行的:
void CEmbedModuleView::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
Navigate2(_T("http://www.microsoft.com"),NULL,NULL);
}
顯然要將Navigate2()函數(shù)的第一個(gè)參數(shù)改成Temp.swf的存放路徑。剛才在釋放資源到文件時(shí)并沒有指定絕對(duì)路徑,因此釋放出來的資源文件應(yīng)當(dāng)和應(yīng)用程序處于同一目錄。但是在此處如果不寫明絕對(duì)路徑是無法顯示該臨時(shí)文件的。獲取該臨時(shí)文件的絕對(duì)路徑可用如下方法實(shí)現(xiàn):先獲取應(yīng)用程序本身的絕對(duì)路徑,然后去處應(yīng)用程序全名(程序名和擴(kuò)展名)此時(shí)得到的是應(yīng)用程序和臨時(shí)文件所處文件夾的路徑,最后只需在此基礎(chǔ)上加上臨時(shí)文件的文件名Temp.swf即可得到臨時(shí)文件的全路徑。下面是實(shí)現(xiàn)的主要代碼:
//獲取應(yīng)用程序的全路徑
char exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);
//將其格式化為字符串
m_TempFile.Format("%s",exeFullPath);
//去掉應(yīng)用程序的全名(15為應(yīng)用程序文件全名的長度)
exeFullPath[m_TempFile.GetLength()-15]='\0';
//得到應(yīng)用程序所在路徑
m_TempFile.Format("%s",exeFullPath);
//得到臨時(shí)文件的全路徑
m_TempFile+="Temp.swf";
最后將得到的臨時(shí)文件的全路徑m_TempFile作為參數(shù)傳遞給Navigate2()即可在程序運(yùn)行時(shí)把Flash動(dòng)畫作為主頁而顯示
由于臨時(shí)文件Temp.swf是在程序運(yùn)行過程中從應(yīng)用程序的資源中提取出來的,因此在程序退出之前需要將其刪除。一般是在消息WM_DESTORY的響應(yīng)函數(shù)里通過DeleteFile()函數(shù)來加以實(shí)現(xiàn)的。
小結(jié)
本文通過對(duì)CHtmlView和內(nèi)嵌資源的動(dòng)態(tài)釋放實(shí)現(xiàn)了Flash動(dòng)畫在VC程序中的播放,并對(duì)資源的動(dòng)態(tài)釋放作了較為清晰的描述。通過類似的方法,可以將動(dòng)態(tài)鏈接庫、HTML文件等程序模塊作為資源嵌入其中,在使用時(shí)再動(dòng)態(tài)釋放到臨時(shí)文件,這樣可有效避免文件模塊過多時(shí)的雜亂以及程序模塊丟失導(dǎo)致程序非正常運(yùn)行等情況的發(fā)生。本文所述程序在Windows 98下,由Microsoft Visual C++ 6.0編譯通過。Flash動(dòng)畫由 Macromedia Flash 5.0制作,所需瀏覽器支持為Internet Explorer 6.0。