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

📄 movieview.cpp

📁 自制电影播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//==========================================================================;
//
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE.
//
//  Copyright (c) 1994 - 1998  Microsoft Corporation.  All Rights Reserved.
//
//--------------------------------------------------------------------------;
//

// MovieView.cpp : implementation of the CMovieView class
// aze
// (c) Stephane Rodriguez 98

#include "stdafx.h"
#include "MovieApp.h"
#include "MovieDoc.h"

#include <mmstream.h>	// Multimedia stream interfaces
#include <mmreg.h>
#include <amstream.h>	// DirectShow multimedia stream interfaces
#include <initguid.h>   // Defines DEFINE_GUID macro and enables GUID initialization
#include "MovieView.h"

#include <atlbase.h>
CComModule _Module;
#include <atlcom.h>
#include <atlimpl.cpp>


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMovieView

IMPLEMENT_DYNCREATE(CMovieView, CView)

BEGIN_MESSAGE_MAP(CMovieView, CView)
	//{{AFX_MSG_MAP(CMovieView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(IDM_START, OnStart)
	ON_COMMAND(IDM_PAUSE, OnPause)
	ON_COMMAND(IDM_STOP, OnStop)
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMovieView construction/destruction

CMovieView::CMovieView()
{
	m_bAppactive=FALSE;
	m_bFileLoaded = FALSE;
	m_bPaused=FALSE;

	// MultiMedia streaming interfaces
	m_pMMStream=NULL;
	m_pPrimaryVidStream=NULL;    
	m_pDDStream=NULL;
	m_pSample=NULL;

	//DirectDrawEx interfaces
	m_pDD=NULL;
	m_pDD3=NULL;
	m_pDDF=NULL;
	m_pPrimarySurface=NULL;
	m_pDDSOffscreen=NULL;
	m_pDDSOffscreen2=NULL;
	m_pDDClipper=NULL;

	// attach the view to the app (to easier interfacing)
	((CMovieApp*)AfxGetApp())->OnViewChildCreated(this);

}

CMovieView::~CMovieView()
{
	ExitCode();
}

BOOL CMovieView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMovieView drawing

void CMovieView::OnDraw(CDC* pDC)
{
	CMovieDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// draw a black background when the video is not yet loaded
	// so we are dealing with a video application and not a simple
	// MFC MDI type.
	if (!m_bFileLoaded)
	{
		CBrush brush;
		brush.CreateSolidBrush(RGB(0,0,0));

		CRect rect;
		GetClientRect(&rect);

		pDC->FillRect(&rect,&brush);
	}
	
}

BOOL CMovieView::OnEraseBkgnd( CDC* pDC )
{
	return TRUE;
}



