jPlayer : plays .mp3 files in a directory (or more)

Download jplayer.zip

Synopsis:

jplayer.cfg
AboutHandler.cpp
AboutHandler.h
CAboutDlg.cpp
CAboutDlg.h
ExtensibleContainer.h
FileFinder.cpp
FileFinder.h
jPlayer.cpp
jPlayer.h
jPlayer.rc
jPlayerDlg.cpp
jPlayerDlg.h
MciWrapper.cpp
MciWrapper.h
PersistedList.cpp
PersistedList.h
Player.cpp
Player.h
Playlist.cpp
Playlist.h
resource.h
Util.cpp
Util.h


jplayer.cfg

Synopsis
e:\mystuff\mymusic

AboutHandler.cpp

Synopsis
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions

#include "CAboutDlg.h"
#include "AboutHandler.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void AboutHandler::AddAboutMenu(CMenu* pSysMenu)
  {
  if (pSysMenu == NULL) return;

  // IDM_ABOUTBOX must be in the system command range.
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX < 0xF000);

  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
    {
    pSysMenu->AppendMenu(MF_SEPARATOR);
    pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
  }
bool AboutHandler::IsAboutBox(UINT nID)
  {
  return (nID & 0xFFF0) == IDM_ABOUTBOX;
  }
void AboutHandler::Show()
  {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
  }

AboutHandler.h

Synopsis
#pragma once

class AboutHandler
  {
  public:
    static void AddAboutMenu(CMenu* pSysMenu);
    static bool IsAboutBox(UINT nID);
    static void Show();
  };

CAboutDlg.cpp

Synopsis
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include "CAboutDlg.h"

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()

CAboutDlg.h

Synopsis
#pragma once
#include "resource.h"

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()
  };

ExtensibleContainer.h

Synopsis
#pragma once

class ExtensibleContainer
  {
  public:
    virtual void AddString(const char* item) = 0;
  } ;

FileFinder.cpp

Synopsis
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "filefinder.h"

static DWORD cFileAttribute = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE;
static DWORD cDirAttribute =  FILE_ATTRIBUTE_DIRECTORY;

bool FileFinder::first(const string& path)
  {
  string fspec = path + "\\*.*";
  h = ::FindFirstFile(fspec.c_str(), &fdata);
  return h != INVALID_HANDLE_VALUE;
  }
bool FileFinder::next()
  {
  return ::FindNextFile(h, &fdata) == TRUE;
  }
string FileFinder::getName()
  {
  return fdata.cFileName;
  }
bool FileFinder::isDotFiles()
  {
  return getName() == "." || getName() == "..";
  }
void FileFinder::close()
  {
  ::FindClose(h);
  }
bool FileFinder::isDir()
  {
  return (fdata.dwFileAttributes & cDirAttribute) != 0;
  }
bool FileFinder::isFile()
  {
  return (fdata.dwFileAttributes & cFileAttribute) != 0;
  }


FileFinder.h

Synopsis
#pragma once

#include <string>
using std::string;

class FileFinder
  {
  public:
    bool first(const string& path);
    bool next();
    string getName();
    bool isDotFiles();
    void close();
    bool isDir();
    bool isFile();
  private:
    WIN32_FIND_DATA fdata;
    HANDLE h;
  } ;

jPlayer.cpp

Synopsis
#pragma warning(disable: 4786)
#include "jPlayer.h"
#include "jPlayerDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CJPlayerApp theApp;

BEGIN_MESSAGE_MAP(CJPlayerApp, CWinApp)
  //{{AFX_MSG_MAP(CJPlayerApp)
  // NOTE - the ClassWizard will add and remove mapping macros here.
  //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG
  ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

CJPlayerApp::CJPlayerApp()
  {
  }

BOOL CJPlayerApp::InitInstance()
  {
  CJPlayerDlg dlg;
  m_pMainWnd = &dlg;
  int nResponse = dlg.DoModal();
  return FALSE;
  }

jPlayer.h

Synopsis
// jPlayer.h : main header file for the jPLAYER application
//

#pragma once
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include "resource.h"		// main symbols

/////////////////////////////////////////////////////////////////////////////
// CJPlayerApp:
// See jPlayer.cpp for the implementation of this class
//
class CJPlayerApp : public CWinApp
  {
  public:
    CJPlayerApp();

    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CJPlayerApp)
  public:
    virtual BOOL InitInstance();
    //}}AFX_VIRTUAL

    // Implementation

    //{{AFX_MSG(CJPlayerApp)
    // NOTE - the ClassWizard will add and remove member functions here.
    //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
  };


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

jPlayer.rc

Synopsis
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
    "#ifdef _WIN32\r\n"
    "LANGUAGE 9, 1\r\n"
    "#pragma code_page(1252)\r\n"
    "#endif //_WIN32\r\n"
    "#include ""jPlayer.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
    "#include ""afxres.rc""         // Standard components\r\n"
    "#endif\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME           ICON                    "jPlayer.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOG  0, 0, 235, 55
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About jPlayer"
FONT 8, "MS Sans Serif"
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,11,17,20,20
    LTEXT           "jPlayer Version 1.0",IDC_STATIC,40,10,119,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2003",IDC_STATIC,40,25,119,8
    DEFPUSHBUTTON   "OK",IDOK,178,7,50,14,WS_GROUP
END

IDD_JPLAYER_DIALOG DIALOGEX 0, 0, 374, 233
STYLE DS_SETFONT | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
    WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_STATICEDGE | WS_EX_APPWINDOW
CAPTION "MP3 Player with jPlayer"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
    PUSHBUTTON      "Play",IDC_PLAY,7,42,50,14
    PUSHBUTTON      "Stop",IDC_STOP,7,56,50,14
    PUSHBUTTON      "Pause",IDC_PAUSE,7,70,50,14
    PUSHBUTTON      "E&xit",IDCANCEL,7,167,50,14
    PUSHBUTTON      "Browse ...",IDC_BROWSE,7,98,50,14
    PUSHBUTTON      "Next",IDC_NEXT,7,84,50,14
    PUSHBUTTON      "Sort",IDC_SORT,7,126,50,14
    PUSHBUTTON      "Randomize",IDC_RANDOMIZE,7,112,50,14
    LISTBOX         IDC_FILELIST,61,43,306,162,LBS_NOINTEGRALHEIGHT | 
                    WS_VSCROLL | WS_TABSTOP
    LTEXT           "Static",IDC_CURRENT,7,26,360,14,SS_SUNKEN
END


/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904B0"
        BEGIN
            VALUE "FileDescription", "jPlayer MFC Application"
            VALUE "FileVersion", "1, 0, 0, 1"
            VALUE "InternalName", "jPlayer"
            VALUE "LegalCopyright", "Copyright (C) 2003"
            VALUE "OriginalFilename", "jPlayer.EXE"
            VALUE "ProductName", "jPlayer Application"
            VALUE "ProductVersion", "1, 0, 0, 1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 228
        TOPMARGIN, 7
        BOTTOMMARGIN, 48
    END

    IDD_JPLAYER_DIALOG, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 367
        TOPMARGIN, 7
        BOTTOMMARGIN, 226
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE 
BEGIN
    IDS_ABOUTBOX            "&About jPlayer..."
END

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "afxres.rc"         // Standard components
#endif

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED


jPlayerDlg.cpp

Synopsis
#pragma warning(disable: 4786)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <mmsystem.h> //required for MM_MCINOTIFY

#include "resource.h"
#include "jPlayerDlg.h"
#include "AboutHandler.h"
#include "Player.h"
#include "PersistedList.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CJPlayerDlg dialog

CJPlayerDlg::CJPlayerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CJPlayerDlg::IDD, pParent)
  {
  mIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  }
CJPlayerDlg::~CJPlayerDlg()
  {
  }

void CJPlayerDlg::DoDataExchange(CDataExchange* pDX)
  {
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CJPlayerDlg)
  DDX_Control(pDX, IDC_PLAY, mPlay);
  DDX_Control(pDX, IDC_STOP, mStop);
  DDX_Control(pDX, IDC_PAUSE, mPause);
  DDX_Control(pDX, IDC_CURRENT, mCurrent);
  DDX_Control(pDX, IDC_FILELIST, mPlaylist);
  //}}AFX_DATA_MAP
  }

