[Flash][VB.NET] Flash 與 WinForm 雙向通訊,以及使其右鍵失效的方法

Standard

最近的 Case 要將 Flash 做主要的 UI,而與其他裝置是透過 WinForm (VB.NET) 來寫。因此要將 Flash SWF 檔案嵌入 WinForm,並使 Flash 與 WinForm 能做雙向的指令溝通。

這方面的資料還算好找,Google 一下就有相關的結果了,在此就實做一次 VB.NET 版本的。


Flash 端

Flash 端這邊的 ActionScript 如下:

import flash.external.*;

stop();

btn_mc.buttonMode=true;
btn_mc.addEventListener(MouseEvent.CLICK, clickEvent);

function clickEvent(e:MouseEvent):void {
	// 向 WinForm 傳送數據
	ExternalInterface.call("");
	fscommand("sayHello");
};

//接受 WinForm 發來的數據
ExternalInterface.addCallback("c2flash", c2flash);
function c2flash(s:String)
{
    out_txt.text = s;
}

再來分項解說:

Flash 中擺了一個 Button,希望使用者按下之後可以傳送命令到 WinForm,並在 WinForm 中跳出對話框(MessageBox)。
這邊使用:

	ExternalInterface.call("");
	fscommand("sayHello");

ExternalInterface.call 與 fscommand 搭配來傳送命令。經測試,ExternalInterface.call 似乎擺空字串去 call 也會引發命令,只是告訴 WinForm 說「我傳一個指令過去囉,請偵聽 fscommand 的內容吧」。這邊的測試有誤請再告訴我 :P

再來是 Flash 中增加一個 CallBack 來接收 WinForm 傳送過來的命令,

ExternalInterface.addCallback("c2flash", c2flash);
function c2flash(s:String)
{
    out_txt.text = s;
}

Flash 的部分不複雜,大概就這樣。


WinForm 端

再來看 WinForm (VB.NET) 的部分,由於我們需要嵌入 Flash SWF 物件,因此請在左方「工具箱」點右鍵選擇「選擇項目…」、「COM 元件」,找到「Shockwave Flash Object」,打勾後「確定」,就可看到左方工具箱內新出現一個「Shockwave Flash Object」了。

Form 上我擺了 Shockwave Flash Object、Label、Textbox、Timer,以及 Button,配置請參考下圖:


Code 部分:
Form_Load

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        flash.Movie = System.Configuration.ConfigurationSettings.AppSettings("FlashSWF")

        Timer1.Interval = 1000
        Timer1.Start()

    End Sub

其中 flash 為 Shockwave Flash Object 物件名稱,在此將其 Movie 預設影片路徑指定於 app.setting 檔案中。

定義一個 WinForm 傳送給 Flash 的方法 callFunction

    'Winform 傳送給 Flash
    Private Sub callFunction(ByVal funName As String, ByVal arg As String)

        Try

            flash.CallFunction("<invoke name=""" & funName & """ returntype=""xml""><arguments><string>" & arg & "</string></arguments></invoke>")

        Catch ex As Exception

        End Try

    End Sub

以及接收 Flash 傳給 WinForm 的方法 flash_FSCommand:

    'Flash 傳送過來的 fscommand
    Private Sub flash_FSCommand(ByVal sender As System.Object, ByVal e As AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent) Handles flash.FSCommand

        If e.command = "sayHello" Then
            MessageBox.Show("SWF說:" + e.command.ToString())
        End If

    End Sub

當 command 等於 sayHello 的時候,WinForm 就跳出一對話框顯示呼叫的 command。

再來測試看看利用 WinForm 中的 Timer,使 Flash 中的文字框,顯示現時時間。

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        callFunction("c2flash", DateTime.Now.ToString("hh:mm:ss"))

    End Sub

主要使用到上面的 callFunction 方法,將現時時間傳送給 Flash 中的 c2flash CallBack 來處理。

接著這個方法是將 WinForm 中 Textbox 所輸入的文字,按鈕後傳送至 Flash 中顯示:

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        '向Flash發送數據
        callFunction("c2flash", Me.textBox1.Text)
    End Sub

Flash 與 WinForm 的通訊大致就如同上面的範例。


關閉 WinForm 中 Flash 影片的右鍵功能

接著通常還會遇到一個問題──在 WinForm 中的這個 Flash 影片上按右鍵,會出現右鍵選單,有設定、全域設定、關於等等的,我們不希望使用者可以點選後離開這個 WinForm 去操作其他 IE 啊之類的視窗。

聽說 Flash 中無法完全地關掉右鍵選單,仍會留下上述幾項,因此這邊還是需要 VB.NET 來處理囉。

首先先將下面這段 copy 過去:

    '使Shockwave物件右鍵失效==
    Private Const GWL_WNDPROC As Integer = -4
    Public Delegate Function FlaWndProc(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

    Private OldWndProc As IntPtr = IntPtr.Zero
    Private Wpr As FlaWndProc = Nothing

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal wndProc As FlaWndProc) As IntPtr
    End Function
    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Public Shared Function CallWindowProc(ByVal wndProc As IntPtr, ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    End Function

    Private Function FlashWndProc(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
        If msg = 516 Then
            Return 0
        End If
        Return CallWindowProc(OldWndProc, hWnd, msg, wParam, lParam)
    End Function
    '使Shockwave物件右鍵失效==

原理大致是使右鍵按下時將原有的指令碼代換為無效的 0。

接著在 Form_Load 也要加入下面這段:

        '使Shockwave物件右鍵失效==
        Try
            Me.Wpr = New FlaWndProc(AddressOf Me.FlashWndProc)
            Me.OldWndProc = SetWindowLong(flash.Handle, GWL_WNDPROC, Wpr)
        Catch ex As Exception
            MessageBox.Show("Load exception:" + ex.Message)
        End Try
        '使Shockwave物件右鍵失效==

其中 SetWindowLong(flash.Handle, GWL_WNDPROC, Wpr) 中的 flash,即是 Shockwave Flash Object 元件的名稱。

以上兩段,就能使 WinForm 中的 Flash 影片右鍵功能失效囉。


最後是本範例的 Source files
請解壓縮在 D:/test 中。

小弟是沒寫幾次 WinForm 的新手(又撈過界了..噗),有誤之處請不吝指正囉 ~~


參考資料:

One thought on “[Flash][VB.NET] Flash 與 WinForm 雙向通訊,以及使其右鍵失效的方法

  1. 感謝這篇的教學-___-
    讓我大概了解.net和flashplayer如何溝通
    不然我關鍵字實在不知道怎下,總是找不到比較適合的教學(攤手
    最近在研究youtube api 用as3 和vb結合 這方面的教學少之又少>"""<

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

你可以使用這些 HTML 標籤與屬性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>