HRESULT CMovieView::InitDDrawEx()
{    
	HRESULT			hr=NOERROR;
	DDSURFACEDESC	ddsd, ddsd2, ddsd3;

	CoInitialize(NULL);
	
	//Create a DirectDrawFactory object
	hr = CoCreateInstance(
		CLSID_DirectDrawFactory, NULL, CLSCTX_INPROC_SERVER, 
		IID_IDirectDrawFactory, (void **)&m_pDDF);
	if (FAILED(hr))
	{   
		AfxMessageBox(_T("Couldn't create DirectDrawFactory"));
		return E_FAIL;
	}


	//Call the IDirectDrawFactory::CreateDirectDraw method to create the 
	//DirectDraw object, set the cooperative level, and get the address 
	//of an IDirectDraw interface pointer
	hr = (m_pDDF->CreateDirectDraw(NULL, ::GetDesktopWindow(), DDSCL_NORMAL, 
				NULL, NULL, &m_pDD));   

	if (FAILED(hr))
	{   
		AfxMessageBox(_T("Couldn't create DirectDraw object"));
		return E_FAIL;
	}

	//Now query for the new IDirectDraw3 interface
	hr =(m_pDD->QueryInterface(IID_IDirectDraw3, (LPVOID*)&m_pDD3));
	
	if (FAILED(hr))
	{   
		AfxMessageBox(_T("Couldn't get IDirectDraw3"));
		return E_FAIL;
	}

    //Initialize the DDSURFACEDESC structure for the primary surface
	::ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);    
	ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 
    hr = m_pDD3->CreateSurface(&ddsd, &m_pPrimarySurface, NULL);

    if(FAILED(hr))
    {   
		AfxMessageBox(_T("Couldn't create Primary Surface"));
    	return E_FAIL;
	}


	// Now, do the same for the offscreen surfaces.

    // The offscreen surface needs to use the same pixel format as the primary.
    // Query the primary surface to for its pixel format.
    hr = m_pPrimarySurface->GetSurfaceDesc(&ddsd);
    if(FAILED(hr))
    {   
		AfxMessageBox(_T("Couldn't GetSurfaceDesc"));
		return E_FAIL;
    }

	// Now, set the info for the offscreen surface #1, using the primary's pixel format.
    ::ZeroMemory(&ddsd2, sizeof(ddsd2));
	ddsd2.dwSize = sizeof(ddsd2);    
	ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
    ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd2.dwHeight = ddsd.dwHeight;	//set the height of the surfaces equal
    ddsd2.dwWidth  = ddsd.dwWidth;	//set the width of the surfaces equal
    ddsd2.ddpfPixelFormat = ddsd.ddpfPixelFormat; //set the pixel formats equal


    // Now, create the offscreen surface #1 and query for the latest interface.
	hr = m_pDD3->CreateSurface(&ddsd2, &m_pDDSOffscreen, NULL);
	if(FAILED(hr))
    {   
		AfxMessageBox(_T("Couldn't create Offscreen Surface"));
		return E_FAIL;
    }


	// Now, set the info for the offscreen surface #2, using the primary's pixel format.
    ::ZeroMemory(&ddsd3, sizeof(ddsd3));
	ddsd3.dwSize = sizeof(ddsd3);    
	ddsd3.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
    ddsd3.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd3.dwHeight = ddsd.dwHeight;	//set the height of the surfaces equal
    ddsd3.dwWidth  = ddsd.dwWidth;	//set the width of the surfaces equal
    ddsd3.ddpfPixelFormat = ddsd.ddpfPixelFormat; //set the pixel formats equal


    // Now, create the offscreen surface #2 and query for the latest interface.
	hr = m_pDD3->CreateSurface(&ddsd3, &m_pDDSOffscreen2, NULL);
	if(FAILED(hr))
    {   
		AfxMessageBox(_T("Couldn't create Offscreen Surface2"));
		return E_FAIL;
    }




	//Add code for Clipper
	hr = m_pDD3->CreateClipper(0, &m_pDDClipper, NULL);
	if(FAILED(hr))
    {   
		AfxMessageBox(_T("Couldn't create Clipper"));
		return E_FAIL;
    }
	
	hr = m_pPrimarySurface->SetClipper(m_pDDClipper);
	if(FAILED(hr))
    {   
		AfxMessageBox(_T("Call to SetClipper failed"));
		return E_FAIL;
    }

	
	hr = m_pDDClipper->SetHWnd(0, AfxGetMainWnd()->m_hWnd);
	if(FAILED(hr))
    {   
		AfxMessageBox(_T("Call to SetHWnd failed"));
	    return E_FAIL;
    }

	return NOERROR;	
}



//Renders a file to a multimedia stream
HRESULT CMovieView::RenderFileToMMStream(LPCTSTR szFilename)		//IMultiMediaStream **ppMMStream
{	
	IAMMultiMediaStream *pAMStream;
    HRESULT hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, 
        CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, 
        (void **)&pAMStream);
    if (FAILED(hr))
    {
        return hr;
    }

    WCHAR wPath[MAX_PATH + 1];
    MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wPath, MAX_PATH + 1);

    pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL);
    pAMStream->AddMediaStream(m_pDD, &MSPID_PrimaryVideo, 0, NULL);
    pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
    hr = pAMStream->OpenFile(wPath, 0);
    if (SUCCEEDED(hr))
    {
        hr = pAMStream->QueryInterface(IID_IMultiMediaStream, 
            (void**)&m_pMMStream);
    }
    pAMStream->Release();
    return hr;
//	return NOERROR;
}



//Create the stream sample which will be used to call updates on the video
HRESULT CMovieView::InitRenderToSurface()
{    
	HRESULT			hr;
	DDSURFACEDESC	ddsd;
	CRect			rect;
	
	//Use the multimedia stream to get the primary video media stream
    hr = m_pMMStream->GetMediaStream(MSPID_PrimaryVideo, &m_pPrimaryVidStream);
	if (FAILED(hr))
	{   goto Exit;
	}
	//Use the media stream to get the IDirectDrawMediaStream
    hr = m_pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&m_pDDStream);
	if (FAILED(hr))
	{   goto Exit;
	}
	//Must set dwSize before calling GetFormat
    ddsd.dwSize = sizeof(ddsd);
    hr = m_pDDStream->GetFormat(&ddsd, NULL, NULL, NULL);
	if (FAILED(hr))
	{   goto Exit;
	}

	rect.top = rect.left = 0;			
    rect.bottom = ddsd.dwHeight; m_video_height=(WORD)rect.bottom;
    rect.right = ddsd.dwWidth; m_video_width=(WORD)rect.right;

	//Create the stream sample in offscreen surface #2 (attachment)
	hr = m_pDDStream->CreateSample(m_pDDSOffscreen2, &rect, 0, &m_pSample);
	if (FAILED(hr))
	{   goto Exit;
	}

Exit:
	if (FAILED(hr)) 
	{	
		AfxMessageBox(_T("Initialization failure in InitRenderToSurface"));
		return E_FAIL;

⌨️ 快捷键说明

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