⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 movieview.cpp

📁 自制电影播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	return NOERROR;
}

//Perform frame by frame updates and blits. Set the stream 
//state to STOP if there are no more frames to update.
void CMovieView::RenderToSurface(BOOL bSingleBlit)
{
	HRESULT		hr;
	POINT		point;
	CRect		rect, rect2;

	if (!m_bFileLoaded || !m_bAppactive) return;

	if (!m_bPaused)
	{
		//update each frame
		if (m_pSample->Update(0, NULL, NULL, 0) != S_OK) 
		{
			m_bAppactive = FALSE;
			m_pMMStream->SetState(STREAMSTATE_STOP);		
		}
	}

	rect.top = rect.left = 0;			
    rect.bottom = m_video_height;
    rect.right = m_video_width;

	if (!bSingleBlit)
	{
		// performs a couple of operations including a blit.

		//blit from the offscreen surface #2 (video sample-backbuffer)
		// to the offscreen surface #1 (copy-backbuffer)
		hr = m_pDDSOffscreen->Blt(&rect, m_pDDSOffscreen2, &rect, DDBLT_WAIT, NULL); 
		if(FAILED(hr))
		{
			AfxMessageBox("Blt failed");
			ExitCode();
		}
	}

	//stretchblit from the offscreen surface #1 to the primary surface
	//get window coordinates to blit into
	GetClientRect(&rect2); // rectangle for the primary surface
	point.x = rect2.top; // transfrom rect into screen coordinates
	point.y = rect2.left;
	ClientToScreen(&point);
	rect2.left = point.x;
	rect2.top = point.y;
	point.x = rect2.right;
	point.y = rect2.bottom;
	ClientToScreen(&point);
	rect2.right = point.x;
	rect2.bottom= point.y;

	// In single blit mode, choose the sample-backbuffer to stretch-blit from
	// Otherwise, blit from the copy-backbuffer
	IDirectDrawSurface *surface= bSingleBlit ? m_pDDSOffscreen2 : m_pDDSOffscreen;

	hr = m_pPrimarySurface->Blt(&rect2, surface, &rect, DDBLT_WAIT, NULL); 
	if(FAILED(hr))
	{
		AfxMessageBox(_T("Blt failed"));
		ExitCode();
	}
	
}



void CMovieView::DestroyObjects()
{

	//Release MultiMedia streaming Objects
	if (m_pMMStream != NULL) {
		m_pMMStream->Release();
		m_pMMStream= NULL;
	}
	if (m_pSample != NULL) {
		m_pSample->Release();   
		m_pSample = NULL;
	}
	if (m_pDDStream != NULL) {
		m_pDDStream->Release();
		m_pDDStream= NULL;
	}
	if (m_pPrimaryVidStream != NULL) {
		m_pPrimaryVidStream->Release();
		m_pPrimaryVidStream= NULL;
	}

	// Release DirectDrawEx interfaces
	if (m_pDDSOffscreen != NULL) {
		m_pDDSOffscreen->Release();
		m_pDDSOffscreen= NULL;
	}
	if (m_pDDSOffscreen2 != NULL) {
		m_pDDSOffscreen2->Release();
		m_pDDSOffscreen2= NULL;
	}
	if (m_pDDClipper != NULL) {
		m_pDDClipper->Release();
		m_pDDClipper= NULL;
	}
	if (m_pPrimarySurface != NULL) {
		m_pPrimarySurface->Release();
		m_pPrimarySurface= NULL;
	}
	if (m_pDD3 != NULL) {
		m_pDD3->Release();
		m_pDD3= NULL;
	}
	if (m_pDD != NULL) {
		m_pDD->Release();
		m_pDD= NULL;
	}
	if (m_pDDF != NULL) {
		m_pDDF->Release();
		m_pDDF= NULL;
	}

}



void CMovieView::ExitCode()
{
	DestroyObjects();
	
	::PostQuitMessage(0);
	CoUninitialize();
}








afx_msg void CMovieView::OnFileOpen()
{

	//If a file is already open - call STOP first
	if (m_bAppactive && m_bFileLoaded) 
	{
		m_pMMStream->SetState(STREAMSTATE_STOP);
		// as the routine OnFileOpen can be called a couple of times, each time
		// the multimedia stream and directDraw surfaces should be released before
		// we start the whole story once again...
		DestroyObjects();
	}

	if (m_pDD==NULL)
	{
		HRESULT	hr = InitDDrawEx();	// initialize DirectDrawEx
		if (FAILED(hr)) ExitCode();
	}

	static BOOL bOpen = TRUE; 
	
	GetOpenMovieFile(m_szFilename);
	if (bOpen) 
	{
		
		HRESULT hr = RenderFileToMMStream(m_szFilename);  
		if (FAILED(hr)) 
		{
			// file format not supported
			// hence destroy stream
			DestroyObjects();
			m_bAppactive = m_bFileLoaded = FALSE;
		}
		else
		{
			hr = InitRenderToSurface();
			if (FAILED(hr)) 
			{
				ExitCode();
			}
			m_bAppactive = m_bFileLoaded = TRUE;
			m_bPaused = FALSE;		//Take care of any old pauses
			//Now set the multimedia stream to RUN
			hr = m_pMMStream->SetState(STREAMSTATE_RUN);
			if (FAILED(hr))
			{  
				ExitCode();
			}
		}
	}	// end if (bOpen)
}



