1. 程式人生 > >MFC和FLASH互動

MFC和FLASH互動

一、準備工作

第一步:下載並安裝Adobe Flash Player。

從官方網站(http://get.adobe.com/cn/flashplayer/)上下載最新的Flash Player(大約為2.66M),並安裝。對於Windows 32位系統,其預設安裝目錄為:C:\WINDOWS\system32\Macromed\Flash\;對於64位系統,為:C:\Windows\SysWOW64\Macromed\Flash。

      Flash控制元件的大版本號用數字表示,如9,10,11等,小版本號用小寫字母表示,如a, b, c, d, e。如我安裝的版本為:Flash10l.ocx。

第二步:通過regsvr32.exe註冊flash控制元件 Flash10l.ocx。

       從開始選單中開啟執行對話方塊,並輸入:

regsvr32 C:\Windows\SysWOW64\Macromed\Flash\Flash10l.ocx 註冊該控制元件(註冊之後就可以在專案中進行控制元件添加了),如果註冊成功,有如下提示:

     登出控制元件的命令列為

regsvr32 /u C:\Windows\SysWOW64\Macromed\Flash\Flash10l.ocx。

二、新建MFC專案,新增Flash控制元件

第一步:建立基於對話方塊的MFC程式。

開啟Visual Studio 2010,新建專案,選擇“MFC應用程式”,並將其命名為MFCFlash。

在接下來的選型設定中,選擇應用程式型別為“基於對話方塊”,其他可按預設設定。專案建成後,程式預設添加了MFCFlash和MFCFlashDlg的標頭檔案和實現檔案,截圖如下:

第二步:新增Shockwave Flash Object類。

VC++ 6.0中,可以使用ClassWizard新增ActiveX控制元件,而VS2005以後的版本沒有。如果要新增ActiveX對應的類,可以先在解決方案管理器中選中專案後在選單中點“專案”

→“新增類”→“ActiveX控制元件中的MFC類”,開啟“從ActiveX控制元件新增類嚮導”對話方塊。選擇從“檔案”新增類,找到Flash控制元件的安裝位置,即可新增Shockwave Flash控制元件,介面選擇“IShockwaveFlash”,以生成CShockwaveFlash類(類的名稱可以修改)。插入後,VC會自動把這個類加入工程裡面。

第三步:新增Shockwave Flash Object控制元件。

在資源視圖裡找到“Dialog”,並選擇其中的IDD_MFCFLASH_DIALOG,在其上點右鍵,選擇“插入ActiveX控制元件”,從彈出的列表中選擇“Shockwave Flash Object”。

使用BUTTON、EDIT等其它Windows控制元件一樣,我們可以使用這個類的成員函式來操縱這個物件,來進行Flash動畫的控制以及和自己的程式進行互動等操作了。在Flash控制元件上點右鍵,然後選擇“新增變數”,設定“變數名”為:m_FlashPlayer。可再次在Flash控制元件上點右鍵,然後選擇“屬性”,將其ID改為IDC_SHOCKWAVEFLASH。

第四步:使用成員函式LoadMovie和Play來匯入並播放動畫。

在MFCFlashDlg.cpp檔案中,找到CMFCFlashDlg::OnInitDialog()函式,在“return TRUE”之前新增程式碼:

      CString str = _T("E:\\VS\\Flash\\media\\test.swf");

      m_FlashPlayer.LoadMovie (0, str);

      m_FlashPlayer. Play ();

其中m_FlashPlayer.LoadMovie(0, str)用來將動畫匯入程式中,str為要播放的flash路徑,要用絕對路徑(注意路徑用雙斜槓“\\”隔開); m_FlashPlayer. Play ()開始播放動畫。

相對路徑轉絕對路徑:

wchar_t szPath[MAX_PATH];

    memset(szPath, 0, sizeof(CHAR)*MAX_PATH);

    GetCurrentDirectory(MAX_PATH, szPath);

    StrCat(szPath, _T("\\風扇.swf"));

自己嘗試了一下:

再初始化中:

	//開啟Flash
	wchar_t szPath[MAX_PATH];//全路徑 也就是當前執行程式的全路徑
	memset(szPath, 0, sizeof(CHAR)*MAX_PATH);
	GetCurrentDirectory(MAX_PATH, szPath);
	StrCat(szPath, _T("\\Flash\\Face.swf"));
	m_FlashPlayer.LoadMovie(0, szPath);//載入
	m_FlashPlayer.Play();//播放

	//全屏
	ShowWindow(SW_SHOWMAXIMIZED);//背景全屏
	m_FlashPlayer.SetWindowPos(this, 0, 0, 1920, 1080, SWP_NOZORDER);//Flash全屏

現在執行程式,就可以看到flash嵌入到程式裡面了。還有幾個常用的函式可以用來控制動畫的播放,如GotoFrame(long FrameNum)可以轉到FrameNum偵播放(偵數從0開始),StopPlay()可以停止播放。。。,還有很多,可以自己試試。下圖是我做的一個飛行儀表,介面比較醜陋,湊合看吧^_^

三、實現MFCFlash的通訊

1Flash通過FSCommand訊息呼叫MFC

第一步:新增訊息處理函式。

在Flash控制元件上點右鍵,然後選擇“新增事件處理程式”,在類列表選擇“CMFCFlashDlg”,訊息型別選擇“FSCommand”,則函式處理程式名稱自動為“FSCommandShockwaveflash”。它的形式大概是這樣子的:

  void CMFCFlashDlg::OnFSCommandShockwaveflash(LPCTSTR command, LPCTSTR args) ;函式有兩個引數,就是flash的Action Script中FSCommand語句中的兩個引數。其實並不一定兩個引數都用到,flash指令碼中可以就使用一個引數,這樣這邊的函式就只要對第一個引數進行處理就行了。

第二步:編寫訊息處理程式碼。

在剛新增的FSCommand訊息處理函式中,對兩個引數進行處理。其實就是做字串比較的操作,根據是什麼字串來判斷使用者進行了什麼操作。大概就是這樣子的:

  void CPlayFlashDlg::OnFSCommandShockwaveflash1(LPCTSTR command, LPCTSTR args)
{
  // TODO: Add your control notification handler code here
  if( 0 == strcmp(command,”bt”) )
  {
    if( 0 == strcmp(args,”enter”) )
    {
      MessageBox(“歡迎進入系統!”);
    }
  }
  else if( 0 == strcmp(command,”quit”) )
  {
    MessageBox(“您選擇了退出!”);
    CDialog::OnCancel();
  }
}    

這只是最簡單的處理形式,當然你可以在flash中傳送複雜的字串,在這邊就要進行更多的處理了。

2MFC通過CallFunction函式呼叫Flash

第一步:Flash中ExternalInterface.addCallback用處理。

在FLASH中,要用ExternalInterface.addCallback把能被外部呼叫的函式註冊一下,例如:ExternalInterface.addCallback("setAlt", setAlt);

function setAlt (para:String = "3150")

{

       alt.text = para; //alt為swf檔案中的一個動態文字

}

我自己:在Flash中先新增一下庫

import flash.external.ExternalInterface;

然後在main函式裡面新增這段,需要新增判斷

if (ExternalInterface.available)
			{
				ExternalInterface.addCallback("setAlt", setAlt);//mfc發訊息給flash
			}

main函式外面新增這段程式碼,此時在MFC中按鍵檢測就可以出發Flash中需要觸發的函數了

	//mfc發訊息給flash
		public function setAlt (para:String = "3150")
		{
			//readyCapture();//MFC需要Flash執行的函式
		}	

MFC中使用CallFunction函式傳入引數。

想讓MFC主動往flash傳內容並且讓flash響應,用控制元件的CallFunction方法。在MFC中,呼叫CallFunction方法,傳入一個比較複雜的字串,描述了要呼叫的函式的名稱、引數等等,以XML的形式呈現。詳情參考FLASH幫助的“外部 API 的 XML 格式”一文。此處CallFunction傳遞的引數為XML格式,如下:

    CString temp = _T("<invoke name=\"setAlt\" returntype=\"xml\">\

                          <arguments><string>3500FT</string></arguments>\

                       </invoke>");

    m_FlashPlayer.CallFunction(temp);

我將其首先全域性變數寫上這段話

然後建立按鍵檢測:呼叫這個函式

注意,<arguments>必須是完整的一行,具體為什麼我也不太清楚。再次執行程式,可以發現ALT的值已經由3280FT變成了3500FT。

shockwave flash object控制元件的相應類是CShockwaveFlash類,該類的常用函式:

Play()   播放動畫           StopPlay()  停止動畫         IsPlaying():動畫是否正在播放(true,false) 

GotoFrame(frame_number)跳轉到某幀(frame_number+1)                   

TotalFrames() 獲取動畫總幀數                CurrentFrame()回傳當前動畫所在幀數-1  

Rewind()  使動畫返回第一幀                   SetZoomRect(left,top,right,buttom)放大指定區域 

Zoom(percent) 改變動畫大小                 Pan(x_position,y_position,unit)  使動畫在x,y方向上平移 

PercentLoaded()返回動畫被載入的百分比(0-100) 

LoadMovie(level_number,path) 載入動畫 

TGotoFrame(movie_clip,frame_number)   movie_clip跳轉到指定幀數  
TGotoLabel(muvie_clip,label_name)        movie_clip跳轉到指定標籤  
TCurrentFrame(movie_clip)  回傳movie_clip當前幀-1 

TCurrentLabel(movie_clip) 回傳movie_clip當前標籤 

TPlay(movie_clip)  播放movie_clip            TStopPlay(movie_clip)  停止movie_clip的播放 

GetVariable(variable_name)   獲取變數     SetVariable(variable_name,value)  變數賦值 

TCallFrame(movie_clip,frame_number)  call指定幀上的action 

TCallLabel(movie_clip,label)  call指定標籤上的action

TGetProperty(movie_clip,property)  獲取movie_clip的指定屬性 

TSetProperty(movie_clip,property,number)     設定movie_clip的指定屬性

MFC中CShockwaveFlash控制元件相關說明

MFC中播放Flash使用的ActiceX控制元件Shockwave Flash Object,其對應的類為CShockwaveFlash。下面給出該控制元件的常用屬性和方法說明:

==================================
FLASH播放器控制元件相關屬性和方法說明
==================================

++++++++++++++++++++++++
++++++++++屬性++++++++++
++++++++++++++++++++++++
語法:AlignMode As Long 
說明:對齊方式(與SAlign屬性聯動).當控制元件的長寬比例與影片不一致且WMode不為ExactFit時,影片在控制元件中顯示的位置可用該屬性調整.
屬性值與相應的對齊方式:
    1:左對齊
    2:右對齊
    4:頂對齊
    8:底對齊 
注意:也可以組合各種對齊方式,就是將這四個基本值組合相加.比如同時左對齊和頂對齊,屬性值則設為5.

語法:BackgroundColor As Long
說明:影片的背景色.預設的影片背景色為-1.如果影片設定了底色或有圖片當作背景,那麼看不出來該屬性值的改變會有什麼影響 。 
注意:顏色值使用RGB格式的顏色值

語法:Base As String 
說明:指定用於解決影片中所有相對路徑的宣告的基地址.當影片與其需要的其他檔案不在同一目錄中的時候該屬性特別有用.如不特別指定,Base的值預設為".",也就是當前影片所在的路徑.
 
語法:BGColor As String 
說明:影片的背景色.與BackgroundColor不同的是,BGColor是一個六位的十六進位制數,每兩位分別代表紅綠藍顏色值.如:FFEEAA表示R值為FF,G值為EE,B值為AA.

語法:DeviceFont As Boolean 
說明:決定是否使用影片內嵌的字型,預設值為False.將該屬性值設為True則強制播放器不使用影片中內嵌的字型而使用本地系統字型.
 
語法:EmbedMovie As Boolean 
說明:影片是否被存貯到控制元件所在的容器中.當你已載入一個影片後將該屬性設為True,播放影片時就不必再去讀取SWF檔案了.這樣可以使SWF檔案鑲程序序中,不必再讀取檔案.但將該屬性設為True後,控制元件的Movie屬性就不再接受新的值了.要想播放另一個影片(給Movie屬性賦新值),必須先將該屬性(EmbedMovie)設為False.


語法:FrameNum As Long 
說明:影片當前幀的編號(從0開始計數).設定該屬性值將使影片停在由FrameNum指定的幀處.
注意:不僅可以從中獲得當前幀,還可以設定當前幀,即跳轉到某幀

語法:Loop As Boolean 
說明:控制影片是否迴圈播放.設為True就是迴圈播放,設為False則只播放一次. 

語法:Menu As Boolean 
說明:是否顯示選單.設為True顯示所有選單,設為False選單被遮蔽,但仍有一項"About Macromedia Flash Player...",點選後會開啟Macromedia的網站.如果你實在不喜歡這個選單,應該在程式中通過攔截滑鼠訊息的方法來達到目的.

語法:Movie As String 
說明:要播放的影片路徑(URL).設定該屬性為一個SWF檔案的URL,當該屬性被設定後,控制元件將自動載入檔案並播放它.

語法:Playing As Boolean 
說明:當前播放狀態.如果影片正在播放,該屬性值為True,否則為False. 

語法:Quality As Long 
說明:畫面質量.
Quality的屬性可以取: 
    0:相當於Quality2取"Low" 
    1:相當於Quality2取"High" 
    2:相當於Quality2取"AutoLow" 
    3:相當於Quality2取"AutoHigh"

語法:Quality2 As String 
說明:畫面質量
Quality的屬性可以取:
    Low:偏重於播放速度而不管顯示效果,而且不啟用消除鋸齒功能.
    High:偏重於畫面而不管播放速度,並且總是啟用消除鋸齒功能.如果影片中不包含動畫就平滑處理點陣圖;如果有動畫,那麼點陣圖就不被平滑處理.
    AutoLow:先著重於播放速度,但只要有可能就改善顯示效果.一開始播放時先禁用消除鋸齒功能.如果播放器檢測到處理器能承受得了,就啟用消除鋸齒功能.
    AutoHigh:一開始是播放速度和顯示效果並重,但如有必要就犧牲畫質確保速度.開始播放時就啟用消除鋸齒功能.但如果實際的幀速率比設計時指定的速率慢了,就禁用消除鋸齒功能來提高播放速度.

語法:ReadyState As Long 
說明:影片的當前狀態.
ReadyState的值有:
    0:正在載入
    1:未初始化
    2:已載入
    3:正在互動
    4:完成例子
注意:可以使用該屬性來粗略的判斷SWF檔案的讀取進度,但如果想得到更精確的判斷,應該在在SWF檔案中使用FScommand()來達到與VB的互動與聯絡,即傳送資料給VB.
 
語法:SAlign As String 
說明:對齊模式.與上文的AlignMode相同,但值的形式不同罷了.
可取值:
    L:即左對齊
    T:即頂對齊
    R:即右對齊
    B:即底對齊
注意:當使用組合對齊方法是L,T,R,B的先後順序不能變,如:左和底的對齊:SAlign="LB"

語法:Scale As String 
說明:控制影片的縮放模式.
Scale的值可以取:
    ShowAll:在控制元件內顯示全部影片區域,保持影片長寬比例不變,影片的大小決定於控制元件長或寬中較小的一邊.
    NoBorder:在控制元件內顯示部分影片區域,保持影片長寬比例不變,影片的大小決定於控制元件長或寬中較大的一邊.
    ExactFit:在控制元件內顯示全部影片區域,不考慮影片的長寬比例,強制將影片的長寬等於控制元件的長寬. 

語法:ScaleMode As Long 
說明:縮放模式,與Scale相同,只不過屬性值為數字而已.
ScaleMode可以取: 
    0:相當於Scale取"ShowAll" 
    1:相當於Scale取"NoBorder" 
    2:相當於Scale取"ExactFit" 

語法:TotalFrames As Long 
說明:返回影片中總幀數.該引數要到影片載入完成才有效,即ReadyState=4 

語法:WMode As String 
說明:控制元件的視窗模式(實現向量圖在VB介面顯示的重要屬性).
WMode可以取:
    Window:WMode屬性的預設值,按Flash播放器典型的方式工作,即在控制元件的矩形視窗中播放影片,這樣一般都能提供最快的動畫效果.
Opaque:使影片不透明.
    Transparent:建立一個透明的影片,如果影片中有透明的片段時,就可以看到控制元件下面的背景.但使用此屬性值,動畫的播放速度可能會慢一些.


++++++++++++++++++++++++
++++++++++方法++++++++++
++++++++++++++++++++++++
Play()                                                       // 播放動畫

StopPlay()                                                // 停止動畫

IsPlaying()                                                // 動畫是否正在播放(true,false) 

GotoFrame(frame_number)                     // 跳轉到某幀(frame_number+1)                        

CurrentFrame()                                        // 回傳當前動畫所在幀數-1  

Rewind()                                                   // 使動畫返回第一幀                  

SetZoomRect(left,top,right,buttom)           // 放大指定區域 

Zoom(percent)                                          //  改變動畫大小                

Pan(x_position,y_position,unit)                 // 使動畫在x,y方向上平移 

PercentLoaded()                                      //返回動畫被載入的百分比(0-100) 

LoadMovie(level_number,path)                // 載入動畫 

GetVariable(variable_name)                     // 獲取變數    

SetVariable(variable_name,value)            //變數賦值 

TotalFrames()                                           // 獲取動畫總幀數           

TPlay(movie_clip)                                      // 播放movie_clip           

TStopPlay(movie_clip)                               //停止movie_clip的播放 

TGotoFrame(movie_clip,frame_number)   // movie_clip跳轉到指定幀數 

TGotoLabel(muvie_clip,label_name)         // movie_clip跳轉到指定標籤 

TCurrentFrame(movie_clip)                       // 回傳movie_clip當前幀-1 

TCurrentLabel(movie_clip)                        // 回傳movie_clip當前標籤 

TCallFrame(movie_clip,frame_number)     // call指定幀上的action 

TCallLabel(movie_clip,label)                      // call指定標籤上的action

TGetProperty(movie_clip,property)            // 獲取movie_clip的指定屬性 

TSetProperty(movie_clip,property,number)// 設定movie_clip的指定屬性