BEGIN_MESSAGE_MAP(CJPlayerDlg, CDialog)
  //{{AFX_MSG_MAP(CJPlayerDlg)
  ON_WM_SYSCOMMAND()
  ON_WM_PAINT()
  ON_WM_QUERYDRAGICON()
  ON_BN_CLICKED(IDC_PLAY, OnPlay)
  ON_BN_CLICKED(IDC_SORT, OnSort)
  ON_BN_CLICKED(IDC_NEXT, OnNext)
  ON_BN_CLICKED(IDC_PAUSE, OnPause)
  ON_BN_CLICKED(IDC_STOP, OnStop)
  ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  ON_BN_CLICKED(IDC_RANDOMIZE, OnRandomize)
  ON_LBN_SELCHANGE(IDC_FILELIST, OnSelChange)
  ON_WM_SIZE()
  //}}AFX_MSG_MAP

  // { MM_MCINOTIFY, 0, 0, 0, AfxSig_v_u_u, 	(AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > (OnMMNotify)) },
  { MM_MCINOTIFY, 0, 0, 0, AfxSig_lwl, 	(AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > (OnMMNotify)) },

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CJPlayerDlg message handlers

BOOL CJPlayerDlg::OnInitDialog()
  {
  CDialog::OnInitDialog();
  AboutHandler::AddAboutMenu(GetSystemMenu(FALSE));

  // Set the icon for this dialog.  The framework does this automatically
  //  when the application's main window is not a dialog
  SetIcon(mIcon, TRUE);			// Set big icon
  SetIcon(mIcon, FALSE);		// Set small icon

  mPlay.EnableWindow(TRUE);
  mStop.EnableWindow(FALSE);
  mPause.EnableWindow(FALSE);
  mCurrent.SetWindowText("");

  mConfig.Load();
  LoadPlaylist();
  OnRandomize();
  
  return TRUE;  // return TRUE  unless you set the focus to a control
  }
void CJPlayerDlg::LoadPlaylist()
  {
  mConfig.AddAllTo(&mPlayer);
  }
void CJPlayerDlg::SetPlaylistBox()
  {
  mPlaylist.ResetContent();
  mPlayer.AddAllTo(&mPlaylist);
  }
void CJPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
  {
  if (AboutHandler::IsAboutBox(nID))
    AboutHandler::Show();
  else
    CDialog::OnSysCommand(nID, lParam);
  }

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
void CJPlayerDlg::OnPaint() 
  {
  if (IsIconic())
    HandleIconic();
  else
    CDialog::OnPaint();
  }

void CJPlayerDlg::HandleIconic()
  {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, mIcon);
  }

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CJPlayerDlg::OnQueryDragIcon()
  {
  return (HCURSOR) mIcon;
  }
void CJPlayerDlg::OnRandomize() 
  {
  mPlayer.Randomize();
  SetPlaylistBox();
  }
void CJPlayerDlg::OnSort() 
  {
  mPlayer.Sort();
  SetPlaylistBox();
  }
void CJPlayerDlg::OnPlay() 
  {
  Play();
  Pause = FALSE;
  mPlay.EnableWindow(FALSE);
  mPause.EnableWindow(TRUE);
  mStop.EnableWindow(TRUE);
  }
void CJPlayerDlg::OnNext() 
  {
  PlayNext();
  Pause = FALSE;
  mPlay.EnableWindow(FALSE);
  mPause.EnableWindow(TRUE);
  mStop.EnableWindow(TRUE);
  }
void CJPlayerDlg::OnPause() 
  {
  if (Pause)
    {
    mPause.SetWindowText("Pause");
    Pause = FALSE;
    mPlayer.Resume();
    }
  else
    {
    mPause.SetWindowText("Resume");
    Pause = TRUE;
    mPlayer.Pause();
    }
  }
void CJPlayerDlg::OnCancel() 
  {
  mPlayer.Stop();
  CDialog::OnCancel();
  }
void CJPlayerDlg::OnSelChange() 
  {
  int idx = mPlaylist.GetCurSel();
  CString p;
  mPlaylist.GetText(idx, p);
  mPlayer.Play(this->GetSafeHwnd(), (LPCSTR) p);
  SetCurrent((LPCSTR) p);
  }
void CJPlayerDlg::OnStop() 
  {
  mPlayer.Stop();
  mPlay.EnableWindow(TRUE);
  mPause.EnableWindow(FALSE);
  mStop.EnableWindow(FALSE);
  }
