📄 playerwindow.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
///////////////////////////////////////////////////////////////////////////////
// File: PlayerWindow.cpp
//
// Desc: This file contains the implementation of the PlayerWindow class,
// which combines the MediaPlayer container and Event Sink class into
// one class to facilitate event handling.
//
///////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>
#include <shellapi.h>
#include "PlayerWindow.h"
#define _COMCTL32_
#include <commctrl.h>
#undef _COMCTL32_
#include <commdlg.h>
#include <uuids.h>
#include <strsafe.h>
#include "PropertyDlg.h"
#include "resource.h"
#include "StatisticsDlg.h"
#include "OpenURLDlg.h"
#include "OptionsDlg.h"
#include "PlaylistDlg.h"
#include "CEPlayerUtil.h"
#include "PlaylistMgr.h"
#include "decibels.h"
#define HIMETRIC_PER_INCH 2540
#define MAP_LOGHIM_TO_PIX(x, ppli) ((ppli) * (x) / HIMETRIC_PER_INCH)
#define MINIMUM_PLAYER_WIDTH 239
#define MINIMUM_PLAYER_HEIGHT 88
#define SKIN_HEIGHT 40
#define SKIN_WIDTH 210
#define SKIN_MARGIN 10
#define TRACKER_ID 123
#define TRACKER_TIMEOUT 750
#define MENU_ICON_WIDTH 16
#define MENU_ITEM_HEIGHT 20
#define MENU_ITEM_HORZ_MARGIN 2
#define MAX_MENU_ITEM_WIDTH 200
static const int FILTER_SIZE = 300;
static const int REGKEY_SIZE = 80;
extern TCHAR **g_ppszAudioTypes;
extern TCHAR **g_ppszVideoTypes;
extern TCHAR **g_ppszPlaylistTypes;
extern TCHAR *g_szHomePage;
extern DWORD g_cAudioTypes;
extern DWORD g_cVideoTypes;
extern DWORD g_cPlaylistTypes;
extern bool g_bSmallScreen;
extern bool g_bFullscreenToWindowedOnPause;
static const int ratesArray[] = { -600, -60, -30, -15, -4, -2, -1, 1, 2, 4, 15, 30, 60, 600 };
CPlayerWindow::CPlayerWindow(HWND hWnd, HINSTANCE hInstance) :
m_uiStatTimer(0),
m_uiTrackerTimer(0),
m_hInstance(hInstance),
m_hWnd(hWnd),
m_hWndCB(NULL),
m_hWndProp(NULL),
m_hWndStat(NULL),
m_hWndPlay(NULL),
m_eState(EState::BAD),
m_szFilename(NULL),
m_szPath(NULL),
m_szFilter(NULL),
m_bPlayForever(FALSE),
m_bShuffle(FALSE),
m_dwZoomLevel(1),
m_dwMinimumWidth(MINIMUM_PLAYER_WIDTH),
m_dwMinimumHeight(MINIMUM_PLAYER_HEIGHT),
m_nFilterIndex(1),
m_pPlaylist(NULL),
m_himgLocationList(NULL),
m_bSwitchingPlaylists(false),
m_hbmBuffer(NULL),
m_iSkinMargin(0),
m_fResumeOpen( FALSE ),
m_bStop( FALSE )
{
int i;
// Intialize the properties structure to invalid properties
m_stats.dFrameRate = 0.0;
m_stats.dActualRate = 0.0;
m_stats.lFramesDropped = 0;
m_stats.lBandwidth = 0;
m_stats.lSourceProtocol = 0;
m_stats.lReceivedPackets = 0;
m_stats.lRecoveredPackets = 0;
m_stats.lLostPackets = 0;
m_stats.lDroppedAudioPackets = 0;
m_stats.szErrorCorrection = NULL;
m_stats.szFilename = NULL;
m_currentRate = sizeof( ratesArray ) / sizeof( ratesArray[0] ) / 2;
InitializeCriticalSection( &m_csButtonInfoCritSec );
m_himgLocationList = ImageList_LoadBitmap(g_hInst,
MAKEINTRESOURCE(IDB_LOCATIONLIST),
MENU_ICON_WIDTH,
1,
CLR_DEFAULT);
for( i = 0; i < MAX_FILEOPEN_HISTORY; i++ )
{
m_szFilenameHistory[i] = NULL;
}
SetState(BAD);
CMPContainer::AddRef();
CMPEventSink::AddRef();
}
CPlayerWindow::~CPlayerWindow()
{
// Incase someone forgot to call this method, we'll do it now
Fini();
// don't call Release for CMPContainer and CMPEventSink, because we don't
// want their ref count going to zero...
if (NULL != m_himgLocationList)
{
ImageList_Destroy(m_himgLocationList);
}
}
///////////////////////////////////////////////////////////////////////////////
// Name: CPlayerWindow::Init()
// Desc: This function is used to initialize the PlayerWindow class.
// It creates the Media Player control, and hooks up the Event sink.
///////////////////////////////////////////////////////////////////////////////
bool CPlayerWindow::Init()
{
IConnectionPointContainer *pCPC = NULL;
IConnectionPoint *pCP = NULL;
//
// Load skin bitmaps
//
#ifdef CEPLAYER_SKIN
BITMAP bm;
m_binfo[SKIN_PREV].eState = DISABLED;
m_binfo[SKIN_PREV].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PREV_UP));
m_binfo[SKIN_PREV].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PREV_DOWN));
m_binfo[SKIN_PREV].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PREV_DISABLED));
m_binfo[SKIN_PREV].ptPos.x = 49;
m_binfo[SKIN_PREV].ptPos.y = 18;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_PREV].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_PREV].ptDim.x = bm.bmWidth;
m_binfo[SKIN_PREV].ptDim.y = bm.bmHeight;
m_binfo[SKIN_FR].eState = DISABLED;
m_binfo[SKIN_FR].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_FR_UP));
m_binfo[SKIN_FR].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_FR_DOWN));
m_binfo[SKIN_FR].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_FR_DISABLED));
m_binfo[SKIN_FR].ptPos.x = 71;
m_binfo[SKIN_FR].ptPos.y = 18;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_FR].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_FR].ptDim.x = bm.bmWidth;
m_binfo[SKIN_FR].ptDim.y = bm.bmHeight;
m_binfo[SKIN_FF].eState = DISABLED;
m_binfo[SKIN_FF].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_FF_UP));
m_binfo[SKIN_FF].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_FF_DOWN));
m_binfo[SKIN_FF].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_FF_DISABLED));
m_binfo[SKIN_FF].ptPos.x = 93;
m_binfo[SKIN_FF].ptPos.y = 18;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_FF].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_FF].ptDim.x = bm.bmWidth;
m_binfo[SKIN_FF].ptDim.y = bm.bmHeight;
m_binfo[SKIN_NEXT].eState = DISABLED;
m_binfo[SKIN_NEXT].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_NEXT_UP));
m_binfo[SKIN_NEXT].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_NEXT_DOWN));
m_binfo[SKIN_NEXT].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_NEXT_DISABLED));
m_binfo[SKIN_NEXT].ptPos.x = 115;
m_binfo[SKIN_NEXT].ptPos.y = 18;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_NEXT].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_NEXT].ptDim.x = bm.bmWidth;
m_binfo[SKIN_NEXT].ptDim.y = bm.bmHeight;
m_binfo[SKIN_SOUND].eState = UP;
m_binfo[SKIN_SOUND].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SOUND_UP));
m_binfo[SKIN_SOUND].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SOUND_DOWN));
m_binfo[SKIN_SOUND].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SOUND_DISABLED));
m_binfo[SKIN_SOUND].ptPos.x = 137;
m_binfo[SKIN_SOUND].ptPos.y = 18;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_SOUND].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_SOUND].ptDim.x = bm.bmWidth;
m_binfo[SKIN_SOUND].ptDim.y = bm.bmHeight;
m_binfo[SKIN_STOP].eState = DISABLED;
m_binfo[SKIN_STOP].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_STOP_UP));
m_binfo[SKIN_STOP].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_STOP_DOWN));
m_binfo[SKIN_STOP].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_STOP_DISABLED));
m_binfo[SKIN_STOP].ptPos.x = 30;
m_binfo[SKIN_STOP].ptPos.y = 6;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_STOP].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_STOP].ptDim.x = bm.bmWidth;
m_binfo[SKIN_STOP].ptDim.y = bm.bmHeight;
m_binfo[SKIN_PLAY].eState = DISABLED;
m_binfo[SKIN_PLAY].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PLAY_UP));
m_binfo[SKIN_PLAY].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PLAY_DOWN));
m_binfo[SKIN_PLAY].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PLAY_DISABLED));
m_binfo[SKIN_PLAY].ptPos.x = 0;
m_binfo[SKIN_PLAY].ptPos.y = 0;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_PLAY].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_PLAY].ptDim.x = bm.bmWidth;
m_binfo[SKIN_PLAY].ptDim.y = bm.bmHeight;
m_binfo[SKIN_PAUSE].eState = UP;
m_binfo[SKIN_PAUSE].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PAUSE_UP));
m_binfo[SKIN_PAUSE].hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PAUSE_DOWN));
m_binfo[SKIN_PAUSE].hDisabled = NULL;
m_binfo[SKIN_PAUSE].ptPos.x = 0;
m_binfo[SKIN_PAUSE].ptPos.y = 0;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_PAUSE].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_PAUSE].ptDim.x = bm.bmWidth;
m_binfo[SKIN_PAUSE].ptDim.y = bm.bmHeight;
m_binfo[SKIN_VOLUME].eState = UP;
m_binfo[SKIN_VOLUME].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_VOLUME_FOREGROUND));
m_binfo[SKIN_VOLUME].hDown = NULL;
m_binfo[SKIN_VOLUME].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_VOLUME_BACKGROUND));
m_binfo[SKIN_VOLUME].ptPos.x = 159;
m_binfo[SKIN_VOLUME].ptPos.y = 19;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_VOLUME].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_VOLUME].ptDim.x = bm.bmWidth;
m_binfo[SKIN_VOLUME].ptDim.y = bm.bmHeight;
m_binfo[SKIN_SEEK].eState = DISABLED;
m_binfo[SKIN_SEEK].hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SEEK_FOREGROUND));
m_binfo[SKIN_SEEK].hDown = NULL;
m_binfo[SKIN_SEEK].hDisabled = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SEEK_BACKGROUND));
m_binfo[SKIN_SEEK].ptPos.x = 49;
m_binfo[SKIN_SEEK].ptPos.y = 0;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfo[SKIN_SEEK].hUp, sizeof (BITMAP), &bm);
m_binfo[SKIN_SEEK].ptDim.x = bm.bmWidth;
m_binfo[SKIN_SEEK].ptDim.y = bm.bmHeight;
m_binfoVolThumb.eState = UP;
m_binfoVolThumb.hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_THUMB_UP));
m_binfoVolThumb.hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_THUMB_DOWN));
m_binfoVolThumb.hDisabled = NULL;
m_binfoVolThumb.ptPos.x = 159;
m_binfoVolThumb.ptPos.y = 19;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfoVolThumb.hUp, sizeof (BITMAP), &bm);
m_binfoVolThumb.ptDim.x = bm.bmWidth;
m_binfoVolThumb.ptDim.y = bm.bmHeight;
m_binfoSeekThumb.eState = UP;
m_binfoSeekThumb.hUp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_THUMB_UP));
m_binfoSeekThumb.hDown = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_THUMB_DOWN));
m_binfoSeekThumb.hDisabled = NULL;
m_binfoSeekThumb.ptPos.x = 49;
m_binfoSeekThumb.ptPos.y = 0;
memset(&bm, 0, sizeof (BITMAP));
GetObject(m_binfoSeekThumb.hUp, sizeof (BITMAP), &bm);
m_binfoSeekThumb.ptDim.x = bm.bmWidth;
m_binfoSeekThumb.ptDim.y = bm.bmHeight;
memset(&m_rcVolBounds, 0, sizeof (m_rcVolBounds));
memset(&m_rcSeekBounds, 0, sizeof (m_rcSeekBounds));
m_rcVolBounds.left = m_binfo[SKIN_VOLUME].ptPos.x;
m_rcVolBounds.right = m_binfo[SKIN_VOLUME].ptPos.x + m_binfo[SKIN_VOLUME].ptDim.x - m_binfoVolThumb.ptDim.x;
m_rcSeekBounds.left = m_binfo[SKIN_SEEK].ptPos.x;
m_rcSeekBounds.right = m_binfo[SKIN_SEEK].ptPos.x + m_binfo[SKIN_SEEK].ptDim.x - m_binfoSeekThumb.ptDim.x;
m_bPlayPause = true;
#endif /* CEPLAYER_SKIN */
SetState(BAD);
if (NULL != m_szFilter)
{
delete[] m_szFilter;
m_szFilter = NULL;
}
// Figure out how big this string will be.
int iTotalSize = 0;
int iStrLen = 0;
DWORD i;
iTotalSize += _tcslen(TEXT("All Media Files")) + 1;
for (i = 0; i < g_cAudioTypes; i++)
{
iTotalSize += _tcslen(g_ppszAudioTypes[i]) + 2;
}
for (i = 0; i < g_cVideoTypes; i++)
{
iTotalSize += _tcslen(g_ppszVideoTypes[i]) + 2;
}
for (i = 0; i < g_cPlaylistTypes; i++)
{
iTotalSize += _tcslen(g_ppszPlaylistTypes[i]) + 2;
}
iTotalSize++;
iTotalSize += _tcslen(TEXT("Video Files")) + 1;
for (i = 0; i < g_cVideoTypes; i++)
{
iTotalSize += _tcslen(g_ppszVideoTypes[i]) + 2;
}
iTotalSize++;
iTotalSize += _tcslen(TEXT("Playlists")) + 1;
for (i = 0; i < g_cPlaylistTypes; i++)
{
iTotalSize += _tcslen(g_ppszPlaylistTypes[i]) + 2;
}
iTotalSize++;
iTotalSize += _tcslen(TEXT("Audio Files")) + 1;
for (i = 0; i < g_cAudioTypes; i++)
{
iTotalSize += _tcslen(g_ppszAudioTypes[i]) + 2;
}
iTotalSize++;
iTotalSize += _tcslen(TEXT("All Files")) + 1;
iTotalSize += _tcslen(TEXT("*.*")) + 2;
// Allocate the filter string
m_szFilter = new TCHAR[iTotalSize + 1];
// Build the filter string.
if( !m_szFilter )
{
return false;
}
_tcscpy(m_szFilter, TEXT("All Media Files"));
iStrLen = _tcslen(m_szFilter);
iStrLen++;
for (i = 0; i < g_cAudioTypes; i++)
{
_stprintf(m_szFilter + iStrLen, TEXT("*%s;"), g_ppszAudioTypes[i]);
iStrLen += _tcslen(g_ppszAudioTypes[i]) + 2;
}
for (i = 0; i < g_cVideoTypes; i++)
{
_stprintf(m_szFilter + iStrLen, TEXT("*%s;"), g_ppszVideoTypes[i]);
iStrLen += _tcslen(g_ppszVideoTypes[i]) + 2;
}
for (i = 0; i < g_cPlaylistTypes; i++)
{
_stprintf(m_szFilter + iStrLen, TEXT("*%s;"), g_ppszPlaylistTypes[i]);
iStrLen += _tcslen(g_ppszPlaylistTypes[i]) + 2;
}
iStrLen++;
_tcscpy(m_szFilter + iStrLen, TEXT("Video Files"));
iStrLen += _tcslen(TEXT("Video Files"));
iStrLen++;
for (i = 0; i < g_cVideoTypes; i++)
{
_stprintf(m_szFilter + iStrLen, TEXT("*%s;"), g_ppszVideoTypes[i]);
iStrLen += _tcslen(g_ppszVideoTypes[i]) + 2;
}
iStrLen++;
_tcscpy(m_szFilter + iStrLen, TEXT("Playlists"));
iStrLen += _tcslen(TEXT("Playlists"));
iStrLen++;
for (i = 0; i < g_cPlaylistTypes; i++)
{
_stprintf(m_szFilter + iStrLen, TEXT("*%s;"), g_ppszPlaylistTypes[i]);
iStrLen += _tcslen(g_ppszPlaylistTypes[i]) + 2;
}
iStrLen++;
_tcscpy(m_szFilter + iStrLen, TEXT("Audio Files"));
iStrLen += _tcslen(TEXT("Audio Files"));
iStrLen++;
for (i = 0; i < g_cAudioTypes; i++)
{
_stprintf(m_szFilter + iStrLen, TEXT("*%s;"), g_ppszAudioTypes[i]);
iStrLen += _tcslen(g_ppszAudioTypes[i]) + 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -