📄 yogaplaydlg.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
// YogaPlayDlg.cpp
//
// Yoga MPEG Audio Player
//
// 09/11/1999 fOSSiL Initial version
//
#include "stdafx.h"
#include "YogaPlay.h"
#include "YogaPlayDlg.h"
#include "playw32.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStereoDisplay
CStereoDisplay::CStereoDisplay()
{
HDC hDC = ::GetDC(NULL);
LOGFONT logFont;
memset(&logFont, 0, sizeof(LOGFONT));
logFont.lfCharSet = DEFAULT_CHARSET;
lstrcpyn(logFont.lfFaceName, "MS Sans Serif", sizeof(logFont.lfFaceName));
POINT pt;
pt.y = GetDeviceCaps(hDC, LOGPIXELSY) * 180;
pt.y /= 720; // 72 points/inch, 10 decipoints/point
DPtoLP(hDC, &pt, 1);
POINT ptOrg = {0, 0};
DPtoLP(hDC, &ptOrg, 1);
logFont.lfHeight = -abs(pt.y - ptOrg.y);
Font.Attach(CreateFontIndirect(&logFont));
::ReleaseDC(NULL, hDC);
}
CStereoDisplay::~CStereoDisplay()
{
Font.DeleteObject();
}
BEGIN_MESSAGE_MAP(CStereoDisplay, CStatic)
//{{AFX_MSG_MAP(CStereoDisplay)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStereoDisplay message handlers
void CStereoDisplay::OnPaint()
{
// Do not call CStatic::OnPaint() for painting messages
CPaintDC dc(this); // device context for painting
Redraw(&dc);
}
BOOL CStereoDisplay::OnEraseBkgnd(CDC* pDC)
{
RECT WinRect;
GetClientRect(&WinRect);
return FillRect(pDC->m_hDC, &WinRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
}
void CStereoDisplay::SetText(LPCTSTR Text)
{
sText = Text;
Redraw();
}
void CStereoDisplay::Redraw(CDC* pDC)
{
BOOL bCustDC = FALSE;
if (pDC == NULL) {
bCustDC = TRUE;
pDC = GetDC();
}
pDC->SaveDC();
CRect WinRect;
GetClientRect(&WinRect);
pDC->SetTextColor(0x00E000);
pDC->SetBkColor(0);
pDC->SetTextAlign(TA_CENTER | TA_BASELINE);
// select our font
pDC->SelectObject(&Font);
pDC->ExtTextOut(WinRect.Width() / 2, WinRect.Height() / 2 + 4, ETO_OPAQUE, WinRect, sText, NULL);
pDC->RestoreDC(-1);
if (bCustDC)
ReleaseDC(pDC);
}
/////////////////////////////////////////////////////////////////////////////
// CYogaPlayDlg dialog
void CYogaPlayDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CYogaPlayDlg)
DDX_Control(pDX, IDC_VOLUME, Volume);
DDX_Control(pDX, IDC_SONGPOS, SongPos);
DDX_Control(pDX, IDC_EJECT, btnEject);
DDX_Control(pDX, IDC_RW, btnRewind);
DDX_Control(pDX, IDC_FFW, btnFastFwd);
DDX_Control(pDX, IDC_PAUSE, btnPause);
DDX_Control(pDX, IDC_STOP, btnStop);
DDX_Control(pDX, IDC_PLAY, btnPlay);
DDX_Control(pDX, IDC_DISPLAY, Display);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CYogaPlayDlg, CDialog)
//{{AFX_MSG_MAP(CYogaPlayDlg)
ON_COMMAND(ID_HELP_ABOUT, OnHelpAbout)
ON_COMMAND(IDHELP, OnHelp)
ON_COMMAND(ID_OPTIONS_REMAIN, OnTrackTimeWay)
ON_COMMAND(ID_OPTIONS_CONTPLAY, OnContPlay)
ON_COMMAND(ID_FILE_PLAYMPX, OnFileOpen)
ON_COMMAND(ID_COMMANDS_EJECT, OnEject)
ON_COMMAND(ID_COMMANDS_STOP, OnStop)
ON_COMMAND(ID_COMMANDS_PAUSE, OnPause)
ON_COMMAND(ID_COMMANDS_PLAY, OnPlay)
ON_COMMAND(ID_COMMANDS_RW, OnSkipBackward)
ON_COMMAND(ID_COMMANDS_FFW, OnSkipForward)
ON_WM_KEYDOWN()
ON_WM_HELPINFO()
ON_WM_SYSCOMMAND()
ON_WM_TIMER()
ON_WM_HSCROLL()
ON_WM_ACTIVATE()
ON_BN_CLICKED(IDC_EJECT, OnEject)
ON_BN_CLICKED(IDC_STOP, OnStop)
ON_BN_CLICKED(IDC_PAUSE, OnPause)
ON_BN_CLICKED(IDC_PLAY, OnPlay)
ON_BN_CLICKED(IDC_FFW, OnSkipForward)
ON_BN_CLICKED(IDC_RW, OnSkipBackward)
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CYogaPlayDlg::CYogaPlayDlg(CWnd* pParent /*=NULL*/)
: CDialog(CYogaPlayDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CYogaPlayDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
bTimeFwd = TRUE;
bContPlay = FALSE;
bPaused = FALSE;
bPlaying = FALSE;
bUpdatePos = TRUE;
bPlayerBusy = FALSE;
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_hAccel = LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINACCEL));
Menu.LoadMenu(IDR_MAINMENU);
BtnImages.Create(IDB_BUTTONS, 16, 1, 0x808000);
}
UINT DlgBtnIDs[] = {IDC_PLAY, IDC_PAUSE, IDC_STOP, IDC_RW, IDC_FFW, IDC_EJECT, 0};
UINT DlgBtnIcons[] = {0, 1, 2, 3, 6, 7};
MPEGPLAYLIST* pList = (MPEGPLAYLIST*) new long(0);
UINT ListSize = 0;
UINT nCurFile = (DWORD)-1;
MPEGSTREAMINFO Info;
HMIXEROBJ hMixer = NULL;
DWORD MixerLine = 0;
MIXERCONTROL VolCtrl;
int InitMixer()
{
if (mixerGetNumDevs() < 1 || MMSYSERR_NOERROR != mixerOpen((HMIXER*)&hMixer, 0, NULL, 0, MIXER_OBJECTF_MIXER))
return FALSE;
MIXERLINE ml;
ml.cbStruct = sizeof(ml);
ml.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
if (MMSYSERR_NOERROR != mixerGetLineInfo(hMixer, &ml, MIXER_GETLINEINFOF_COMPONENTTYPE)) {
mixerClose((HMIXER)hMixer);
hMixer = NULL;
return FALSE;
}
MixerLine = ml.dwLineID;
MIXERLINECONTROLS mlcs;
mlcs.cbStruct = sizeof(mlcs);
mlcs.dwLineID = ml.dwLineID;
mlcs.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mlcs.cbmxctrl = sizeof(MIXERCONTROL);
mlcs.pamxctrl = &VolCtrl;
if (MMSYSERR_NOERROR != mixerGetLineControls(hMixer, &mlcs, MIXER_GETLINECONTROLSF_ONEBYTYPE)) {
mixerClose((HMIXER)hMixer);
hMixer = NULL;
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CYogaPlayDlg message handlers
BOOL CYogaPlayDlg::OnInitDialog()
{
CDialog::OnInitDialog();
if (!MpegOpenDevice()) {
AfxMessageBox("MPEG Device did not initialize", MB_OK | MB_ICONSTOP);
// EndDialog(1);
}
// 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 both icons
SetMenu(&Menu);
SetTimer(1, 500, NULL);
for (int i = 0; DlgBtnIDs[i] != 0; i++)
GetDlgItem(DlgBtnIDs[i])->SendMessage(BM_SETIMAGE, IMAGE_ICON, (LPARAM)BtnImages.ExtractIcon(DlgBtnIcons[i]));
// init song position slider
SongPos.SetRangeMin(0);
SongPos.SetRangeMax(1000000);
SongPos.SetPageSize(1000000/10);
SongPos.SetLineSize(1000000/200);
// init volume control
if (InitMixer()) {
Volume.SetRangeMin(VolCtrl.Bounds.dwMinimum);
Volume.SetRangeMax(VolCtrl.Bounds.dwMaximum);
int Range = VolCtrl.Bounds.dwMaximum - VolCtrl.Bounds.dwMinimum;
Volume.SetPageSize(Range/10);
Volume.SetLineSize(Range/200);
RefreshVolume();
} else {
Volume.EnableWindow(FALSE);
}
RefreshDisplay();
return TRUE; // return TRUE unless you set the focus to a control
}
void CYogaPlayDlg::OnHelpAbout()
{
CAboutDlg Dlg;
Dlg.DoModal();
}
void CYogaPlayDlg::OnTrackTimeWay()
{
bTimeFwd = !bTimeFwd;
Menu.CheckMenuItem(ID_OPTIONS_REMAIN, bTimeFwd ? MF_UNCHECKED : MF_CHECKED);
}
void CYogaPlayDlg::OnFileOpen()
{
if (AskFiles()) {
OnStop();
MpegSetPlayList(pList, ListSize);
OnPlay();
}
}
int CYogaPlayDlg::AskFiles()
{
CHAR Files[4096] = "";
OPENFILENAME ofn;
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hWnd;
// add "Playlists (*.m3u;*.pls)\0*.m3u;*.pls\0" when playlist support is coded
ofn.lpstrFilter = "MPEG Audio (*.mp3;*.mp2)\0*.mp2;*.mp3\0All Files (*.*)\0*.*\0\0";
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -