DVD Playback (with MFC)

The previous DVD playback sample used the default video window for the DVD playback. This page shows you how to render DVD video on a custom window. Please note that error handling codes are omitted to keep the sample code simple.

Sample code

The following sample code shows how to use render DVD video on a custom MFC window.

Differences between this sample and the MFC sample shown before are the DVD graph creation part, and RenderFile part. This sample code plays DVD in the DVD drive. If the DVD drive is empty, this sample will not work.


#include <afxwin.h>

#include <dshow.h>

#define	WM_GRAPH_NOTIFY		(WM_APP + 1)

class CMainWin : public CFrameWnd
{
public:
	CMainWin();
	~CMainWin();
	DECLARE_MESSAGE_MAP()

private:
	IDvdGraphBuilder *pDvdGraphBuilder;
	IGraphBuilder *pGraphBuilder;
	IMediaControl *pMediaControl;
	IMediaEventEx *pMediaEventEx;
	IVideoWindow *pVideoWindow;

	bool bRunning;

protected:
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	LRESULT OnGraphNotify(WPARAM wParam, LPARAM lParam);
};

CMainWin::CMainWin()
{
 Create(NULL, "Sample");

 bRunning = false;
 CoInitialize(NULL);
}

CMainWin::~CMainWin()
{
 if (pMediaEventEx != NULL) {
	pMediaEventEx->Release();
 }

 if (pMediaControl != NULL) {
	pMediaControl->Release();
 }

 if (pVideoWindow != NULL) {
	pVideoWindow->Release();
 }

 if (pGraphBuilder != NULL) {
	pGraphBuilder->Release();
 }

 CoUninitialize();
}

void
CMainWin::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 if (bRunning == false) {
   CoCreateInstance(CLSID_DvdGraphBuilder,
       NULL,
       CLSCTX_INPROC_SERVER,
       IID_IDvdGraphBuilder,
       (LPVOID *)&pDvdGraphBuilder);

   AM_DVD_RENDERSTATUS stat;
   pDvdGraphBuilder->RenderDvdVideoVolume(NULL,
       AM_DVD_HWDEC_PREFER, &stat);

   pDvdGraphBuilder->GetFiltergraph(&pGraphBuilder);

   pGraphBuilder->QueryInterface(IID_IMediaControl,
       (LPVOID *)&pMediaControl);

   pGraphBuilder->QueryInterface(IID_IMediaEventEx,
       (LPVOID *)&pMediaEventEx);
   pMediaEventEx->SetNotifyWindow((OAHWND)GetSafeHwnd(),
       WM_GRAPH_NOTIFY, NULL);

   pGraphBuilder->QueryInterface(IID_IVideoWindow,
       (LPVOID *)&pVideoWindow);
   pVideoWindow->put_Owner((OAHWND)GetSafeHwnd());

   pVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);

   RECT rect;
   GetClientRect(&rect);
   pVideoWindow->SetWindowPosition(0, 0,
       rect.right - rect.left,
       rect.bottom - rect.top);

   pVideoWindow->put_Visible(OATRUE);
   pVideoWindow->SetWindowForeground(OATRUE);

   pMediaControl->Run();

   bRunning = true;
 }
}

// called when an event is triggered
LRESULT
CMainWin::OnGraphNotify(WPARAM wParam, LPARAM lParam)
{
 long evCode;
 LONG param1, param2;

 // Get all events
 while (SUCCEEDED(pMediaEventEx->GetEvent(&evCode,
				&param1, &param2, 0))) {
	pMediaEventEx->FreeEventParams(evCode, param1, param2);

	switch (evCode) {
		case EC_COMPLETE:
			// playback complete
			MessageBox("EC_COMPLETE");
			break;
	}
 }

 return NOERROR;
}

class CApp : public CWinApp
{
public:
	BOOL InitInstance();
};

BOOL CApp::InitInstance()
{
 m_pMainWnd = new CMainWin;
 m_pMainWnd->ShowWindow(m_nCmdShow);
 m_pMainWnd->UpdateWindow();

 return true;
}

BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)
	ON_WM_CHAR()
	ON_MESSAGE(WM_GRAPH_NOTIFY, OnGraphNotify)
END_MESSAGE_MAP()

CApp App;


  

Copyright (C) GeekPage.JP. All rights reserved.