| DIY自己的Flash播放器 | 出處:PConline |
| [02-3-5 15:57] | 作者:cyberian |
|
·特別問(wèn)題:如何全屏幕播放?
全屏幕播放是個(gè)看似簡(jiǎn)單,實(shí)現起來(lái)一點(diǎn)也不容易的功能。在所有的播放控制功能中,全屏幕播放是唯一一個(gè)不是由Flash控件提供的,因為只有窗口才有全屏的概念,控件則沒(méi)有,因此它需要播放器自己實(shí)現。全屏的要求是窗口充滿(mǎn)屏幕,并且無(wú)標題條的邊框,這就需要在運行時(shí)刻動(dòng)態(tài)改變窗口的風(fēng)格,但我們知道VB開(kāi)發(fā)的程序,沒(méi)有提供在運行時(shí)刻動(dòng)態(tài)更改窗口風(fēng)格的方法(運行時(shí)更改窗口的BorderStyle無(wú)效,ControlBox屬性不能在運行時(shí)更改),看來(lái)惟有借助Windows API了。Windows在user32.dll中提供了一組對應函數來(lái)分別獲取和更改窗口的屬性--GetWindowlong和SetWindowLong,它們都可以在VB的API Loader中找到:Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long;
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long。其中hwnd參數是被操作窗口的句柄;nIndex參數告訴函數要操作窗口的什么屬性,在本程序中傳入GWL_STYLE值,其他參數值可查閱MSDN;dwNewLong參數是新的窗口屬性值。標準的窗口風(fēng)格是有標題條和可縮放的邊框,對應的窗口風(fēng)格參數值是WS_CAPTION和WS_THICKFRAME,所以要實(shí)現全屏只要將窗口風(fēng)格屬性中的這兩個(gè)值去掉就達到效果了,要恢復也很簡(jiǎn)單,重新加上這兩個(gè)值即可。
了解原理后,下面我們就進(jìn)行編程實(shí)踐了!
::編程實(shí)踐::
打開(kāi)VB,新建一個(gè)標準的EXE工程,將工程名稱(chēng)命名為"MyFlashPlayer",在控件箱中添加CommonDialog、StatusBar、Slider、ShockwaveFlash控件。將默認生成的窗口Name屬性改為"frmMyFlashPlayer",Caption改為"My FlashPlayer",ScaleMode改為"3 - Pixel",然后依次添加以下控件:
1、12個(gè)按鈕(CommandButton),Name屬性分別為"cmdPlaySWF"、"cmdPauseSWF"、"cmdStopSWF"、
"cmdRewindSWF"、"cmdStepBackSWF"、"cmdStepForwardSWF"、"cmdGotoEndSWF"、
"cmdFastBackSWF"、"cmdFastForwardSWF"、"cmdZoomInSWF"、"cmdZoomOutSWF"、
"cmdZoomNoSWF",Caption屬性分別為“播放”、“暫停”、“停止”、“重播”、“后退”、“前進(jìn)”、“末幀”、“快退”、“快進(jìn)”、“放大”、“縮小”、“正常”。
2、1個(gè)劃動(dòng)條(Slider),Name屬性為SliderSWF,Max屬性為"100"(表示100%),TickStyle屬性為"3 - sldNoTicks"。1個(gè)狀態(tài)欄(StatusBar),雙擊其屬性中的“(自定義)”,在彈出的屬性頁(yè)的窗格欄中,插入2個(gè)窗格,并將2個(gè)窗格的對齊方式設置為"1 - sbrCenter"。
3、1個(gè)定時(shí)器(Timer),Name屬性為T(mén)imerSWF,Enabled屬性為"False",Interval屬性為"1000"。1個(gè)通用對話(huà)框(CommonDialog),Name屬性為"OpenDialogSWF",DialogTitle屬性為“打開(kāi)Flash動(dòng)畫(huà)文件”,Filter屬性為“Flash動(dòng)畫(huà)文件(*.swf)|*.swf|所有文件(*.*)|*.*”,FilterIndex屬性為"1"。
4、1個(gè)ShockwaveFlash控件,Name屬性為MyShockwaveFlash,點(diǎn)擊鼠標右鍵彈出快捷菜單,選擇“置前”,使其在所有控件的最上面,全屏幕播放需要此設置,在后面源代碼中筆者將說(shuō)明其用途。
5、打開(kāi)菜單編輯器,添加如下菜單:“文件(&F)”(mnuFileSWF)、“打開(kāi)(&O)”(Ctrl+O)(mnuOpenSWF)、“退出(&X)”(mnuExitSWF)、“查看(&V)”(mnuViewSWF)、“質(zhì)量(&Q)”(mnuQualitySWF)、“高(&H)”(復選)(mnuQualityHigh)、“中(&M)”(mnuQualityMedium)、“低(&L)”(mnuQualityLow)、“循環(huán)播放(&L)”(復選)(mnuLoopSWF)、“快捷菜單(&M)”(復選)(mnuMenuSWF)、“全屏幕播放(&F)”(F11)(mnuFullScreenSWF)。其中“文件”包括“打開(kāi)”、“退出”,“查看”包括“質(zhì)量”、“循環(huán)播放”、“快捷菜單”、“全屏幕播放”,“質(zhì)量”又包括“高”、“中”、“低”。
好了,界面設計完成,效果如圖1。

