Click here to Skip to main content
15,886,055 members
Articles / Mobile Apps / Windows Mobile

Audio Book Player

Rate me:
Please Sign up or sign in to vote.
4.86/5 (36 votes)
11 Jun 2009CPOL6 min read 197.5K   3.5K   84  
Audio player designed specifically for listening to audio books
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Threading;
using System.Runtime.InteropServices;

namespace abPlayer
{
    public partial class frmFileSelector : Form
    {
        // API calls
        [DllImport("coredll.dll")]
        public static extern IntPtr GetDC(IntPtr hWnd);
        [DllImport("coredll.dll")]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        // treeview root name
        private const String ROOT_NAME = "My Device";
        // selected book & files are returned in these
        public ArrayList BookFiles = null;
        public String DefaultBookName = "";

        public frmFileSelector()
        {
            InitializeComponent();

            // selected book & files are returned in these
            BookFiles = new ArrayList();
        }
        // override the showdialog so we can do some prep
        // first time only - we scan the directories and build the treeview
        // on subsequnt call we initialize view
        public new DialogResult ShowDialog()
        {
            // reset book name & files
            BookFiles.Clear();
            DefaultBookName = "";
            // clear files
            lvw.Items.Clear();
            // erase book count display
            spl.Refresh();
            chkRec.Checked = false;
            // no treeview entries? - this is the first call - build treeview
            if (tvw.Nodes.Count == 0)
            {
                // this may take time - show wait cursor
                Cursor.Current = Cursors.WaitCursor;
                tvw.BeginUpdate();
                // create root node
                TreeNode node = tvw.Nodes.Add(ROOT_NAME);
                // add subdirs - this is a recursive function and is re-called
                // for every directory found until all have been scanned
                AddDirs(node);
                tvw.EndUpdate();
                // expand root
                node.Expand();
                // change cursor back to normal
                Cursor.Current = Cursors.Default;
            }
            return base.ShowDialog();
        }
        // since we have a fictitios root we need to override the default
        // fullpath function to return a legitimate path
        String FullPath(TreeNode node)
        {
            return (node.Text == ROOT_NAME) ? "\\" : node.FullPath.Substring(ROOT_NAME.Length);
        }
        // recursive function that reads all the subdirectories of a given
        // directory and adds them to the treeview. the node parameter is
        // the directory/node to be scanned
        private void AddDirs(TreeNode node)
        {
            // holds the directories we find
            String[] dirs = new string[0];
            // sub-node
            TreeNode sNode = null;
            // get subdirs
            try
            {
                dirs = Directory.GetDirectories(FullPath(node));
            }
            catch { }
            // sort them
            Array.Sort(dirs);
            foreach (String dir in dirs)
            {
                // use the file name of the path as treenode name
                sNode = node.Nodes.Add(new FileInfo(dir).Name);
                // image - directory
                sNode.ImageIndex = 0;
                sNode.SelectedImageIndex = 1;
                // go do it now for the newly found dir
                AddDirs(sNode);
            }
        }
        // when a treenode is selected - we display the media files in it
        // in the listview
        private void tvw_AfterSelect(object sender, TreeViewEventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            lvw.BeginUpdate();
            // clear all previous files
            lvw.Items.Clear();
            // clear result set
            BookFiles.Clear();
            // if a treenode is selected - go fetch the files
            if(e.Node != null)
                if (e.Node.IsSelected) 
                    ShowFiles(FullPath(e.Node));
            // show file count 
            spl.Refresh();
            lvw.EndUpdate();
            Cursor.Current = Cursors.Default;
        }
        // scan a directory (path) find media files and add to listview
        // this is a recursive function that may be called for all
        // subdirectories if relevant chekbox is checked
        private void ShowFiles(String path)
        {
            // get files
            String[] files = GetMediaFiles(path);
            // sort
            Array.Sort(files);
            foreach (String file in files)
            {
                // extract file name from path
                // add to listview
                ListViewItem item = lvw.Items.Add(new ListViewItem(new FileInfo(file).Name));
                // set image index
                item.ImageIndex = 2;
                // default state is checked (included)
                item.Checked = true;
                // add files to result set
                BookFiles.Add(file); 
            }
            // subdirs are to scanned:
            if (chkRec.Checked)
            {
                // get subdirs
                String[] dirs = Directory.GetDirectories(path);
                // sort
                Array.Sort(dirs);
                // repeat scan for all found subdirs
                foreach (String dir in dirs)
                    ShowFiles(dir);
            }
        }

