gps/GPSProject/MediaPlayer/MediaPlayerDlg.cpp

736 lines
16 KiB
C++
Executable File

// MediaPlayerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MediaPlayer.h"
#include "MediaPlayerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMediaPlayerDlg dialog
CMediaPlayerDlg::CMediaPlayerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMediaPlayerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMediaPlayerDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_InitDC = false;
// 初始化背景画刷
CBitmap tmpBmp;
// 从资源中加载背景图片
tmpBmp.LoadBitmap(IDB_MOVE_WND);
m_BgDC.CreateCompatibleDC(NULL);
m_BgDC.SelectObject(&tmpBmp);
tmpBmp.DeleteObject();
// 加载资源文件
theApp.LoadLanguageRes(theApp.GetLanguage());
m_txtFont.CreateFont(16,0,0,0,FW_NORMAL,0,0,0,GB2312_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,_T("Arial"));
// WCHAR strRes[MAX_PATH];
// CString(LoadString(theApp.GetResourceLib(),IDS_MOVEPLAYER_TITLE,strRes,MAX_PATH));
m_TitleText = L"";
m_SourceFile = L"";
m_pGraph = NULL;
m_pSeek = NULL;
m_pEvent = NULL;
m_pMediaControl = NULL;
m_InitGraph = FALSE;
m_BlockD = FALSE;
m_Timer = NULL;
m_FullScreen = false;
}
CMediaPlayerDlg::~CMediaPlayerDlg()
{
m_BgDC.DeleteDC();
m_MemDC.DeleteDC();
m_BlockDC.DeleteDC();
m_BlockDCD.DeleteDC();
m_txtFont.DeleteObject();
if (m_Timer)
{
timeKillEvent(m_Timer);
}
if (m_pGraph)
{
m_pGraph->Release(); // Graph
m_pGraph = NULL;
}
if (m_pEvent)
{
m_pEvent->Release(); // 事件接口
m_pEvent = NULL;
}
if (m_pSeek)
{
m_pSeek->Release(); // 数据流定位接口
m_pSeek = NULL;
}
if (m_pMediaControl)
{
m_pMediaControl->Release(); // 播放器接口
m_pMediaControl = NULL;
}
}
void CMediaPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMediaPlayerDlg)
DDX_Control(pDX, IDC_STATIC_TIME, m_labTime);
DDX_Control(pDX, IDC_STATIC_VIDEO, m_wndVideo);
DDX_Control(pDX, IDC_BUTTON_STOP, m_butStop);
DDX_Control(pDX, IDC_BUTTON_SEEK, m_butSeek);
DDX_Control(pDX, IDC_BUTTON_PLAY, m_butPlay);
DDX_Control(pDX, IDC_BUTTON_OPEN, m_butOpen);
DDX_Control(pDX, IDC_BUTTON_FULLSCREEN, m_butFullScreen);
DDX_Control(pDX, IDC_BUTTON_CLOSE, m_butExit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMediaPlayerDlg, CDialog)
//{{AFX_MSG_MAP(CMediaPlayerDlg)
ON_MESSAGE(WM_DSPLAYER,OnDSPlayer)
ON_MESSAGE(WM_DRAWPLAYTIME, OnPlayerTimer)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnButtonClose)
ON_BN_CLICKED(IDC_STATIC_VIDEO, OnStaticVideo)
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
ON_BN_CLICKED(IDC_BUTTON_SEEK, OnButtonSeek)
ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
ON_BN_CLICKED(IDC_BUTTON_FULLSCREEN, OnButtonFullscreen)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMediaPlayerDlg message handlers
BOOL CMediaPlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
MoveWindow(0,0,320,240);
m_butExit.MoveWindow(282,6,25,25);
m_butExit.LoadBitmaps(IDB_MOVE_CLOSE,IDB_MOVE_CLOSED);
m_butOpen.MoveWindow(1,133,46,46);
m_butOpen.LoadBitmaps(IDB_MOVE_OPEN,IDB_MOVE_OPEND);
m_butPlay.MoveWindow(272,41,46,46);
m_butPlay.LoadBitmaps(IDB_MOVE_PLAY,IDB_MOVE_PLAYD,IDB_MOVE_PLAYDIS);
m_butStop.MoveWindow(272,98,46,46);
m_butStop.LoadBitmaps(IDB_MOVE_STOP,IDB_MOVE_STOPD,IDB_MOVE_STOPDIS);
m_butSeek.MoveWindow(272,155,46,46);
m_butSeek.LoadBitmaps(IDB_MOVE_FAST,IDB_MOVE_FASTD,IDB_MOVE_FASTDIS);
m_butFullScreen.MoveWindow(1,56,46,46);
m_butFullScreen.LoadBitmaps(IDB_MOVE_FULLSCREEN,IDB_MOVE_FULLSCREEND,IDB_MOVE_FULLSCREENDIS);
m_wndVideo.MoveWindow(57,40,206,153);
m_wndVideo.BringWindowToTop();
ShowProgress();
//SetTimer(1,1500,NULL);
m_Timer = timeSetEvent(1000,100,(LPTIMECALLBACK)PlayerTimeProc,(DWORD)this,TIME_PERIODIC);
m_labTime.MoveWindow(100,203,120,16);
m_labTime.SetWindowText(L"00:00:00/00:00:00");
return TRUE; // return TRUE unless you set the focus to a control
}
void CMediaPlayerDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
m_MemDC.BitBlt(0,0,320,240,&m_BgDC,0,0,SRCCOPY);
m_MemDC.DrawText(m_TitleText,CRect(90,6,233,31),DT_CENTER|DT_VCENTER);
// ShowProgress();
dc.BitBlt(0,0,320,240,&m_MemDC,0,0,SRCCOPY);
// Do not call CDialog::OnPaint() for painting messages
}
BOOL CMediaPlayerDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
if (!m_InitDC)
{
CBitmap tmpBmp;
tmpBmp.CreateCompatibleBitmap(pDC,320,240);
m_MemDC.CreateCompatibleDC(pDC);
m_MemDC.SelectObject(&tmpBmp);
m_MemDC.SelectObject(&m_txtFont);
m_MemDC.SetBkMode(TRANSPARENT);
m_MemDC.SetTextColor(RGB(255,255,255));
tmpBmp.DeleteObject();
tmpBmp.LoadBitmap(IDB_MUSIC_BAR);
m_BlockDC.CreateCompatibleDC(pDC);
m_BlockDC.SelectObject(&tmpBmp);
tmpBmp.DeleteObject();
tmpBmp.LoadBitmap(IDB_MUSIC_BAR);
m_BlockDCD.CreateCompatibleDC(pDC);
m_BlockDCD.SelectObject(&tmpBmp);
tmpBmp.DeleteObject();
m_InitDC = true;
}
return FALSE;
//return CDialog::OnEraseBkgnd(pDC);
}
void CMediaPlayerDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
ShowProgress();
CDialog::OnTimer(nIDEvent);
}
void PlayerTimeProc(UINT uTimerID,UINT uMsg,DWORD_PTR dwUser,DWORD_PTR dw1,DWORD dw2)
{
CMediaPlayerDlg* pDlg = (CMediaPlayerDlg*)dwUser;
//pDlg->SendMessage(WM_DRAWPLAYTIME,0,0);
PostMessage(pDlg->GetSafeHwnd(),WM_DRAWPLAYTIME,NULL,NULL);
}
void CMediaPlayerDlg::OnDSPlayer()
{
long evCode,param1,param2;
HRESULT hr;
while (hr = m_pEvent->GetEvent(&evCode,&param1,&param2,0),SUCCEEDED(hr))
{
hr = m_pEvent->FreeEventParams(evCode,param1,param2);
switch(evCode)
{
case EC_COMPLETE:
if (m_FullScreen)
{
OnStaticVideo();
}
// 更新按钮图片
m_butPlay.LoadBitmaps(IDB_MOVE_PLAY,IDB_MOVE_PLAYD);
m_butStop.EnableWindow(FALSE);
m_butSeek.EnableWindow(FALSE);
m_butFullScreen.EnableWindow(FALSE);
m_butFullScreen.Invalidate();
m_butSeek.Invalidate();
m_butStop.Invalidate();
m_butPlay.Invalidate();
// 停止播放流
m_pMediaControl->Stop();
// 复位
SetCurrentPosition(0);
m_labTime.SetWindowText(L"00:00:00/00:00:00");
break;
default:
break;
}
}
}
void CMediaPlayerDlg::OnPlayerTimer(WPARAM wParam, LPARAM lParam)
{
if (!m_FullScreen)
{
if (IsPaused() || IsPlaying())
{
int FileTime = GetDuration();
if(FileTime < 0)
{
FileTime = 0;
}
int tolSecond = GetCurrentPosition();
CString str;
if(tolSecond < 0)
{
tolSecond = 0;
}
unsigned char Minute = (int)(tolSecond / 60);
unsigned char Second = tolSecond % 60;
unsigned char Hour = (int)(tolSecond / 3600);
unsigned char fHour = (int)(FileTime / 3600);
unsigned char fMinute = (int)(FileTime / 60);
unsigned char fSec = FileTime % 60;
if (Hour != 0)
{
str.Format(_T("%02d:%02d:%02d/%02d:%02d:%02d"),Hour,Minute,Second,fHour,fMinute,fSec);
}
else
{
str.Format(_T("%02d:%02d/%02d:%02d"),Minute,Second,fMinute,fSec);
}
m_labTime.SetWindowText(str);
}
ShowProgress();
}
}
void CMediaPlayerDlg::CreateGraph()
{
// 建立Graph
CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void **)&m_pGraph);
m_pGraph->RenderFile(m_SourceFile,NULL);
m_pGraph->QueryInterface(IID_IVideoWindow,(void **)&m_pVideo);
m_pVideo->put_Owner((OAHWND)m_wndVideo.GetSafeHwnd());
m_pVideo->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);
m_pVideo->put_MessageDrain((OAHWND)m_wndVideo.GetSafeHwnd());
CRect rect;
m_wndVideo.GetClientRect(&rect);
m_pVideo->put_Left(rect.left);
m_pVideo->put_Top(rect.top);
m_pVideo->put_Height(rect.Height());
m_pVideo->put_Width(rect.Width());
m_pGraph->QueryInterface(IID_IMediaEventEx,(void **)&m_pEvent);
m_pEvent->SetNotifyWindow((OAHWND)(this->GetSafeHwnd()),WM_DSPLAYER,0);
m_pGraph->QueryInterface(IID_IMediaSeeking,(void**)&m_pSeek);
m_pSeek->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
m_pGraph->QueryInterface(IID_IMediaControl,(void **)&m_pMediaControl);
m_InitGraph = true;
}
bool CMediaPlayerDlg::IsPlaying()
{
// 判断当前播放器是否正在播放
if (m_pGraph && m_pMediaControl)
{
OAFilterState statePlay = State_Stopped;
if (SUCCEEDED(m_pMediaControl->GetState(10,&statePlay)))
{
return (statePlay == State_Running);
}
}
return false;
}
bool CMediaPlayerDlg::IsPaused()
{
// 判断当前播放器是否暂停
if (m_pGraph && m_pMediaControl)
{
OAFilterState statePlay = State_Stopped;
if (SUCCEEDED(m_pMediaControl->GetState(10,&statePlay)))
{
return (statePlay == State_Paused);
}
}
return false;
}
bool CMediaPlayerDlg::IsStopped()
{
// 判断当前播放器是否已经停止
if (m_pGraph && m_pMediaControl)
{
OAFilterState statePlay = State_Stopped;
if (SUCCEEDED(m_pMediaControl->GetState(10,&statePlay)))
{
return (statePlay == State_Stopped);
}
}
return false;
}
HRESULT CMediaPlayerDlg::GetPlayerStatus()
{
// 判断当前播放器状态
if (m_pGraph && m_pMediaControl)
{
OAFilterState statePlay = State_Stopped;
if (SUCCEEDED(m_pMediaControl->GetState(10,&statePlay)))
{
return statePlay;
}
}
return -1;
}
int CMediaPlayerDlg::GetDuration()
{
// 获取媒体文件总长度
__int64 lTime = -1;
if (m_pGraph && m_pSeek)
{
m_pSeek->GetDuration(&lTime);
lTime /= 10000000;
}
return (int)lTime;
}
int CMediaPlayerDlg::GetCurrentPosition()
{
// 获取媒体文件总长度
__int64 lTime = -1;
if (m_pGraph && m_pSeek)
{
m_pSeek->GetCurrentPosition(&lTime);
lTime /= 10000000;
}
return (int)lTime;
}
void CMediaPlayerDlg::DisposeGraph()
{
if (m_pMediaControl)
{
m_pMediaControl->Stop();
}
}
bool CMediaPlayerDlg::SetCurrentPosition(int iPosition)
{
// 获取媒体文件总长度
__int64 lTime = 10000000;
__int64 possion = (__int64)(iPosition * lTime);
if (m_pGraph && m_pSeek)
{
HRESULT hr = m_pSeek->SetPositions(&possion,AM_SEEKING_AbsolutePositioning |
AM_SEEKING_SeekToKeyFrame,0,AM_SEEKING_NoPositioning);
return SUCCEEDED(hr);
}
return false;
}
CString CMediaPlayerDlg::GetFileName(CString strFileName)
{
CString FileExt;
FileExt.Empty();
// 文件名长度
int strLen = strFileName.GetLength() - 1;
for(int i = strLen; i >= 0; i--)
{
// 查找文件名中最好一个'.'
if(strFileName.GetAt(i) == '\\')
{
// 提取文件扩展名
FileExt = strFileName.Right(strLen - i);
break;
}
}
strLen = FileExt.GetLength() - 1;
strFileName = FileExt;
for(i = strLen; i >= 0; i--)
{
// 查找文件名中最好一个'.'
if(strFileName.GetAt(i) == '.')
{
// 提取文件扩展名
FileExt = strFileName.Left(i);
break;
}
}
return FileExt;
}
void CMediaPlayerDlg::OnButtonClose()
{
// TODO: Add your control notification handler code here
//SendMessage(WM_CLOSE,0,0);
if (IsPlaying())
{
if (m_pMediaControl)
{
m_pMediaControl->Stop();
}
}
EndDialog(IDOK);
}
void CMediaPlayerDlg::OnStaticVideo()
{
// TODO: Add your control notification handler code here
if (m_FullScreen)
{
m_FullScreen = false;
if (m_pVideo)
{
m_FullScreen = false;
m_wndVideo.MoveWindow(57,40,206,153);
CRect rect;
m_wndVideo.GetClientRect(&rect);
m_pVideo->put_Left(rect.left);
m_pVideo->put_Top(rect.top);
m_pVideo->put_Height(rect.Height());
m_pVideo->put_Width(rect.Width());
}
}
}
void CMediaPlayerDlg::OnButtonPlay()
{
// TODO: Add your control notification handler code here
if (m_SourceFile.IsEmpty())
{
if (m_SourceFile.IsEmpty())
{
OnButtonOpen();
}
}
else
{
if (IsPlaying())
{
if (m_pMediaControl)
{
m_butPlay.LoadBitmaps(IDB_MOVE_PLAY,IDB_MOVE_PLAYD);
m_pMediaControl->Pause();
}
}
else
{
if (m_pMediaControl)
{
m_butPlay.LoadBitmaps(IDB_MOVE_PAUSE,IDB_MOVE_PAUSED);
m_pMediaControl->Run();
}
}
}
//m_labFile.SetWindowText(GetFileName(m_SourceFile));
m_butStop.EnableWindow(TRUE);
m_butSeek.EnableWindow(TRUE);
m_butFullScreen.EnableWindow(TRUE);
m_butPlay.Invalidate();
}
void CMediaPlayerDlg::OnButtonOpen()
{
// TODO: Add your control notification handler code here
if (IsPlaying())
{
m_pMediaControl->Stop();
}
COpenMoveFileDlg fileDlg;
if (fileDlg.DoModal() == IDOK)
{
m_SourceFile = fileDlg.GetFilePath();
m_TitleText = GetFileName(m_SourceFile);
InvalidateRect(CRect(90,6,233,31));
//m_SourceFile = L"\\gsdwr.wmv";
CreateGraph();
OnButtonPlay();
}
}
void CMediaPlayerDlg::OnButtonSeek()
{
// TODO: Add your control notification handler code here
SetCurrentPosition(GetCurrentPosition() + 10);
Sleep(1000);
}
void CMediaPlayerDlg::OnButtonStop()
{
// TODO: Add your control notification handler code here
if (!IsStopped())
{
m_pMediaControl->Stop();
m_butStop.EnableWindow(FALSE);
m_butSeek.EnableWindow(FALSE);
m_butFullScreen.EnableWindow(FALSE);
// 设置播放位置
SetCurrentPosition(0);
m_butPlay.LoadBitmaps(IDB_MOVE_PLAY,IDB_MOVE_PLAYD);
m_butPlay.Invalidate();
}
}
void CMediaPlayerDlg::OnButtonFullscreen()
{
// TODO: Add your control notification handler code here
if (m_pVideo && !m_FullScreen)
{
m_wndVideo.MoveWindow(0,0,320,240);
CRect rect;
m_wndVideo.GetClientRect(&rect);
m_pVideo->put_Left(rect.left);
m_pVideo->put_Top(rect.top);
m_pVideo->put_Height(rect.Height());
m_pVideo->put_Width(rect.Width());
m_FullScreen = true;
}
}
void CMediaPlayerDlg::ShowProgress()
{
// 定义设备绘图指针
CClientDC dc(this);
unsigned int len = 0;
unsigned int volLen = 0;
int startX = 35;
int startY = 219;
int volX = 202;
DWORD lVolume;
if (waveOutGetVolume(0,&lVolume) == MMSYSERR_NOERROR)
{
lVolume &= 0xFFFF;
lVolume = lVolume / 1365;
volLen = lVolume;
if (volX + volLen > 285)
{
volLen = 285 - volX;
}
}
else
{
volLen = 0;
}
if (GetDuration() > 0)
{
if(GetCurrentPosition() >= GetDuration())
{
len = 112;
}
else
{
len = (unsigned int)(112 * GetCurrentPosition()
/ GetDuration());
}
}
CDC tmpDC;
CBitmap tmpBmp;
tmpBmp.CreateCompatibleBitmap(&dc,320,240);
tmpDC.CreateCompatibleDC(&dc);
tmpDC.SelectObject(&tmpBmp);
tmpDC.BitBlt(0,0,320,240,&m_MemDC,0,0,SRCCOPY);
TransparentImage(tmpDC.m_hDC,startX + len,startY,18,17,
m_BlockDC.m_hDC,0,0,18,17,RGB(255,0,0));
TransparentImage(tmpDC.m_hDC,volX + volLen,startY,18,17,
m_BlockDCD.m_hDC,0,0,18,17,RGB(255,0,0));
dc.BitBlt(0,0,320,240,&tmpDC,0,0,SRCCOPY);
tmpDC.DeleteDC();
tmpBmp.DeleteObject();
}
void CMediaPlayerDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (point.x >= 35 && point.y >= 219 && point.x <= 164 && point.y <= 235)
{
if (!IsStopped() && m_pSeek)
{
int iCurrent = point.x * GetDuration() / 164;
if (iCurrent > 0)
{
if (SetCurrentPosition(iCurrent))
{
ShowProgress();
}
}
}
}
if (point.x >= 202 && point.y >= 219 && point.x <= 285 && point.y <= 235)
{
int iCurrent = 65 / (point.x - 202);
if (iCurrent > 0)
{
DWORD volume = ((0xFFFF/iCurrent) << 16);
volume &= 0xFFFF0000;
volume |= 0xFFFF/iCurrent;
waveOutSetVolume(0,volume);
}
}
CDialog::OnLButtonDown(nFlags, point);
}