Private Sub cmdStopSWF_Click()
‘ 停止
‘ 一般多媒體播放器停止的行為是停止播放并返回到第一幀
‘ 但ShockwaveFlash控件中沒(méi)有這樣的功能
‘ 所以只能以“返回到第一幀”和“暫停播放”兩個(gè)功能組合實(shí)現
MyShockwaveFlash.Rewind
MyShockwaveFlash.StopPlay
End Sub
Private Sub cmdZoomInSWF_Click()
‘ 放大一倍,以原先為50%
MyShockwaveFlash.Zoom (50)
End Sub
Private Sub cmdZoomNoSWF_Click()
‘ 正常大小
MyShockwaveFlash.Zoom (0)
End Sub
Private Sub cmdZoomOutSWF_Click()
‘ 縮小一倍,以原先為200%
MyShockwaveFlash.Zoom (200)
End Sub
Private Sub Form_Load()
‘ 設置打開(kāi)文件對話(huà)框的標志為:
‘ 文件名和路徑都必須有效,并且不顯示“以只讀方式打開(kāi)(R)”的復選項
OpenDialogSWF.Flags = cdlOFNFileMustExist Or cdlOFNPathMustExist Or cdlOFNHideReadOnly
End Sub
Private Sub Form_Resize()
If Me.WindowState <> vbMinimized Then
‘ 當窗口不是最小化時(shí),根據窗口大小調整各控件的位置和大小
‘ 否則計算高度和寬度時(shí)會(huì )出現非正數而出錯
If Me.ScaleHeight > (cmdPlaySWF.Height + StatusBarSWF.Height + SliderSWF.Height) Then
MyShockwaveFlash.Move 0, cmdPlaySWF.Height + 8,
Me.ScaleWidth, Me.ScaleHeight - cmdPlaySWF.Height - StatusBarSWF.Height - SliderSWF.Height - 16
End If
SliderSWF.Top = Me.ScaleHeight - StatusBarSWF.Height - SliderSWF.Height
SliderSWF.Width = Me.ScaleWidth
StatusBarSWF.Panels(1).MinWidth = Me.ScaleWidth * 0.6
StatusBarSWF.Panels(2).MinWidth = Me.ScaleWidth * 0.2
StatusBarSWF.Panels(3).MinWidth = Me.ScaleWidth * 0.2
End If
End Sub
Private Sub mnuClose_Click()
TimerSWF.Enabled = False
MyShockwaveFlash.Movie = "http://" ‘ 只有此參數才能關(guān)閉當前動(dòng)畫(huà),如果傳入vbNullString會(huì )出錯
StatusBarSWF.Panels(1).Text = vbNullString
StatusBarSWF.Panels(1).ToolTipText = vbNullString
StatusBarSWF.Panels(2).Text = vbNullString
StatusBarSWF.Panels(3).Text = vbNullString
SliderSWF.Value = 0
End Sub
Private Sub mnuExitSWF_Click()
Unload Me
End Sub
Private Sub mnuFullScreenSWF_Click()
‘ 全屏幕播放,隱藏播放控制和進(jìn)度顯示
Dim ReturnValue As Long, WindowStyle As Long
mnuFullScreenSWF.Checked = Not mnuFullScreenSWF.Checked
If mnuFullScreenSWF.Checked Then
‘ 更改窗口風(fēng)格為無(wú)邊框和無(wú)標題條,并且充滿(mǎn)屏幕
WindowStyle = GetWindowLong(Me.hwnd, GWL_STYLE)
ReturnValue = SetWindowLong(Me.hwnd, GWL_STYLE, WindowStyle - WS_CAPTION - WS_THICKFRAME)
Me.WindowState = vbNormal
Me.Move 0, 0, Screen.Width, Screen.Height
‘ 因為ShockwaveFlash在所有控件的最上面
‘ 所以無(wú)須隱藏其他控件就可充滿(mǎn)窗口
MyShockwaveFlash.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
Else
‘ 恢復窗口風(fēng)格為正常式樣,并且還原為默認大小
WindowStyle = GetWindowLong(Me.hwnd, GWL_STYLE)
ReturnValue = SetWindowLong(Me.hwnd, GWL_STYLE, WindowStyle Or WS_CAPTION Or WS_THICKFRAME)
Me.Move 0, 0, 488 * Screen.TwipsPerPixelX, 446 * Screen.TwipsPerPixelY
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
End If
End Sub
Private Sub mnuLoopSWF_Click()
‘ 設置ShockwaveFlash是否循環(huán)播放
mnuLoopSWF.Checked = Not mnuLoopSWF.Checked
MyShockwaveFlash.Loop = mnuLoopSWF.Checked
End Sub
Private Sub mnuMenuSWF_Click()
‘ 設置ShockwaveFlash快捷菜單是否可用
mnuMenuSWF.Checked = Not mnuMenuSWF.Checked
MyShockwaveFlash.Menu = mnuMenuSWF.Checked
End Sub
Private Sub mnuOpenSWF_Click()
‘ 打開(kāi)Flash動(dòng)畫(huà)文件
On Error GoTo ErrorOpenSWF
OpenDialogSWF.ShowOpen
If OpenDialogSWF.FileName <> vbNullString Then
StatusBarSWF.Panels(1).Text = OpenDialogSWF.FileName
StatusBarSWF.Panels(1).ToolTipText = OpenDialogSWF.FileName
MyShockwaveFlash.Movie = OpenDialogSWF.FileName
TimerSWF.Enabled = True ‘ 開(kāi)始顯示播放進(jìn)度
StatusBarSWF.Panels(2).Text = Format$(MyShockwaveFlash.TotalFrames, "共#幀")
End If
Exit Sub
ErrorOpenSWF:
‘ 打開(kāi)Flash動(dòng)畫(huà)文件中有個(gè)Bug:
‘ 如果打開(kāi)了一個(gè)非Flash動(dòng)畫(huà)格式或是損壞的Flash動(dòng)畫(huà),ShockwaveFlash控件將產(chǎn)生異常錯誤
‘ 但之后就無(wú)法再打開(kāi)任何完好的Flash動(dòng)畫(huà)了,即無(wú)法給Movie屬性賦予任何有效值了,只有關(guān)閉程序再重新運行
‘ 我猜測可能是ShockwaveFlash控件的問(wèn)題
MsgBox "不是有效的Flash動(dòng)畫(huà),或Flash動(dòng)畫(huà)已損壞,程序將被關(guān)閉!", vbCritical
Unload Me
End Sub
Private Sub mnuQualityHigh_Click()
‘ 高質(zhì)量
MyShockwaveFlash.Quality2 = "High" ‘等同于:MyShockwaveFlash.Quality = 1
mnuQualityHigh.Checked = True
mnuQualityMedium.Checked = False
mnuQualityLow.Checked = False
End Sub
Private Sub mnuQualityLow_Click()
‘ 低質(zhì)量
MyShockwaveFlash.Quality2 = "Low" ‘等同于:MyShockwaveFlash.Quality = 0
mnuQualityHigh.Checked = False
mnuQualityMedium.Checked = False
mnuQualityLow.Checked = True
End Sub
Private Sub mnuQualityMedium_Click()
‘ 中質(zhì)量
MyShockwaveFlash.Quality2 = "Medium" ‘無(wú)對應數字值,只能用字符串賦值
mnuQualityHigh.Checked = False
mnuQualityMedium.Checked = True
mnuQualityLow.Checked = False
End Sub
Private Sub mnuWebOpen_Click()
Dim SWFURL As String
SWFURL = InputBox("輸入動(dòng)畫(huà)鏈接地址")
If SWFURL <> vbNullString Then
MyShockwaveFlash.Movie = SWFURL
End If
End Sub
Private Sub SliderSWF_Scroll()
If MyShockwaveFlash.FrameNum >= 0 Then
‘ 根據劃動(dòng)條的值為百分比跳轉到動(dòng)畫(huà)播放進(jìn)度
MyShockwaveFlash.GotoFrame (SliderSWF.Value * 0.01 * (MyShockwaveFlash.TotalFrames - 1))
Else
SliderSWF.Value = 0
End If
End Sub
Private Sub TimerSWF_Timer()
‘ ShockwaveFlash控件沒(méi)有播放進(jìn)度的事件
‘ 因此使用定時(shí)器顯示當前動(dòng)畫(huà)的播放信息
SliderSWF.Value = MyShockwaveFlash.FrameNum / (MyShockwaveFlash.TotalFrames - 1) * 100
SliderSWF.ToolTipText = CStr(SliderSWF.Value) + "%"
StatusBarSWF.Panels(3).Text = Format$(MyShockwaveFlash.FrameNum + 1, "第0幀")
End Sub
::結束語(yǔ)::
完成后編譯運行,運行效果如圖2。


聯(lián)系客服