        public String[] GetMediaFiles(String path)
        {
            // audio files supported by WMP
            String[] MEDIA_FILES = {"*.mp3", "*.wav", "*.snd", "*.wma", "*.mid"};
            ArrayList files = new ArrayList();
            foreach (String pattern in MEDIA_FILES)
            {
                try
                {
                    files.AddRange(Directory.GetFiles(path, pattern));
                }
                catch (Exception e)
                {
                    MessageBox.Show("File System Error : " + e.Message);
                }
            }
            return (String[])files.ToArray(typeof(String));
        }

        // use splitter as a paint area to display file count
        private void spl_Paint(object sender, PaintEventArgs e)
        {
            // erase the whole control face with its backcolor
            e.Graphics.FillRectangle(new SolidBrush(spl.BackColor), 0, 0,
                spl.Width, spl.Height);
            // draw rectangle around it
            e.Graphics.DrawRectangle(new Pen(Color.Silver, 1),
                new Rectangle(0, 0, spl.Width - 2, spl.Height - 2));
            // if no files are displayed - we are done
            if (lvw.Items.Count <= 0) return;
            // set display string
            String txt = lvw.Items.Count.ToString() + " Files";
            // get string sizes
            SizeF strWH = e.Graphics.MeasureString(txt, this.Font);
            // display string in mid horizontal and vertical point
            e.Graphics.DrawString(txt, this.Font, new SolidBrush(Color.White),
                (spl.Width / 2 - strWH.Width / 2),
                (spl.Height / 2 - strWH.Height / 2));
        }
        // user hit OK
        private void btnOK_Click(object sender, EventArgs e)
        {
            FlashControl((Control)sender);
            // only if a directory is selected
            if (tvw.SelectedNode != null)
            {
                // bookfiles already holds all files, however, user might have
                // deselected some/all
                // remove deselected files from result set
                bool found = false;
                for (int i = 0; i < lvw.Items.Count; i++)
                {
                    if (lvw.Items[i].Checked)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                    return;
                for (int i = lvw.Items.Count - 1; i >= 0; i--)
                {
                    if (!lvw.Items[i].Checked)
                        BookFiles.RemoveAt(i);
                }
                // directory name is default book name
                DefaultBookName = tvw.SelectedNode.Text;
                // go back
                DialogResult = DialogResult.OK;
            }
        }
        // user hit cancel
        private void btnCancel_Click(object sender, EventArgs e)
        {
            FlashControl((Control)sender);
            // reset result set
            DefaultBookName = "";
            BookFiles.Clear();
            // go back
            DialogResult = DialogResult.Cancel;
        }
        // draw pic pitton if skin load failed
        public void Pic_Paint(object sender, PaintEventArgs e)
        {
            PictureBox obj = (PictureBox)sender;
            if (obj.Image == null)
            {
                String str = (String)obj.Tag;
                e.Graphics.FillRectangle(new SolidBrush(Color.White),
                    1, 1, obj.Width - 2, obj.Height - 2);
                if (str.Length > 0)
                {
                    float size = Font.Size + 1;
                    Font font;
                    SizeF strWH;
                    do
                    {
                        size--;
                        font = new Font(Font.Name, size, FontStyle.Bold);
                        strWH = e.Graphics.MeasureString(str, font);
                    } while (strWH.Width > obj.Width);
                    e.Graphics.DrawString(str, font, new SolidBrush(Color.Black),
                        (obj.Width - strWH.Width) / 2,
                        (obj.Height - strWH.Height) / 2);
                }
            }
        }
        // function used by the frmPlayer and this form to provide visual 
        // confirmation that a button (actually a picture box) was pressed:
        public void FlashControl(Control Wnd)
        {
            // create a graphics object from the control's dc
            IntPtr hDC = GetDC(Wnd.Handle);
            Graphics dc = Graphics.FromHdc(hDC);
            // paint the whole control area black
            dc.FillRectangle(new SolidBrush(Wnd.BackColor), 0, 0,
                Wnd.Width, Wnd.Height);
            // allow effect to take place
            Application.DoEvents();
            // go sleep for a while (60 milliseconds)
            Thread.Sleep(60);
            // release resources
            ReleaseDC(Wnd.Handle, hDC);
            dc.Dispose();
            // have the control re-paint itself
            Wnd.Refresh();
        }

        private void chkRec_CheckStateChanged(object sender, EventArgs e)
        {
            tvw_AfterSelect(tvw, new TreeViewEventArgs(tvw.SelectedNode, TreeViewAction.Unknown));
        }

        private void picNone_Click(object sender, EventArgs e)
        {
            CheckItems(sender, false);
        }

        private void picAll_Click(object sender, EventArgs e)
        {
            CheckItems(sender, true);
        }

        private void CheckItems(object sender, bool Value)
        {
            FlashControl((Control)sender);
            foreach (ListViewItem item in lvw.Items)
                item.Checked = Value;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions