SimplePlayerDlg.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:11k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // SimplePlayerDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "SimplePlayer.h"
  5. #include "SimplePlayerDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CSimplePlayerDlg dialog
  13. CSimplePlayerDlg::CSimplePlayerDlg(CWnd* pParent /*=NULL*/)
  14. : CDialog(CSimplePlayerDlg::IDD, pParent)
  15. {
  16. //{{AFX_DATA_INIT(CSimplePlayerDlg)
  17. // NOTE: the ClassWizard will add member initialization here
  18. //}}AFX_DATA_INIT
  19. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  20. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  21. mFilterGraph = NULL;
  22. mSourceFile  = "";
  23. mSliderTimer = 0;
  24. }
  25. CSimplePlayerDlg::~CSimplePlayerDlg()
  26. {
  27. DestroyGraph();
  28. }
  29. void CSimplePlayerDlg::DoDataExchange(CDataExchange* pDX)
  30. {
  31. CDialog::DoDataExchange(pDX);
  32. //{{AFX_DATA_MAP(CSimplePlayerDlg)
  33. DDX_Control(pDX, IDC_SLIDER_GRAPH, mSliderGraph);
  34. DDX_Control(pDX, IDC_VIDEO_WINDOW, mVideoWindow);
  35. //}}AFX_DATA_MAP
  36. }
  37. BEGIN_MESSAGE_MAP(CSimplePlayerDlg, CDialog)
  38. //{{AFX_MSG_MAP(CSimplePlayerDlg)
  39. ON_WM_PAINT()
  40. ON_WM_QUERYDRAGICON()
  41. ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
  42. ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
  43. ON_BN_CLICKED(IDC_BUTTON_PAUSE, OnButtonPause)
  44. ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
  45. ON_BN_CLICKED(IDC_BUTTON_GRAB, OnButtonGrab)
  46. ON_BN_CLICKED(IDC_BUTTON_FULLSCREEN, OnButtonFullscreen)
  47. ON_WM_ERASEBKGND()
  48. ON_WM_TIMER()
  49. ON_WM_HSCROLL()
  50. ON_BN_CLICKED(IDC_BUTTON_TEST, OnButtonTest)
  51. //}}AFX_MSG_MAP
  52. ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
  53. END_MESSAGE_MAP()
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CSimplePlayerDlg message handlers
  56. BOOL CSimplePlayerDlg::OnInitDialog()
  57. {
  58. CDialog::OnInitDialog();
  59. // Set the icon for this dialog.  The framework does this automatically
  60. //  when the application's main window is not a dialog
  61. SetIcon(m_hIcon, TRUE); // Set big icon
  62. SetIcon(m_hIcon, FALSE); // Set small icon
  63. // TODO: Add extra initialization here
  64. // Change the window style for video window, or video window
  65. // will not be painted properly.
  66. mVideoWindow.ModifyStyle(0, WS_CLIPCHILDREN);
  67. mSliderGraph.SetRange(0, 1000);
  68. mSliderGraph.SetPos(0);
  69. return TRUE;  // return TRUE  unless you set the focus to a control
  70. }
  71. // If you add a minimize button to your dialog, you will need the code below
  72. //  to draw the icon.  For MFC applications using the document/view model,
  73. //  this is automatically done for you by the framework.
  74. void CSimplePlayerDlg::OnPaint() 
  75. {
  76. if (IsIconic())
  77. {
  78. CPaintDC dc(this); // device context for painting
  79. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  80. // Center icon in client rectangle
  81. int cxIcon = GetSystemMetrics(SM_CXICON);
  82. int cyIcon = GetSystemMetrics(SM_CYICON);
  83. CRect rect;
  84. GetClientRect(&rect);
  85. int x = (rect.Width() - cxIcon + 1) / 2;
  86. int y = (rect.Height() - cyIcon + 1) / 2;
  87. // Draw the icon
  88. dc.DrawIcon(x, y, m_hIcon);
  89. }
  90. else
  91. {
  92. CDialog::OnPaint();
  93. }
  94. }
  95. // The system calls this to obtain the cursor to display while the user drags
  96. //  the minimized window.
  97. HCURSOR CSimplePlayerDlg::OnQueryDragIcon()
  98. {
  99. return (HCURSOR) m_hIcon;
  100. }
  101. void CSimplePlayerDlg::OnButtonOpen() 
  102. {
  103. // TODO: Add your control notification handler code here
  104. CString    strFilter = "AVI File (*.avi)|*.avi|";
  105. strFilter += "MPEG File (*.mpg;*.mpeg)|*.mpg;*.mpeg|";
  106. strFilter += "Mp3 File (*.mp3)|*.mp3|";
  107. strFilter += "Wave File (*.wav)|*.wav|";
  108. strFilter += "All Files (*.*)|*.*|";
  109. CFileDialog dlgOpen(TRUE, NULL, NULL, OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, 
  110. strFilter, this);
  111. if (IDOK == dlgOpen.DoModal()) 
  112. {
  113. mSourceFile = dlgOpen.GetPathName();
  114. // Rebuild the file playback filter graph
  115. CreateGraph();
  116. }
  117. }
  118. void CSimplePlayerDlg::OnButtonPlay() 
  119. {
  120. if (mFilterGraph)
  121. {
  122. mFilterGraph->Run();
  123. // Start a timer
  124. if (mSliderTimer == 0)
  125. {
  126. mSliderTimer = SetTimer(SLIDER_TIMER, 100, NULL);
  127. }
  128. }
  129. }
  130. void CSimplePlayerDlg::OnButtonPause() 
  131. {
  132. if (mFilterGraph)
  133. {
  134. mFilterGraph->Pause();
  135. // Start a timer
  136. if (mSliderTimer == 0)
  137. {
  138. mSliderTimer = SetTimer(SLIDER_TIMER, 100, NULL);
  139. }
  140. }
  141. }
  142. void CSimplePlayerDlg::OnButtonStop() 
  143. {
  144. if (mFilterGraph)
  145. {
  146. mFilterGraph->SetCurrentPosition(0);
  147. mFilterGraph->Stop();
  148. // Stop the timer
  149. if (mSliderTimer)
  150. {
  151. KillTimer(mSliderTimer);
  152. mSliderTimer = 0;
  153. }
  154. }
  155. }
  156. void CSimplePlayerDlg::OnButtonGrab() 
  157. {
  158. if (mFilterGraph)
  159. {
  160. // Firstly grab a bitmap to a temp file
  161. char  szTemp[] = "C:\mysnapshot.bmp";
  162. if (mFilterGraph->SnapshotBitmap(szTemp))
  163. {
  164. // User can browser for a new file here
  165. CString   strFilter = "BMP File (*.bmp)|*.bmp|";
  166. CFileDialog dlgOpen(FALSE, ".bmp", NULL, OFN_HIDEREADONLY, strFilter, NULL);
  167. if (IDOK == dlgOpen.DoModal()) 
  168. {
  169. ::CopyFile(szTemp, dlgOpen.GetPathName(), FALSE);
  170. ::DeleteFile(szTemp);
  171. }
  172. }
  173. }
  174. }
  175. void CSimplePlayerDlg::OnButtonFullscreen() 
  176. {
  177. if (mFilterGraph)
  178. {
  179. mFilterGraph->SetFullScreen(TRUE);
  180. }
  181. }
  182. void CSimplePlayerDlg::CreateGraph(void)
  183. {
  184. DestroyGraph();
  185. mFilterGraph = new CDXGraph();
  186. if (mFilterGraph->Create())
  187. {
  188. // Render the source clip
  189. mFilterGraph->RenderFile(mSourceFile);
  190. // Set video window and notification window
  191. mFilterGraph->SetDisplayWindow(mVideoWindow.GetSafeHwnd());
  192. mFilterGraph->SetNotifyWindow(this->GetSafeHwnd());
  193. // Show the first frame
  194. mFilterGraph->Pause();
  195. }
  196. }
  197. void CSimplePlayerDlg::DestroyGraph(void)
  198. {
  199. if (mFilterGraph)
  200. {
  201. // Stop the filter graph first
  202. mFilterGraph->Stop();
  203. mFilterGraph->SetNotifyWindow(NULL);
  204. delete mFilterGraph;
  205. mFilterGraph = NULL;
  206. }
  207. }
  208. BOOL CSimplePlayerDlg::OnEraseBkgnd(CDC* pDC)
  209. {
  210. // Intercept background erasing for the movie window, since the
  211.     // video renderer will keep the screen painted.  Without this code,
  212.     // your video window might get painted over with gray (the default
  213.     // background brush) when it is obscured by another window and redrawn.
  214.     CRect rc;
  215.     // Get the bounding rectangle for the movie screen
  216.     mVideoWindow.GetWindowRect(&rc);
  217.     ScreenToClient(&rc);
  218.     // Exclude the clipping region occupied by our movie screen
  219.     pDC->ExcludeClipRect(&rc);
  220. // Erase the remainder of the dialog as usual
  221.     return CDialog::OnEraseBkgnd(pDC);
  222. }
  223. // We use "Return" key and "Esc" key to restore from fullscreen mode
  224. BOOL CSimplePlayerDlg::PreTranslateMessage(MSG* pMsg) 
  225. {
  226. if (pMsg->message == WM_KEYDOWN)
  227. {
  228. if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
  229. {
  230. // Restore form fullscreen mode
  231. RestoreFromFullScreen();
  232. return 1;
  233. }
  234. }
  235. return CDialog::PreTranslateMessage(pMsg);
  236. }
  237. void CSimplePlayerDlg::RestoreFromFullScreen(void)
  238. {
  239. if (mFilterGraph)
  240. {
  241. if (mFilterGraph->GetFullScreen())
  242. {
  243. mFilterGraph->SetFullScreen(FALSE);
  244. }
  245. }
  246. }
  247. void CSimplePlayerDlg::OnTimer(UINT nIDEvent) 
  248. {
  249. if (nIDEvent == mSliderTimer && mFilterGraph)
  250. {
  251. double pos = 0, duration = 1.;
  252. mFilterGraph->GetCurrentPosition(&pos);
  253. mFilterGraph->GetDuration(&duration);
  254. // Get the new position, and update the slider
  255. int newPos = int(pos * 1000 / duration);
  256. if (mSliderGraph.GetPos() != newPos)
  257. {
  258. mSliderGraph.SetPos(newPos);
  259. }
  260. }
  261. CDialog::OnTimer(nIDEvent);
  262. }
  263. BOOL CSimplePlayerDlg::DestroyWindow() 
  264. {
  265. if (mSliderTimer)
  266. {
  267. KillTimer(mSliderTimer);
  268. mSliderTimer = 0;
  269. }
  270. return CDialog::DestroyWindow();
  271. }
  272. void CSimplePlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  273. {
  274. if (pScrollBar->GetSafeHwnd() == mSliderGraph.GetSafeHwnd())
  275. {
  276. if (mFilterGraph)
  277. {
  278. // Calculate the current seeking position
  279. double duration = 1.;
  280. mFilterGraph->GetDuration(&duration);
  281. double pos = duration * mSliderGraph.GetPos() / 1000.;
  282. mFilterGraph->SetCurrentPosition(pos);
  283. }
  284. }
  285. else
  286. {
  287. CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
  288. }
  289. }
  290. // Deal with the graph events 
  291. LRESULT CSimplePlayerDlg::OnGraphNotify(WPARAM inWParam, LPARAM inLParam)
  292. {
  293. IMediaEventEx * pEvent = NULL;
  294. if (mFilterGraph && (pEvent = mFilterGraph->GetEventHandle()))
  295. {
  296. LONG   eventCode = 0, eventParam1 = 0, eventParam2 = 0;
  297. while (SUCCEEDED(pEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0)))
  298. // Spin through the events
  299. pEvent->FreeEventParams(eventCode, eventParam1, eventParam2);
  300. switch (eventCode)
  301. {
  302. case EC_COMPLETE:
  303. OnButtonPause();
  304. mFilterGraph->SetCurrentPosition(0);
  305. break;
  306. case EC_USERABORT:
  307. case EC_ERRORABORT:
  308. OnButtonStop();
  309. break;
  310. default:
  311. break;
  312. }
  313. }
  314. }
  315. return 0;
  316. }
  317. //////////////////////////////////////////////////////////////////////////////////
  318. // Locate a filter within the graph by searching (from renderers upstream)
  319. // looking for a specific interface on the filter
  320. HRESULT CSimplePlayerDlg::FindFilterByInterface(REFIID riid, IBaseFilter** ppFilter)
  321. {
  322.     *ppFilter = NULL;
  323. if (!mFilterGraph)
  324. {
  325. return E_FAIL;
  326. }
  327.     IEnumFilters* pEnum;
  328.     HRESULT hr = mFilterGraph->GetGraph()->EnumFilters(&pEnum);
  329.     if (FAILED(hr)) 
  330. {
  331. return hr;
  332.     }
  333.     IBaseFilter* pFilter = NULL;
  334.     while (pEnum->Next(1, &pFilter, NULL) == S_OK) 
  335. {
  336. // Check for required interface
  337. IUnknown* pUnk;
  338. HRESULT hrQuery = pFilter->QueryInterface(riid, (void**)&pUnk);
  339. if (SUCCEEDED(hrQuery)) 
  340. {
  341. pUnk->Release();
  342. pEnum->Release();
  343. *ppFilter = pFilter;
  344. return S_OK;
  345. }
  346. pFilter->Release();
  347.     }
  348.     pEnum->Release();
  349.     return E_FAIL;
  350. }
  351. void CSimplePlayerDlg::ShowVRPropertyPage(void)
  352. {
  353. IBaseFilter *pFilter = NULL;
  354. if (FAILED(FindFilterByInterface(IID_IVideoWindow, &pFilter)))
  355. {
  356. return;
  357. }
  358. pFilter->Release();
  359. ISpecifyPropertyPages *pProp = NULL;
  360. HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
  361. if (SUCCEEDED(hr)) 
  362. {
  363. // Get the filter's name and IUnknown pointer.
  364. FILTER_INFO FilterInfo;
  365. hr = pFilter->QueryFilterInfo(&FilterInfo); 
  366. IUnknown *pFilterUnk;
  367. pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
  368. // Show the page. 
  369. CAUUID caGUID;
  370. pProp->GetPages(&caGUID);
  371. pProp->Release();
  372. OleCreatePropertyFrame(
  373. this->GetSafeHwnd(),                   // Parent window
  374. 0, 0,                   // Reserved
  375. FilterInfo.achName,     // Caption for the dialog box
  376. 1,                      // Number of objects (just the filter)
  377. &pFilterUnk,            // Array of object pointers. 
  378. caGUID.cElems,          // Number of property pages
  379. caGUID.pElems,          // Array of property page CLSIDs
  380. 0,                      // Locale identifier
  381. 0, NULL                 // Reserved
  382. );
  383. // Clean up.
  384. pFilterUnk->Release();
  385. FilterInfo.pGraph->Release(); 
  386. CoTaskMemFree(caGUID.pElems);
  387. }
  388. }
  389. void CSimplePlayerDlg::OnButtonTest() 
  390. {
  391. ShowVRPropertyPage();
  392. }