Visual C++實現Flash動畫播放
資訊產業部電子第二十二研究所青島分所 郎銳
摘要: 本文通過在VC中將外部swf格式檔案內嵌為VC的內部資源,使其在程式運行過程中從資源動態釋放到臨時檔案,從而實現VC對Flash動畫的播放。
引言
Flash動畫由於可以很方便地把使用者的想象通過動畫顯現出來,使原本只屬於專業製作人員的動畫製作變的異乎尋常的快捷、方便。由於Flash製作的動畫在層次、內容、表現形式等諸多方面均比較出色,因此在網路上得到迅猛的發展,更有不少廠商用Flash在互連網上做起了廣告和產品示範,效果絲毫不比視頻的差,而體積則要小的多。Flash不僅在網路上有廣泛的應用,在普通的應用程式中也可以藉助Flash實現一些VC、Delphi等程式設計語言所難以實現的特效,比如在一些示範版的程式中完全可以將程式運行前的閃屏用Flash來製作。本文下面將通過對內嵌資源的動態釋放來實現VC對Flash動畫的播放,並給出了部分實現代碼。
嵌資源的動態釋放
Flash動畫在此是作為程式的一個模組,雖然也可以以檔案的形式作為一個外部資源來使用,但為了避免因外部模組遺失而造成程式的非正常運行,可將由Flash 5.0預先製作好的swf格式的檔案以資源的形式打包到應用程式中去,而在程式運行時再將其從資源恢複到檔案,使用完畢再通過程式將其從磁碟刪除。
在匯入資源時由於swf格式檔案並非VC的標準資源,所以在匯入時需要在"Resource type"欄指定資源類型"SWF",特別需要注意的是在此必須要包含引號。加入到資源後可以通過資源檢視看到匯入的SWF資源是以二進位形式儲存的,一但加入就不能再通過資源檢視對其進行編輯了。
在使用SWF資源前首先要將其動態從應用程式中釋放到檔案中才可對資源做進一步的使用。可先通過宏MAKEINTRESOURCE()將資源標識號IDR_SWF轉換成字串Name,再分別通過FindResource()、LoadResource()函數尋找、裝載該資源到記憶體:
CString Type="swf";
HRSRC res=FindResource (NULL,Name,Type);
HGLOBAL gl=LoadResource (NULL,res);
當資源載入到記憶體後,還要通過對資源記憶體的鎖定來返回指向資源記憶體的地址的指標,並籍此實現資源從記憶體到磁碟的儲存,至於存檔的操作則由檔案函數CreateFile()、和WriteFile()來完成:
LPVOID lp=LockResource(gl); //返回指向資源記憶體的地址的指標。
CString filename="Temp.swf"; //儲存的臨時檔案名稱
// CREATE_ALWAYS為不管檔案存不存在都產生新檔案。
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); //關閉控制代碼
FreeResource (gl); //釋放記憶體
通過上述代碼,可將SWF資源從應用程式中提取並釋放到臨時檔案Temp.swf中,在此後只對此臨時檔案操作,與程式內嵌資源無關。
Flash動畫的播放
swf格式的Flash動畫通常主要應用在網頁上,也就是說IE瀏覽器本身可以支援Flash動畫的播放。這樣就不必再單獨編寫用於播放swf檔案的代碼,從而大大減少編程的工作量。在VC ++ 6.0中新增了一個從CView派生的、用於處理網頁的視類CHtmlView,由於該類是以Internet Explorer為後台支援,因此在建立工程時只需在最後一步指定視類從CHtmlView派生就可以使程式不編一行代碼而具備IE瀏覽器的網頁顯示能力。
程式剛產生的時候預設的串連首頁是為微軟公司的首頁,需要對此修改,使程式在執行時立即顯示剛才提取出來的Flash臨時檔案Temp.swf。顯示預設首頁的代碼是在視類的初始化函數中進行的:
void CEmbedModuleView::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
Navigate2(_T("http://www.microsoft.com" ,NULL,NULL);
}
顯然要將Navigate2()函數的第一個參數改成Temp.swf的存放路徑。剛才在釋放資源到檔案時並沒有指定絕對路徑,因此釋放出來的資源檔應當和應用程式處於同一目錄。但是在此處如果不寫明絕對路徑是無法顯示該臨時檔案的。擷取該臨時檔案的絕對路徑可用如下方法實現:先擷取應用程式本身的絕對路徑,然後去處應用程式全名(程式名和副檔名)此時得到的是應用程式和臨時檔案所處檔案夾的路徑,最後只需在此基礎上加上臨時檔案的檔案名稱Temp.swf即可得到臨時檔案的全路徑。下面是實現的主要代碼:
//擷取應用程式的全路徑
char exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);
//將其格式化為字串
m_TempFile.Format("%s",exeFullPath);
//去掉應用程式的全名(15為應用程式檔案全名的長度)
exeFullPath[m_TempFile.GetLength()-15]='/0';
//得到應用程式所在路徑
m_TempFile.Format("%s",exeFullPath);
//得到臨時檔案的全路徑
m_TempFile+="Temp.swf";
最後將得到的臨時檔案的全路徑m_TempFile作為參數傳遞給Navigate2()即可在程式運行時把Flash動畫作為首頁而顯示(如所示)。
由於臨時檔案Temp.swf是在程式運行過程中從應用程式的資源中提取出來的,因此在程式退出之前需要將其刪除。一般是在訊息WM_DESTORY的響應函數裡通過DeleteFile()函數來加以實現的。
小結
本文通過對CHtmlView和內嵌資源的動態釋放實現了Flash動畫在VC程式中的播放,並對資源的動態釋放作了較為清晰的描述。通過類似的方法,可以將動態連結程式庫、HTML檔案等程式模組作為資源嵌入其中,在使用時再動態釋放到臨時檔案,這樣可有效避免檔案模組過多時的雜亂以及程式模組丟失導致程式非正常運行等情況的發生。本文所述程式在Windows 98下,由Microsoft Visual C++ 6.0編譯通過。Flash動畫由 Macromedia Flash 5.0製作,所需瀏覽器支援為Internet Explorer 6.0。