📄 movieview.cpp
字号:
//==========================================================================;
//
// 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 + -