void CJPlayerDlg::OnSize(UINT nType, int cx, int cy)
  {
  if (!::IsWindow(m_hWnd) || !::IsWindow(mPlay.m_hWnd)) return;
  const int cRightBorder = 25;
  const int cBottomBorder = 10;
  const int gap = 3;
   
  RECT rct;
  mPlay.GetClientRect(&rct);
  int width = cx - rct.right - cRightBorder;

  mCurrent.GetWindowRect(&rct);
  ScreenToClient(&rct);
  int top = rct.bottom + gap;
  int height = cy - rct.bottom - cBottomBorder;

  mPlay.GetWindowRect(&rct);
  ScreenToClient(&rct);
  int left = rct.right + gap;

  mPlaylist.SetWindowPos(0, left, top, width, height, SWP_NOZORDER);
  }
void CJPlayerDlg::OnBrowse() 
  {
  CFileDialog avi(TRUE,NULL,NULL,OFN_HIDEREADONLY,"MP3 Files (*.mp3)|*.mp3|AVI Files(*.avi)|*.avi|");
  if(avi.DoModal() == IDOK)
    {
    mConfig.Add((LPCSTR) avi.GetPathName());
    mPlayer.AddString((LPCSTR) avi.GetPathName());
    UpdateData(FALSE);
    }
  }
void CJPlayerDlg::OnMMNotify(WPARAM wParam, LPARAM lParam)
  {
  if (wParam != 1 || lParam != 1) return;
  PlayNext();
  }
void CJPlayerDlg::PlayNext()
  {
  mPlayer.PlayNext(this->GetSafeHwnd());
  SetCurrent();
  }
void CJPlayerDlg::Play()
  {
  mPlayer.Play(this->GetSafeHwnd());
  SetCurrent();
  }
void CJPlayerDlg::SetCurrent()
  {
  SetCurrent(mPlayer.Current());
  }
void CJPlayerDlg::SetCurrent(const string& path)
  {
  mCurrent.SetWindowText(path.c_str());
  mPlaylist.SelectString(-1, path.c_str());
  UpdateData(FALSE);
  }

jPlayerDlg.h

Synopsis
#pragma once
#include "afxwin.h"
#include <string>
using std::string;

#include "PersistedList.h"
#include "ExtensibleContainer.h"
#include "Player.h"
class MyListBox : public CListBox, public ExtensibleContainer
  {
  public:
    void AddString(const char* item)
      {
      CListBox::AddString(item);
      }
  } ;

class CJPlayerDlg : public CDialog
  {
  public:
    CJPlayerDlg(CWnd* pParent = NULL);
    ~CJPlayerDlg();

    // Dialog Data
    //{{AFX_DATA(CJPlayerDlg)
    enum { IDD = IDD_JPLAYER_DIALOG };
    CButton	mPlay;
    CButton	mStop;
    CButton	mPause;
    CStatic mCurrent;
    MyListBox mPlaylist;
    //}}AFX_DATA


    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CJPlayerDlg)
  protected:
    virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
    //}}AFX_VIRTUAL

    // Implementation
  protected:
    HICON mIcon;

    // Generated message map functions
    //{{AFX_MSG(CJPlayerDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg void OnPlay();
    afx_msg void OnSort();
    afx_msg void OnRandomize();
    afx_msg void OnNext();
    afx_msg void OnPause();
    virtual void OnCancel();
    afx_msg void OnStop();
    afx_msg void OnBrowse();
    afx_msg void OnSelChange();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnMMNotify(WPARAM wParam, LPARAM lParam);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()

    void PlayNext();
    void Play();
    void SetCurrent();
    void SetCurrent(const string& path);
    void SetPlaylistBox();
    void LoadPlaylist();
    void HandleIconic();
  private:
    PersistedList mConfig;
    Player mPlayer;
    BOOL Pause;
  };

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.


MciWrapper.cpp

Synopsis
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <vfw.h>
#include <mmsystem.h>

#include "mciwrapper.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

MciWrapper::MciWrapper()
  {
  Init();
  }
void MciWrapper::Init()
  {
  m_Video = 0;
  }
bool MciWrapper::IsActive()
  {
  return m_Video != 0;
  }
void MciWrapper::Resume()
  {
  MCIWndResume(m_Video);
  }
void MciWrapper::Pause()
  {
  MCIWndPause(m_Video);
  }
//MCIWndHome(mPlayer->m_Video); //rewind to beginning
void MciWrapper::Stop()
  {
  if (!IsActive()) return;
  MCIWndStop(m_Video);
  MCIWndDestroy(m_Video);
  Init();
  }