// Display the open dialog box to retrieve the user-selected movie file
BOOL CMovieView::GetOpenMovieFile(LPSTR szName)//LPSTR szName
{
	OPENFILENAME	ofn;
	
	ofn.lStructSize       = sizeof(OPENFILENAME);
	ofn.hwndOwner         = AfxGetMainWnd()->m_hWnd;
	ofn.lpstrFilter       = NULL;
	ofn.lpstrFilter       = "Video (*.avi;*.mov;*.mpg;*.mpeg)\0*.avi;*.mov;*.mpg;*.mpeg\0All Files (*.*)\0*.*\0";
	ofn.lpstrCustomFilter = NULL;
	ofn.nFilterIndex      = 1;
	*szName = 0;
	ofn.lpstrFile         = szName;
	ofn.nMaxFile          = MAX_PATH;
	ofn.lpstrInitialDir   = NULL;
	ofn.lpstrTitle        = NULL;
	ofn.lpstrFileTitle    = NULL;
	ofn.lpstrDefExt       = NULL;
	ofn.Flags             = OFN_FILEMUSTEXIST | OFN_READONLY | OFN_PATHMUSTEXIST;
	return ::GetOpenFileName((LPOPENFILENAME)&ofn);
}



afx_msg void CMovieView::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
	if (nChar==VK_SPACE)
		switchPlayPause();
}

afx_msg void CMovieView::OnLButtonDown( UINT nFlags, CPoint point )
{
	switchPlayPause();

}


void CMovieView::switchPlayPause()
{
	// pause
	if (!m_bPaused && m_bFileLoaded) 
	{	
		m_pMMStream->GetTime(&m_StreamTime);
		m_pMMStream->SetState(STREAMSTATE_STOP);					
		//m_bAppactive = FALSE;
		m_bPaused	= TRUE;
	}
	else // play
	{
		if (m_bPaused) 
		{	// If its in a paused state, seek and run
			m_pMMStream->Seek(m_StreamTime);
			m_pMMStream->SetState(STREAMSTATE_RUN);
			m_bAppactive = TRUE;
			m_bPaused = FALSE;
		}
	}
}

afx_msg void CMovieView::OnStart()
{
	if (m_bFileLoaded)	
	{
		if (!m_bAppactive) // Restart the stream
			m_StreamTime=0;
		if (!m_bAppactive || m_bPaused) // seek to restart or to end the pause state
		{
			m_pMMStream->Seek(m_StreamTime);
			m_pMMStream->SetState(STREAMSTATE_RUN); // run
		}
		m_bAppactive = TRUE;
		m_bPaused = FALSE;
	}
	else
	{
		AfxMessageBox(_T("Please select a movie file first."));
	}

}

			
afx_msg void CMovieView::OnPause()
{
	// Pause if not already in a paused state and you have a file loaded
	if (!m_bPaused && m_bFileLoaded) 
	{	
		m_pMMStream->GetTime(&m_StreamTime);
		m_pMMStream->SetState(STREAMSTATE_STOP);
		m_bAppactive = FALSE;
		m_bPaused	= TRUE;
	}
}
	
afx_msg void CMovieView::OnStop()
{
	if (m_bFileLoaded) 
	{
		m_pMMStream->SetState(STREAMSTATE_STOP);
		m_StreamTime = 0;	// Reset the stream time to 0
		m_pMMStream->Seek(m_StreamTime);	//Run one frame to reset video
		m_pMMStream->SetState(STREAMSTATE_RUN);
		RenderToSurface();
		m_pMMStream->SetState(STREAMSTATE_STOP); // Stop for real this time
		m_StreamTime = 0;
	}
	m_bAppactive = FALSE;
}




/////////////////////////////////////////////////////////////////////////////
// CMovieView diagnostics

#ifdef _DEBUG
void CMovieView::AssertValid() const
{
	CView::AssertValid();
}

void CMovieView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMovieDoc* CMovieView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMovieDoc)));
	return (CMovieDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMovieView message handlers

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -