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

📄 mediaplayer.cpp

📁 EVC环境下用SDK开发WINCE的应用程序
💻 CPP
字号:
// MediaPlayer.cpp: implementation of the CMediaPlayer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MediaPlayer.h"
#include "Commdlg.h"
#include <math.h>


BEGIN_MESSAGE_MAP(CMediaPlayer, CNDialog)
	ON_BN_CLICKED(IDC_OPEN,OnOpen)
	ON_BN_CLICKED(IDC_PLAY,OnPlay)
	ON_BN_CLICKED(IDC_PREVIOUS,OnPrevious)
	ON_BN_CLICKED(IDC_NEXT,OnNext)
	ON_BN_CLICKED(IDC_STOP,OnStop)
	ON_BN_CLICKED(IDC_MUTE,OnMute)
END_MESSAGE_MAP()

#define MAKEVOLUMETOPOS(l) ((l+10000)/100)
#define MAKEPOSTOVOLUME(p) ((p-100)*100)
BOOL CMediaPlayer::m_bMute = FALSE;
long CMediaPlayer::m_lVolume = 0; // its value range from -10000 to 0;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMediaPlayer::CMediaPlayer(CNWnd* pParent, UINT uID)
	:CNDialog(pParent, uID)
{
	m_pMultimedia = NULL;
	m_hRgnMP = NULL;

	m_bFrozen = FALSE;
}

CMediaPlayer::~CMediaPlayer()
{
	DestroyMultimedia();
}

BOOL CMediaPlayer::OnInitDialog()
{
	CNDialog::OnInitDialog();

	// subclassing dialog item
	m_btnOpen.SubclassDlgItem(IDC_OPEN,this);
	m_btnOpen.SetIcon(IDI_MP_OPEN);

	m_btnPlay.SubclassDlgItem(IDC_PLAY,this);
	m_btnPlay.SetIcon(IDI_MP_PLAY);

	m_btnStop.SubclassDlgItem(IDC_STOP,this);
	m_btnStop.SetIcon(IDI_MP_STOP);

	m_btnPrevious.SubclassDlgItem(IDC_PREVIOUS,this);
	m_btnPrevious.SetIcon(IDI_MP_PREVIOUS);

	m_btnNext.SubclassDlgItem(IDC_NEXT,this);
	m_btnNext.SetIcon(IDI_MP_NEXT);

	m_btnMute.SubclassDlgItem(IDC_MUTE,this);
	m_btnMute.SetIcon(m_bMute ? IDI_MP_MUTE_OFF : IDI_MP_MUTE_ON);

	m_sliderProgress.SubclassDlgItem(IDC_SLIDER, this);
	m_sliderProgress.SetSkin(IDB_BMP_TRACK_BACK2, IDB_BMP_TRACK_BACK, IDB_BMP_TRACK_TICK);
	m_sliderProgress.SetRange(0, 100);
	m_sliderProgress.SetCallback(cbProgressSlider, (void*)this);

	m_sliderVolume.SubclassDlgItem(IDC_SLIDER_VOLUME, this);
	m_sliderVolume.SetSkin(IDB_BMP_TRACK_BACK2, IDB_BMP_TRACK_BACK, IDB_BMP_TRACK_TICK);
	m_sliderVolume.SetRange(0, 100);
	m_sliderVolume.SetPos(MAKEVOLUMETOPOS(m_lVolume));
	m_sliderVolume.SetCallback(cbVolumSlider, (void*)this);

	// timer for auto fullscreen. if user didn't op any mouse or key in a 
	// specified time, play it in fullscreen automatically.
	SetTimer(ID_TIMER_FULLSCREEN, FULLSCREEN_TIME_ELAPSED, NULL);

	// set a timer to refresh ProgressSlider every 1 seconds when playing video.
	SetTimer(ID_TIMER_PROGRESS, 300, NULL);


	return TRUE;
}