void MciWrapper::Play(HWND parent, const string& path)
  {
  m_Video = MCIWndCreate(parent, 
           AfxGetInstanceHandle(),
           WS_CHILD | WS_VISIBLE |MCIWNDF_NOMENU, 
           path.c_str());
  MCI_PLAY_PARMS pparms;
  pparms.dwCallback = (DWORD) parent;
  pparms.dwFrom = 0;
  pparms.dwTo = 0;

  MCIERROR err = mciSendCommand(
    MCI_ALL_DEVICE_ID,
    MCI_PLAY, 
    MCI_NOTIFY, 
    (DWORD) &pparms);
  }

MciWrapper.h

Synopsis
#pragma once
#include <string>
using std::string;

class MciWrapper
  {
  public:
    MciWrapper();
    void Init();
    bool IsActive();
    void Resume();
    void Pause();
    void Stop();
    void Play(HWND parent, const string& path);
  private:
    HWND m_Video;
  } ;

PersistedList.cpp

Synopsis
#pragma warning(disable: 4786)
#include <fstream>
using namespace std;
#include "persistedlist.h"
#include "Util.h"
#include "ExtensibleContainer.h"

const char* cConfigFileName = "jPlayer.cfg";

PersistedList::PersistedList()
: mDirty(false)
  {
  Util util;
  mRootDir = util.GetExecutableDir();
  }
PersistedList::~PersistedList()
  {
  Save();
  }
void PersistedList::Add(const string& path)
  {
  mDirty = true;
  mList.push_back(path);
  Reset();
  }
void PersistedList::AddAllTo(ExtensibleContainer* list)
  {
  for (Reset(); !Done(); Next())
    list->AddString(Current().c_str());
  }

void PersistedList::Load()
  {
  char buf[4096];
  string cfgfile = mRootDir + "\\" + cConfigFileName;
  ifstream ifs(cfgfile.c_str());
  while(!ifs.eof())
    {
    if (ifs.fail()) break;
    ifs.getline(buf, sizeof(buf));
    if (strcmp(buf, "") == 0) continue;
    mList.push_back(buf);
    }
  ifs.close();
  }
void PersistedList::Save()
  {
  if (!mDirty) return;

  string cfgfile = mRootDir + "\\" + cConfigFileName;
  Util util;
  util.DelFile(cfgfile);
  ofstream ofs(cfgfile.c_str());
  for(Reset(); !Done(); Next())
    {
    if (ofs.fail()) break;
    ofs << Current() << "\n";
    }
  ofs.close();
  mDirty = false;
  }
void PersistedList::Reset()
  {
  mIt = mList.begin();
  }
bool PersistedList::Done()
  {
  return mIt == mList.end();
  }
void PersistedList::Next()
  {
  ++mIt;
  }
string PersistedList::Current()
  {
  return *mIt;
  }

PersistedList.h

Synopsis
#pragma once
#include <vector>
#include <string>
using std::vector;
using std::string;
typedef vector<string> StringList;

class ExtensibleContainer;
class PersistedList
  {
  public:
    PersistedList();
    ~PersistedList();
    void Load();
    void Save();
    void Reset();
    bool Done();
    void Next();
    string Current();
    void Add(const string& path);
    void AddAllTo(ExtensibleContainer* list);
  private:
    string mRootDir;
    bool mDirty;
    StringList mList;
    StringList::iterator mIt;
  } ;


Player.cpp

Synopsis
#pragma warning(disable: 4786)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "Player.h"
#include "MciWrapper.h"
#include "Playlist.h"

class Player::Private
  {
  public:
    MciWrapper mPlayer;
    Playlist mPlaylist;
  } ;

Player::Player()
: impl(* new Player::Private)
  {
  }
Player::~Player()
  {
  delete &impl;
  }
void Player::AddString(const char* path)
  {
  impl.mPlaylist.Add(path);
  }
void Player::Reset()
  {
  impl.mPlaylist.Reset();
  }
void Player::Randomize()
  {
  impl.mPlaylist.Randomize();
  }
void Player::Sort()
  {
  impl.mPlaylist.Sort();
  }
void Player::AddAllTo(ExtensibleContainer* list)
  {
  impl.mPlaylist.AddAllTo(list);
  impl.mPlaylist.Reset();
  }
