文件名稱 | 描述 |
Dshow.h | 所有的DirectShow應用都必須包含 |
文件名稱 | 描述 |
Strmiids.lib | 此庫文件中導出類標識(CLSID)和接口標識(IID),所有的DirectShow應用都必須包含此文件。 |
Quartz.lib | 此庫文件中導出函數AMGetErrorText,如果你的程序中調用了此函數,則必須包含此庫文件。 |
#include <Dshow.h> |
IDC_STATIC | 控件類型 | Static Text |
Caption | 媒體文件名: | |
IDC_MEDIAFILE_EDIT | 控件類型 | Edit Control |
IDC_BROWSE_BUTTON | 控件類型 | Button |
Caption | 瀏覽 | |
IDC_VW_FRAME | 控件類型 | Picture Control |
Type | Rectangle | |
IDC_PLAY_BUTTON | 控件類型 | Button |
Caption | 播放 | |
IDC_PAUSE_BUTTON | 控件類型 | Button |
Caption | 暫停 | |
IDCANCEL | 控件類型 | Button |
Caption | 關閉 |
BOOL CPlayWndApp::InitInstance() { // 如果一個運行在 Windows XP 上的應用程序清單指定要 // 使用 ComCtl32.dll 版本 6 或更高版本來啟用可視化方式, //則需要 InitCommonControls()。否則,將無法創建窗口。 InitCommonControls(); //初始化COM接口 HRESULT hr = CoInitialize(NULL); clearcase/" target="_blank" >cc>if (FAILED(hr)) { TRACE("ERROR - Could not initialize COM library.\n"); return FALSE; } CWinApp::InitInstance(); AfxEnableControlContainer(); |
int CPlayFileApp::ExitInstance() { // TODO: 在此添加專用代碼和/或調用基類 //關閉COM CoUninitialize(); return CWinApp::ExitInstance(); } |
protected: HICON m_hIcon; // 生成的消息映射函數 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() //和媒體控制相關的成員變量 private: IGraphBuilder *m_pGraph; //IGraphBuilder 接口提供了生成Filter Graph相//關的方法 IMediaControl *m_pMediaControl; //IMediaControl 接口提供了控制流經Filter //Graph數據流的相關方法 IMediaEventEx *m_pEvent; //IMediaEventEx 繼承自IMediaEvent,提供了從 //Filter Graph 管理器獲取事件消息的方法 IMediaSeeking *m_pMediaSeeking; //IMediaSeeking 提供了控制流的播放位置和播放//速度的方法 CString m_strMediaFile; //當前播放的媒體文件的名稱 BOOL m_isPlaying; //當前的播放狀態 }; |
CPlayWndDlg::CPlayWndDlg(CWnd* pParent /*=NULL*/) : CDialog(CPlayWndDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pGraph = NULL; m_pMediaControl = NULL; m_pEvent = NULL; m_pMediaSeeking = NULL; m_strMediaFile = ""; m_isPlaying = FALSE; } |
// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動 // 執行此操作 SetIcon(m_hIcon, TRUE); // 設置大圖標 SetIcon(m_hIcon, FALSE); // 設置小圖標 // TODO: 在此添加額外的初始化代碼 ModifyStyle(0, WS_CLIPCHILDREN); ((CEdit*)GetDlgItem(IDC_MEDIAFILE_EDIT))->SetReadOnly(TRUE); return TRUE; // 除非設置了控件的焦點,否則返回 TRUE } |
BOOL CPlayWndDlg::DestroyWindow() { // TODO: 在此添加專用代碼和/或調用基類 if(m_pGraph) m_pGraph->Release(); if(m_pMediaControl) m_pMediaControl->Release(); if(m_pEvent) m_pEvent->Release(); if(m_pMediaSeeking) m_pMediaSeeking->Release(); m_pGraph = NULL; m_pMediaControl = NULL; m_pEvent = NULL; m_pMediaSeeking = NULL; return CDialog::DestroyWindow(); } |
void CPlayWndDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于繪制的設備上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使圖標在工作矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 繪制圖標 dc.DrawIcon(x, y, m_hIcon); } else { if(m_isPlaying == FALSE) { CClientDC dc(GetDlgItem(IDC_VW_FRAME)); dc.SetBkColor(RGB(0,0,0)); CRect rc; GetDlgItem(IDC_VW_FRAME)->GetClientRect(rc); //ClientToScreen(rc); dc.FillRect(rc, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); GetDlgItem(IDC_VW_FRAME)->Invalidate(); } CDialog::OnPaint(); } } |
void MoveVideoWindow(void); void CleanUp(void); BOOL Stop(void); BOOL Play(void); |
// IDC_VW_FRAME控件Picture Control主要作用是控制Vedio Window的顯示位置 void CPlayWndDlg::MoveVideoWindow(void) { IVideoWindow* pVideoWinow = NULL; if(m_pGraph) { m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVideoWinow); CRect rc; GetDlgItem(IDC_VW_FRAME)->GetWindowRect(rc); ScreenToClient(rc); pVideoWinow->SetWindowPosition(rc.left, rc.top, rc.Width(), rc.Height()); pVideoWinow->Release(); pVideoWinow = NULL; } } void CPlayWndDlg::CleanUp(void) { long levCode; IVideoWindow *pVidWin = NULL; if(!m_pGraph) return; m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin); m_pEvent->WaitForCompletion(INFINITE, &levCode); pVidWin->put_Visible(OAFALSE); pVidWin->Release(); m_pMediaSeeking->Release(); m_pMediaControl->Release(); m_pEvent->Release(); m_pGraph->Release(); m_pMediaSeeking = NULL; m_pMediaControl = NULL; m_pEvent = NULL; m_pGraph = NULL; UpdateData(FALSE); CClientDC dc(GetDlgItem(IDC_VW_FRAME)); dc.SetBkColor(RGB(0,0,0)); CRect rc; GetDlgItem(IDC_VW_FRAME)->GetClientRect(rc); ClientToScreen(rc); dc.FillRect(rc, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); Invalidate(); } BOOL CPlayWndDlg::Stop(void) { IVideoWindow *pVidWin = NULL; HRESULT hr; if(m_pMediaControl) { LONGLONG pos = 0; hr = m_pMediaControl->Stop(); hr = m_pMediaSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,&pos, AM_SEEKING_NoPositioning); m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin); pVidWin->put_Visible(OAFALSE); m_isPlaying = FALSE; GetDlgItem(IDC_PLAY_BUTTON)->EnableWindow(TRUE); GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(FALSE); pVidWin->Release(); long levCode; m_pEvent->WaitForCompletion(INFINITE, &levCode); m_pMediaControl->Release(); return TRUE; } return FALSE; } BOOL CPlayWndDlg::Play(void) { // 運行 IVideoWindow *pVidWin = NULL; if(m_pGraph) { m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin); pVidWin->put_Visible(OATRUE); m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl); m_pMediaControl->Run(); m_isPlaying = TRUE; GetDlgItem(IDC_PLAY_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(TRUE); return TRUE; } return FALSE; } |
void CPlayWndDlg::OnBnClickedBrowseButton() { CFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Movie Files (*.avi;*.mpg;*.mpeg) |\ *.avi;*.mpg;*.mpeg |\ Audio Files (*.wav;*mp3;*.mpa;*.mpu;*.au) |\ *.wav;*.mp3;*.mpa;*.mpu;*.au |\ Midi Files (*.mid;*.midi;*.rmi) |\ *.mid;*.midi;*.rmi| | ", this); if(dlgFile.DoModal() == IDOK) { m_strMediaFile = dlgFile.GetPathName(); GetDlgItem(IDC_MEDIAFILE_EDIT)->SetWindowText(m_strMediaFile); } else return; CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGraph); HRESULT hr = m_pGraph->RenderFile(CA2W(m_strMediaFile), NULL); if(FAILED(hr)) { char szMsg[200]; AMGetErrorText(hr, szMsg, sizeof(szMsg)); AfxMessageBox(szMsg); } //指定父窗體 IVideoWindow* pVidWin = NULL; m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin); pVidWin->put_Owner((OAHWND)m_hWnd); pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); CRect rc; GetDlgItem(IDC_VW_FRAME)->GetWindowRect(rc); ScreenToClient(rc); pVidWin->SetWindowPosition(rc.left, rc.top, rc.Width(), rc.Height()); // 注意此處Filter Graph Manager的事件以WM_GRAPHNOTIFY發出(用戶定義的消息). m_pGraph->QueryInterface(IID_IMediaEventEx, (void **)&m_pEvent); m_pEvent->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0); // 設置Seeking m_pGraph->QueryInterface(IID_IMediaSeeking, (void **)&m_pMediaSeeking); } void CPlayWndDlg::OnBnClickedPlayButton() { Play(); } void CPlayWndDlg::OnBnClickedPauseButton() { m_pMediaControl->Pause(); m_isPlaying = TRUE; GetDlgItem(IDC_PLAY_BUTTON)->EnableWindow(TRUE); GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(FALSE); } void CPlayWndDlg::OnBnClickedCancel() { // TODO: 在此添加控件通知處理程序代碼 CleanUp(); OnCancel(); } |
#define WM_GRAPHNOTIFY WM_USER + 101 |
// 實現 protected: HICON m_hIcon; // 生成的消息映射函數 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() afx_msg HRESULT OnGraphNotify(WPARAM wParam,LPARAM lParam); private: IGraphBuilder *m_pGraph; IMediaControl *m_pMediaControl; IMediaEventEx *m_pEvent; |
ON_BN_CLICKED(IDC_BROWSE_BUTTON, OnBnClickedBrowseButton) ON_BN_CLICKED(IDC_PLAY_BUTTON, OnBnClickedPlayButton) ON_BN_CLICKED(IDC_PAUSE_BUTTON, OnBnClickedPauseButton) ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify) END_MESSAGE_MAP() |
HRESULT CPlayWndDlg::OnGraphNotify(WPARAM wParam,LPARAM lParam) { long levCode, lparam1, lparam2; HRESULT hr; while (hr = m_pEvent->GetEvent(&levCode, &lparam1, &lparam2, 0), SUCCEEDED(hr)) { hr = m_pEvent->FreeEventParams(levCode, lparam1, lparam2); if ((EC_COMPLETE == levCode) || (EC_USERABORT == levCode)) { TRACE("End of the media file!!.\n"); Stop(); //CleanUp(); break; } } return hr; } |