在過去的10年裡,移動技術已經取得了令人難以置信的進步和成就。應用Windows CE系統的行動裝置也在應用和編程方面變得更加靈活和方便。最新的Windows CE裝置中加入了Windows Media Player 10 Mobile,它提供了和PC上的WMP控制項一樣強大的功能。你可以為你的行動裝置增加多媒體能力,包括播放視頻、音頻檔案,展示圖片等等。你可以在文後所附的段落中找到可用的SDK和資源等相關資訊。
下面我們簡單介紹WMP的一些實現技術。
慨述
WMP SDK提供了很多的介面,但不是所有都能應用到Windows Mobile平台上來。下面列出可用的一些並進行解釋:
介面 |
描述 |
IWMPCore |
WMP物件模型的根介面。你可以由此擷取其他介面的指標並且通過它訪問其他空間的基本特性。 |
IWMPControls |
允許一個應用程式訪問Windows Media Player控制項;如它的播放,停止和暫停按鈕。 |
IWMPError |
提供錯誤資訊。 |
IWMPEvents |
把由Windows Media Player控制項產生的事件提供給一個可以反饋的嵌入式程式。 |
IWMPMedia,IWMPMediaCollection |
管理媒體項的屬性。 |
IWMPNetwork |
設定和擷取Windows Media Player所使用的網路連接 |
IWMPPlayer |
控制Windows Media Player空間的使用者介面的行為。 |
IWMPPlaylist, IWMPPlaylistArray, IWMPPlaylistCollection |
播放清單操作。 |
IWMPSettings |
設定或者擷取Windows Media Player的設定。 |
建立第一個應用程式
下面由一個簡單的ATL應用程式開始,你將建立一個空間容器視窗。下面的程式碼片段使用了一個標準的ATL技術來展示Windows Media Player控制項:
LRESULT CWMPHost::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { AtlAxWinInit(); CComPtr<IAxWinHostWindow> spHost; CComPtr<IConnectionPointContainer> spConnectionContainer; CComWMPEventDispatch *pEventListener = NULL; CComPtr<IWMPEvents> spEventListener; HRESULT hr; RECT rcClient; m_dwAdviseCookie = 0; ... // 建立視窗 GetClientRect(&rcClient); m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); if (NULL == m_wndView.m_hWnd) goto FAILURE; // 在視窗中裝載OCX hr = m_wndView.QueryHost(&spHost); if (FAILMSG(hr)) goto FAILURE; hr = spHost->CreateControl(CComBSTR(_T("WMPlayer.OCX")), m_wndView, 0); if (FAILMSG(hr)) goto FAILURE; hr = m_wndView.QueryControl(&m_spWMPPlayer); if (FAILMSG(hr)) goto FAILURE; // 開始監聽事件 hr = CComWMPEventDispatch::CreateInstance(&pEventListener); spEventListener = pEventListener; if (FAILMSG(hr)) goto FAILURE; hr = m_spWMPPlayer->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&spConnectionContainer); if (FAILMSG(hr)) goto FAILURE; // 看OCX 是否支援IWMPEvents介面 hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents), &m_spConnectionPoint); if (FAILMSG(hr)) goto FAILURE; hr = m_spConnectionPoint->Advise(spEventListener, &m_dwAdviseCookie); if (FAILMSG(hr)) goto FAILURE; return 0;FAILURE: ::PostQuitMessage(0); return 0; } |
你所要做的只是建立一個控制項視窗,包含一個IWMPPlayer介面指標,並且對WMP事件進行響應。ATL可以用比MFC更加簡便的方式來完成這些任務,當然你也可以使用MFC。你的程式現在就可以播放Windows媒體檔案,比如WMA和WMV。
WMP控制項也允許程式員來控制它的行為,比如你可以這樣開始播放一個媒體檔案:
LRESULT CWMPHost::OnFileOpen(Word wNotifyCode, Word wID, HWND hWndCtl, BOOL& bHandled) { CFileOpenDlg dlgOpen; HRESULT hr; if (dlgOpen.DoModal(m_hWnd) == IDOK) { hr = m_spWMPPlayer->put_URL(dlgOpen.m_bstrName); if (FAILMSG(hr)) return 0; } return 0; } |
Windows Mobile Player 10的移動範例提供了一系列的控制項使用範例。 在Web應用程式裡使用WMP OCX
在使用Web瀏覽器的時候,應用WMP編程就更加容易了(這是SDK裡的例子):
<HTML> <HEAD> </HEAD> <BODY> <OBJECT ID=wmpocx WIDTH=200 HEIGHT=150 CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" TYPE="application/x-oleobject" VIEWASTEXT> <PARAM name="uimode" value="none"> </OBJECT><BR> <script for="wmpocx" event="PlayStateChange(NewState)" language="JScript">ClipPlayState(NewState); </script> <script for="wmpocx" event="Error()" language="JScript">StopPlayer();</script> <p> <a href=# OnClick='PlayClip("/storage card/webapp/glass.wmv", ImgVideoPlay, true)'> <IMG id="ImgVideoPlay" src="bt_play.gif" border="0"> </a> Video<br> <a href=# OnClick='PlayClip("/storage card/webapp/jeanne.wma", ImgAudioPlay, false)'> <IMG id="ImgAudioPlay" src="bt_play.gif" border="0"> </a> Audio<br> Play state sequence<br> <input type="text" id="PlayStateSequence" width=30> <SCRIPT language="JScript"> <!--var CurrentPlayImage = null; var bVideo = null; var bWasBuffering = false; function StopPlayer() { wmpocx.controls.stop(); wmpocx.close(); if (CurrentPlayImage != null) { CurrentPlayImage.src = "bt_play.gif"; } bWasBufferring = false; } function ClipPlayState(NewState) { PlayStateSequence.value = PlayStateSequence.value + NewState + " "; switch(NewState) { case 1: // stopped if (bWasBuffering) { bWasBufferring = false; if (CurrentPlayImage != null) { CurrentPlayImage.src = "bt_play.gif"; } } break; case 6: // buffering bWasBufferring = true; if (CurrentPlayImage != null) { CurrentPlayImage.src = "bt_load.gif"; } break; case 9: // transitioning case 11: // reconnecting bWasBufferring = false; break; case 3: // playing if (bWasBufferring) { if (CurrentPlayImage != null) { CurrentPlayImage.src = "bt_stop.gif"; } if (bVideo) { wmpocx.fullScreen = true; } } break; default: } } function PlayClip(url, img, video) { if (wmpocx.playState == 3 && bVideo != null && bVideo != video) { return; } bVideo = video; CurrentPlayImage = img; if (wmpocx.playState == 3) { StopPlayer(); } else { PlayStateSequence.value = ""; if (CurrentPlayImage != null) { CurrentPlayImage.src = "bt_load.gif"; } wmpocx.URL = url; } } --> </SCRIPT> </BODY> </HTML> |
使用舊版本的WMP控制項
如果你使用的手持功能沒有WMP10,那事情還沒有完。你仍然還可以使用WMP OCX版本8來為你的Pocket PC編程,雖然提供的功能特性少,好在也可以基本滿足需要。我建立了一個簡單的工程來展示它如何在MFC環境下工作。下面的程式碼片段證明了它和ATL方式一樣簡單:
BOOL CWMP8SampleDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The Framework does this // automatically when the application's main window is not // a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon CenterWindow(GetDesktopWindow()); // center to the hpc screen CRect rect; m_Panel.GetClientRect(&rect); if ( m_PlayerWnd.CreateControl(__uuidof(WMP),L"", WS_VISIBLE|WS_CHILD,rect, &m_Panel,AFX_IDW_PANE_FIRST) ) { LPUNKNOWN lpUnk = m_PlayerWnd.GetControlUnknown(); HRESULT hr = lpUnk->QueryInterface(__uuidof(IWMP),(void**) &m_spWMPPlayer); } else { AfxMessageBox(L"Failed to create WMP control"); ::PostQuitMessage(0); return 0; } if ( m_spWMPPlayer ) { m_WMPEvents.m_pMainDlg = (CWMP8SampleDlg*)this; CComPtr<IConnectionPointContainer> spConnectionContainer; HRESULT hr = m_spWMPPlayer-> QueryInterface( IID_IConnectionPointContainer, (void**)&spConnectionContainer ); if (SUCCEEDED(hr)) { hr = spConnectionContainer-> FindConnectionPoint( __uuidof(_IWMPEvents), &m_spConnectionPoint ); } if (SUCCEEDED(hr)) { hr = m_spConnectionPoint->Advise((IDispatch*)&m_WMPEvents, &m_dwAdviseCookie ); } else { AfxMessageBox(L"Failed to get WMP control events"); ::PostQuitMessage(0); return 0; } if ( FAILED(SetupWMP()) ) { AfxMessageBox(L"Failed to setup WMP control"); ::PostQuitMessage(0); return 0; } } m_spWMPPlayer->Stop(); return TRUE; // return TRUE unless you set the focus to a // control } |