void Player::PlayNext(HWND parent)
  {
  impl.mPlayer.Stop();
  impl.mPlaylist.Next();
  if (impl.mPlaylist.Done()) return;
  impl.mPlayer.Play(parent, impl.mPlaylist.Current().c_str());
  }
void Player::Play(HWND parent)
  {
  impl.mPlayer.Stop();
  impl.mPlayer.Play(parent, impl.mPlaylist.Current().c_str());
  }
void Player::Play(HWND parent, const string& path)
  {
  impl.mPlayer.Stop();
  impl.mPlaylist.Find(path);
  impl.mPlayer.Play(parent, path);
  }
const string Player::Current()
  {
  return impl.mPlaylist.Current();
  }
void Player::Resume()
  {
  impl.mPlayer.Resume();
  }
void Player::Pause()
  {
  impl.mPlayer.Pause();
  }
void Player::Stop()
  {
  impl.mPlayer.Stop();
  }

Player.h

Synopsis
#pragma once
#include <string>
using std::string;
#include "ExtensibleContainer.h"

class Player : public ExtensibleContainer
  {
  public:
    Player();
    ~Player();
    void AddString(const char* path);
    void AddAllTo(ExtensibleContainer* list);
    void Reset();
    void Randomize();
    void Sort();
    void PlayNext(HWND parent);
    void Play(HWND parent);
    void Play(HWND parent, const string& path);
    const string Current();
    void Resume();
    void Pause();
    void Stop();
  private:
    class Private;
    Private& impl;
  };

Playlist.cpp

Synopsis
#pragma warning(disable: 4786)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <time.h>
#include <algorithm>
using std::random_shuffle;
using std::find;
using std::sort;
#include "playlist.h"
#include "FileFinder.h"
#include "ExtensibleContainer.h"

void Playlist::AddAllTo(ExtensibleContainer* list)
  {
  for(Reset(); !Done(); Next())
    list->AddString(Current().c_str());
  }
void Playlist::Add(const string& path)
  {
  if (IsDir(path))
    AddDir(path);
  else
    AddFile(path);
  }

void Playlist::Find(const string& path)
  {
  SetCursor(path);
  if (mIt == mPlaylist.end())
    {
    AddFile(path);
    SetCursor(path);
    }
  }
void Playlist::Reset()
  {
  mIt = mPlaylist.begin();
  }
void Playlist::Next()
  {
  if (Done()) return;
  ++mIt;
  }
bool Playlist::Done() const
  {
  return mIt == mPlaylist.end();
  }
const string Playlist::Current() const
  {
  if (Done()) return string();
  return *mIt;
  }
void Playlist::Randomize()
  {
  srand(time(0));
  random_shuffle(mPlaylist.begin(), mPlaylist.end());
  }
void Playlist::Sort()
  {
  sort(mPlaylist.begin(), mPlaylist.end());
  }
bool Playlist::IsDir(const string& path)
  {
  DWORD dw = ::GetFileAttributes(path.c_str());
  return (dw & FILE_ATTRIBUTE_DIRECTORY) != 0;
  }
void Playlist::AddDir(const string& path)
  {
  FileFinder finder;
  for(finder.first(path); finder.next(); )
    {
    if (finder.isDotFiles()) continue;
    AddFile(path + "\\" + finder.getName());
    }
  finder.close();
  }
void Playlist::AddFile(const string& path)
  {
  if (Contains(path)) return;
  mPlaylist.push_back(path);
  }
bool Playlist::Contains(const string& path)
  {
  return find(mPlaylist.begin(), mPlaylist.end(), path) != mPlaylist.end();
  }
void Playlist::SetCursor(const string& path)
  {
  mIt = find(mPlaylist.begin(), mPlaylist.end(), path);
  }

Playlist.h

Synopsis
#pragma once
#include <string>
#include <vector>
using std::string;
using std::vector;

typedef vector<string> StringList;
typedef std::vector<string>::iterator StringListIterator;

class ExtensibleContainer;
class Playlist
  {
  public:
    void Add(const string& path);
    void AddAllTo(ExtensibleContainer* list);
    void Find(const string& path);
    void Reset();
    void Next();
    bool Done() const;
    const string Current() const;
    void Randomize();
    void Sort();
  private:
    bool IsDir(const string& path);
    void AddDir(const string& path);
    void AddFile(const string& path);
    bool Contains(const string& path);
    void SetCursor(const string& path);
  private:
    vector<string> mPlaylist;
    StringListIterator mIt;
  };