BOOL CMediaPlayer::OnEraseBkgnd(HDC hdc)
{
	RECT rc;
	SetRect(&rc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
	FillSolidRect(hdc, &rc, RGB(0,0,0));
	
	SetRect(&rc, 0,SCREEN_HEIGHT - MP_BAR_HEIGHT, 
		SCREEN_WIDTH, SCREEN_HEIGHT);
	FillSolidRect(hdc, &rc, MP_BAR_COLOR);
	
	return TRUE;
}

HBRUSH CMediaPlayer::OnCtlColor(HDC hdc,HWND hwnd, UINT nCtlColor)
{
	// if neccessary, call base class to set DC attributes
	//CNDialog::OnCtlColor(hdc,hwnd, nCtlColor);

	static BOOL s_bInit = FALSE;
	static HBRUSH s_hbrMenuBar;
	if( !s_bInit )
	{
		s_hbrMenuBar = CreateSolidBrush(MP_BAR_COLOR);
		s_bInit = TRUE;
	}
	// all buttons and route info static control.
	if(nCtlColor == WM_CTLCOLORBTN )
	{
		return s_hbrMenuBar;
	}

	return 	CNDialog::OnCtlColor(hdc,hwnd, nCtlColor);
}


/////////////////////////////////////////////////////////////////////////////
// 创建Filter Graph
void CMediaPlayer::CreateMultimedia(void)
{
	DestroyMultimedia();

	m_pMultimedia = new CMultimedia();
	if( m_pMultimedia->Create() )
	{
		// Render the source clip
		m_pMultimedia->RenderFile(m_strFileName);

		// Set video window and notification window

		m_pMultimedia->SetDisplayWindow(this->GetSafeHwnd());

		RECT rcWindow;
		GetClientRect(&rcWindow);
		m_pMultimedia->ResizeVideoWindow(0,0,
			rcWindow.right - rcWindow.left,
			rcWindow.bottom - rcWindow.top-MP_BAR_HEIGHT);

		m_pMultimedia->SetNotifyWindow(this->GetSafeHwnd());

		// set volume.
		m_pMultimedia->SetAudioVolume(m_bMute ? -10000:m_lVolume);

		// Show the first frame
		m_pMultimedia->Run();
		m_btnPlay.SetIcon(IDI_MP_PAUSE);
	}
	else
	{
		TRACE(_T("Multimedia Creating fail.\n"));
	}
}

/////////////////////////////////////////////////////////////////////////////
// 析构Filter Graph
void CMediaPlayer::DestroyMultimedia(void)
{
	if(m_pMultimedia)
	{
		// Stop the filter graph first
		m_pMultimedia->Stop();
		m_pMultimedia->SetNotifyWindow(NULL);

		delete m_pMultimedia;
		m_pMultimedia = NULL;
	}

	// delete it since multimedia play stoped.
	if(m_hRgnMP != NULL)
	{
		DeleteObject(m_hRgnMP);
		m_hRgnMP = NULL;
	}

}


void CMediaPlayer::OnOpen()
{
	TCHAR strFilter[255] = _T("媒体文件(所有类型)\0*.avi;*.mpg;*.mpeg;*.mp3;*.wma;*.wav;*.mid;*.rmi;*.wmv;*.asf\0");
		//MIDI 文件(midi)(*.mid;*.rmi;*.midi)\0*.mid;*.rmi;*.midi\0");
	/*strFilter += L"Windows Media 文件(asf)(*.asf;*.wm;*.wmv)\0*.asf;*.wm;*.wmv\0";
	strFilter += L"视频文件(avi)(*.avi;*.wmv)\0*.avi;*.wmv\0";
	strFilter += L"音频文件(wav)(*.wav)\0*.wav\0";
	strFilter += L"电影文件(mpeg)(*.mpg;*.mpeg)\0*.mpg;*.mpeg\0";
	strFilter += L"mp3 文件 (*.mp3)\0*.mp3\0";
	strFilter += L"wma 文件 (*.wma)\0*.wma\0";
	strFilter += L"All Files (*.*)\0*.*\0";
*/
	TCHAR		szFileFullName[MAX_PATH+1];
	TCHAR		szTitle[] = _T("Open file");
	OPENFILENAME ofn;       // common dialog box structure

	memset(szFileFullName, 0, sizeof(szFileFullName));
	
	// Initialize OPENFILENAME
	ZeroMemory(&ofn, sizeof(OPENFILENAME));
	ofn.hwndOwner = NGetMainWnd()->GetSafeHwnd();
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = NULL;
	ofn.lpstrFile = szFileFullName;
	ofn.nMaxFile = sizeof(szFileFullName)/sizeof(TCHAR);
	ofn.lpstrFilter = 
		L"媒体文件(所有类型)\0*.avi;*.mpg;*.mpeg;*.mp3;*.wma;*.wav;*.mid;*.rmi;*.wmv;*.asf\0"
		L"MIDI 文件(midi)(*.mid;*.rmi;*.midi)\0*.mid;*.rmi;*.midi\0"
		L"Windows Media 文件(asf)(*.asf;*.wm;*.wmv)\0*.asf;*.wm;*.wmv\0"
		L"视频文件(avi)(*.avi;*.wmv)\0*.avi;*.wmv\0"
		L"音频文件(wav)(*.wav)\0*.wav\0"
		L"电影文件(mpeg)(*.mpg;*.mpeg)\0*.mpg;*.mpeg\0"
		L"mp3 文件 (*.mp3)\0*.mp3\0"
		L"wma 文件 (*.wma)\0*.wma\0"
		L"All Files (*.*)\0*.*\0";
	
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = 0;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	ofn.lpstrTitle = szTitle;

	m_bFrozen = TRUE;
	// Display the Open dialog box. 
	if ( GetOpenFileName(&ofn) ) 
	{
		m_bFrozen = FALSE;
		// help to refresh window quickly.
		InvalidateRect(NULL);
		UpdateWindow();


		m_strFileName = szFileFullName;
		TRACE(_T("%s"),m_strFileName.GetString());
		// Rebuild the file playback filter graph
		CreateMultimedia();
	}
	m_bFrozen = FALSE;
	
}
void CMediaPlayer::OnPlay()
{
	if(m_pMultimedia)
	{
		if( m_pMultimedia->IsRunning() )
		{
			m_pMultimedia->Pause();
			m_btnPlay.SetIcon(IDI_MP_PLAY);

		}
		else
		{
			m_pMultimedia->Run();
			m_btnPlay.SetIcon(IDI_MP_PAUSE);
		}
		m_btnPlay.InvalidateRect(NULL);
	}
}

void CMediaPlayer::OnPrevious()
{
	if(m_pMultimedia)
	{
		double dCurrPos = 0;
		double dDuration = 0;
		m_pMultimedia->GetDuration(&dDuration);
		m_pMultimedia->Pause();
		m_pMultimedia->GetCurrentPosition(&dCurrPos);
		dCurrPos -= dDuration/20;	// 1/20
		dCurrPos = (dCurrPos < 0) ? 0 : dCurrPos;
		m_pMultimedia->SetCurrentPosition(dCurrPos);
		m_pMultimedia->Run();
		/*if(m_nProgressTimer == 0)
		{
			m_nProgressTimer = SetTimer(PROGRESS_TIMER, 100, NULL);
		}*/
	}
}

// forward
void CMediaPlayer::OnNext()
{
	if(m_pMultimedia)
	{
		double dCurrPos = 0;
		double dDuration = 0;
		m_pMultimedia->GetDuration(&dDuration);
		m_pMultimedia->Pause();
		m_pMultimedia->GetCurrentPosition(&dCurrPos);
		dCurrPos += dDuration/20;	//  1/20
		dCurrPos = (dCurrPos > dDuration) ? dDuration : dCurrPos;
		m_pMultimedia->SetCurrentPosition(dCurrPos);
		m_pMultimedia->Run();
		/*if(m_nProgressTimer == 0)
		{
			m_nProgressTimer = SetTimer(PROGRESS_TIMER, 100, NULL);
		}*/
	}
}

void CMediaPlayer::OnStop()
{
	if(m_pMultimedia)
	{
		m_pMultimedia->SetCurrentPosition(0);
		m_pMultimedia->Stop();

		m_btnPlay.SetIcon(IDI_MP_PLAY);
		m_btnPlay.InvalidateRect(NULL);
		/*if(m_nProgressTimer)
		{
			KillTimer(m_nProgressTimer);
			m_nProgressTimer = 0;
		}*/
	}
}

void CMediaPlayer::OnMute()
{
	m_bMute = !m_bMute;
	if(m_pMultimedia)
	{
		m_pMultimedia->SetAudioVolume(m_bMute ? -10000 : m_lVolume);
	}
	m_btnMute.SetIcon(m_bMute ? IDI_MP_MUTE_OFF : IDI_MP_MUTE_ON);
	m_btnMute.InvalidateRect(NULL);
}

void CMediaPlayer::OnIdle()
{
	if( m_bFrozen || (m_pMultimedia && m_pMultimedia->GetFullScreen() ))
		return;

	// if we have opened a multimedia, create the clip region for video window.
	if( m_hRgnMP==NULL && m_pMultimedia )
	{
		long lWidth = 0;
		long lHeight = 0;
		m_pMultimedia->GetVideoSize(lWidth, lHeight);
		
		// set clip region for the dshow. avoid GDI write to the region for playing.
		if( lWidth >0 && lHeight >0 )	// it's a video file.
		{
			RECT rect;
			GetClientRect(&rect);
			
			m_hRgnMP = CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
			HRGN hrgn = CreateRectRgn(rect.left,rect.top,
				rect.right,rect.bottom - MP_BAR_HEIGHT);
			
			CombineRgn(m_hRgnMP,m_hRgnMP,hrgn,RGN_DIFF);
			
			DeleteObject(hrgn);
			
		}
		
	}


#ifdef PC_VERSION
	HDC hdc = GetWindowDC();
#else // for CE
	HDC hdc = GetDCEx(m_hWnd, NULL, DCX_WINDOW | DCX_CACHE );
#endif
	HRGN hOldRgn = (HRGN)SelectObject(hdc, m_hRgnMP);

	BitBlt(hdc,0,0,SCREEN_WIDTH, SCREEN_HEIGHT, g_hdcUI,0,0,SRCCOPY);

	SelectObject(hdc, hOldRgn);
	ReleaseDC(hdc);
}

void CMediaPlayer::OnLButtonDblClk(UINT nFlags, POINT point) 
{
	if(m_pMultimedia)
	{
		m_pMultimedia->SetFullScreen(! m_pMultimedia->GetFullScreen());
	}

}


void CMediaPlayer::OnTimer(UINT nIDEvent)
{
	if( nIDEvent == ID_TIMER_FULLSCREEN
		&& m_pMultimedia 
		&& m_pMultimedia->IsRunning()
		&& !m_pMultimedia->GetFullScreen() 
		&& GetForegroundWindow() == GetSafeHwnd())
	{
		m_pMultimedia->SetFullScreen(TRUE);
	} else if ( nIDEvent == ID_TIMER_PROGRESS && m_pMultimedia )
	{
		m_sliderProgress.GetPos();
		int min, max;
		m_sliderProgress.GetRange(&min, &max);
		
		double outDuration, curDuration;
		if( !m_pMultimedia->GetDuration(&outDuration) )
			return;
		if( !m_pMultimedia->GetCurrentPosition(&curDuration) )
			return;
		
		int pos = (int) (curDuration * (max - min) / outDuration);
		m_sliderProgress.SetPos(pos);

		// check if it finishes playback, if so, back to very first frame.
		if( fabs(curDuration-outDuration) < 0.0001 )
		{
			m_btnStop.PostMessage(BM_CLICK,0,0);
			PostMessage(WM_TIMER,(WPARAM)ID_TIMER_PROGRESS, 0);
		}
	}
	
}

LRESULT CMediaPlayer::WndProc(HWND hDlg,
		UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if( uMsg == WM_LBUTTONDOWN 
		|| uMsg == WM_LBUTTONUP
		|| uMsg == WM_RBUTTONDOWN 
		|| uMsg == WM_RBUTTONUP
		|| uMsg == WM_MOUSEMOVE )
		SetTimer(ID_TIMER_FULLSCREEN, FULLSCREEN_TIME_ELAPSED, NULL);

	return CNDialog::WndProc(hDlg, uMsg, wParam, lParam);
}


void CMediaPlayer::cbVolumSlider(void *pObject)
{
	CMediaPlayer* pMP = static_cast<CMediaPlayer*>(pObject);
	pMP->OnVolumeSlider();
}


void CMediaPlayer::OnVolumeSlider()
{
	int pos = m_sliderVolume.GetPos();
	int min, max;
	m_sliderVolume.GetRange(&min, &max);

	// let it range from -3333 ~ 0
	m_lVolume = MAKEPOSTOVOLUME( (pos-min)*100/(max-min) ) / 3;

	if( m_pMultimedia )
		m_pMultimedia->SetAudioVolume(m_bMute ? -10000:m_lVolume);
}

void CMediaPlayer::cbProgressSlider(void *pObject)
{
	CMediaPlayer* pMP = static_cast<CMediaPlayer*>(pObject);
	pMP->OnProgressSlider();
}


void CMediaPlayer::OnProgressSlider()
{
	int pos = m_sliderProgress.GetPos();
	int min, max;
	m_sliderProgress.GetRange(&min, &max);

	if ( m_pMultimedia )
	{
		double outDuration;
		if( !m_pMultimedia->GetDuration(&outDuration) )
			return;
		
		outDuration = (pos-min+1.5)*outDuration / (max - min);
		m_pMultimedia->SetCurrentPosition(outDuration);
	}
	else
	{
		m_sliderProgress.SetPos(min);
	}
}

⌨️ 快捷键说明

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