resource.h

Synopsis
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by jPlayer.rc
//
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_JPLAYER_DIALOG              102
#define IDR_MAINFRAME                   128
#define IDC_PLAY                        1000
#define IDC_STOP                        1001
#define IDC_PAUSE                       1002
#define IDC_NEXT                        1003
#define IDC_PATH                        1004
#define IDC_PAUSE2                      1004
#define IDC_BROWSE                      1005
#define IDC_FILELIST                    1006
#define IDC_CURRENT                     1007
#define IDC_RANDOMIZE                   1008
#define IDC_SORT                        1009
#define IDC_BROWSE2                     1010
#define IDC_NEXT2                       1011
#define IDC_RANDOMIZE2                  1012
#define IDC_SORT2                       1013

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1009
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

Util.cpp

Synopsis
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <direct.h>
#include "Util.h"

void Util::DelFile(const string& file)
  {
  ::DeleteFile(file.c_str());
  }

//1) if there is an absolute path, use that
//2) if there is a relative path
//   - if the relpath starts with a \, get current drive and prepend
//   - if the relpath doesn't start with a '\', get current dir and prepend
//3) if there is no path at all; search the directories in the PATH for the executable
class ExecDir
  {
  public:
    string Get()
      {
      GetDirFromCmdLine();
      if (IsNoDir())
        return SearchPath();
      
      if (IsAbsolutePath())
        return mDir;
      
      if (IsRelPathFromRoot()) //e.g. '\bin\etc'
        return GetDrive() + mDir;

      return GetCwd() + "\\" + mDir;
      }

  private:
    void GetDirFromCmdLine()
      {
      char cmdline[_MAX_PATH];
      GetCmdLine(cmdline);
      RemoveFilename(cmdline);
      strcpy(mDir, cmdline);
      }
    void GetCmdLine(char* cmdline)
      {
      LPCSTR c = ::GetCommandLine();

      if (c[0] == '"')
        ++c;
      strcpy(cmdline, c);
      if (cmdline[strlen(cmdline)-2] == '"')
        cmdline[strlen(cmdline)-2] = 0;
      ConvertSlashes(cmdline);
      }
    void RemoveFilename(char* cmdline)
      {
      char* p = strrchr(cmdline, '\\');
      if (p)
        *p = 0;
      else
        cmdline[0] = 0;
      }
    bool IsRelPathFromRoot()
      {
      return mDir[0] == '\\';
      }
    bool IsNoDir()
      {
      return strcmp(mDir, "") == 0;
      }
    bool IsAbsolutePath()
      {
      return strlen(mDir) >= 4 && mDir[1] == ':';
      }
    void ConvertSlashes(char* str)
      {
      for (char* p = str; *p; ++p)
        {
        if (*p == '/')
          *p = '\\';
        }
      }
    void StripTrailingSlash(char* p)
      {
      if (p[strlen(p)-1] == '\\')
        p[strlen(p)-1] = 0;
      }
    string SearchPath()
      {
      char ospath[32767];
      ::GetEnvironmentVariable("PATH", ospath, sizeof(ospath));
      for(char* p = strtok(ospath, ";"); p; p = strtok(0, ";"))
        {
        const DWORD cFileAttribute = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE;
        string path(p);
        path += "\\jplayer.exe";
        DWORD res = ::GetFileAttributes(path.c_str());
        if (res != 0xFFFFFFFF && (res & cFileAttribute) )
          return p;
        }
      return "";
      }
    string GetCwd()
      {
      char cwd[_MAX_PATH];
      _getcwd(cwd, sizeof(cwd));
      StripTrailingSlash(cwd);
      return cwd;
      }
    string GetDrive()
      {
      string cwd = GetCwd();
      char drive[3];
      strncpy(drive, cwd.c_str(), 2);
      drive[2] = 0;
      return drive;
      }

  private:
    char mDir[_MAX_PATH];
  };

string Util::GetExecutableDir()
  {
  ExecDir ed;
  return ed.Get();
  }

Util.h

Synopsis
#pragma once
#include <string>
using std::string;

class Util
  {
  public:
    void DelFile(const string& file);
    string GetExecutableDir();
  } ;






Contact me about content on this page using john_web-at-arrizza-dot-com
For Web Master or site problems contact: webadmin-at-arrizza-dot-com
Copyright John Arrizza (c) 2001-2010