Download CD Content
The popularity of MP3 music is unquestioned. There have been several lawsuits directed by the recording industry at companies that aid users in sharing the files, which many times are protected under copyright laws. The media attention to the format is incredible, and with all the publicity, the user base of programs like Kazaa, Morpheus, or any of the similar offerings that allow individuals to freely exchange MP3 files, continues to grow nearly exponentially. This is not an endorsement of exchanging copyrighted materials, but rather an acknowledgment that regardless of the outcome of future lawsuits, the format itself is so popular that it will undoubtedly remain in one capacity or another. With this in mind, developing an MP3 player is a very good project for learning Visual Basic and Tablet PC programming concepts.
The source code for the projects are located on the CD-ROM in the PROJECTS folder. You can either type them in as you go or you can copy the projects from the CD-ROM to your hard drive for editing.
In this chapter, you'll develop an MP3 player. This project could be based around a number of commercial ActiveX controls, but the goal of this book is to allow you to complete most of the projects without spending any additional money.
Instead of an ActiveX control, you could also remotely control another application from a Visual Basic program. For instance, it is relatively easy to write a program that remotely controls an existing MP3 player. Again, this option requires you to purchase additional software, which you shouldn't have to do. Another problem with this approach occurs if you decide to distribute your application to other users. Controlling another application requires the user of your MP3 player to purchase another MP3 player. Instead of an ActiveX control or another application, the solution we use is the Winmm.dll file and Multimedia Control Interface (MCI) commands.
To begin our project, we will construct the basic GUI for the MP3 player. Start the Visual Basic IDE, and from the New Projects window, make sure that Visual Basic is selected and then select Windows Application. You can change the name of the project to something you'd like (it is named Chapter 16 on the CD-ROM and throughout the chapter).
You need to place several controls on the form, one of which is the Open File Dialog. You can place this control anywhere you want as it's not visible at runtime. When you drag it onto the form, it will be displayed beneath the form (see Figure 16.1).
Figure 16.1: The File Open Dialog visible beneath the form and with the Text Property changed.
The next step is to alter the Text property of the form to read 'VB MP3' (without quotations). You will find this property in the Properties window. Next, place a series of command buttons for opening, stopping, and so on. The buttons can be arranged along the top side of the form going from left to right and can be named as follows: cmdOpen, cmdPlay, cmdStop, cmdPause, and cmdClose. Their captions should also be altered to reflect their intended usage; that is, the cmdOpen button should have its caption property renamed to Open. When it's finished, the form should look similar to Figure 16.2.
Figure 16.2: The interface is beginning to take shape with command buttons in place.
The final components that need to be added are a Label control, which will be used to display the filename of the song, and another Label control, which is added to identify the use of the control to the end user. You can name the control lblCaption and change the Text property to an empty string (just erase anything inside the field in the Properties window). The last Label control can be positioned to its left and given a Text Property of 'Filename :'.
If a specific name isn't given, you can use the standard VB assigned names.
Your final interface should appear similar to Figure 16.3.
Figure 16.3: The final GUI.
This application uses several variables to store information. If you double-click the form, it displays the Code Editor and your cursor will be visible in the Form1_Load event. You can move the cursor directly above this event and place the following variable declarations directly beneath 'Inherits System. Inherits.System.Windows.Forms.Form':
Private Declare Function mciSendString Lib "winmm.dll" _ Alias "mciSendStringA" (ByVal lpstrCommand As String, _ ByVal lpstrReturnString As String, ByVal uReturnLength _ As Long, ByVal hwndback As Long) As Long Dim strFileName As String Dim blnPlaying As Boolean Dim Temp As Integer Dim command As String Dim s As String Dim strFileNameTemp As String
You may have noticed the underline character '_' located in the Private Declare statement. This simply allows you to use multiple lines to display a line that should actually be located in a single line.
Although there are several variables, the first line, which begins with Private Declare..., is the most interesting. It's a Windows Application Programming Interface (API) call. For now, you don't need to concern yourself too much with API calls as they are discussed in detail in Chapter 17, Form Effects, but you do need to understand that the mciSendString function is now available to the entire form. The mciSendString function sends a command to a Multimedia Control Interface (MCI) device. The command strings used with this function can perform almost any task necessary for using a multimedia device installed on the computer and provides a relatively easy way to perform multimedia output operations.
The Form1_Load event is called when the form is first displayed. We'll use this event to set up the lblCaption to read ' - No Media'. Enter the following code for the Form_Load event, which sets lblCaption to a value to inform the user that nothing is currently opened:
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load lblCaption.Text = " -- No Media" End Sub
You have created a command button called cmdOpen that will be used by the program to open the MP3 file. We simply use the cmdOpen_Click event, which occurs when the button is clicked. Before we play the file, we need to check to see if a file is already playing, and if there is one playing, you should exit the procedure without opening a file. However, you should let the user know that they are trying to open the player when a file is already open. If a file is not playing, you should continue on with opening a file, which begins with initializing the OpenFileDialog control so that it displays only MP3 files. Lastly, you should use the mciSendString function to open the file.
The following code does all of this:
Private Sub cmdOpen_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdOpen.Click On Error GoTo ErrorHandler If blnPlaying Then MsgBox("Player is Busy!", vbExclamation) Exit Sub End If OpenFileDialog1.Filter = "MP3 Files|*.MP3" OpenFileDialog1.ShowDialog() If OpenFileDialog1.FileName = "" Or _ OpenFileDialog1.FileName = strFileName Then Else strFileName = OpenFileDialog1.FileName strFileNameTemp = OpenFileDialog1.FileName FileCopy(strFileName, "C:mciplay") strFileName = "C:mciplay" mciSendString("open " & strFileName & " type MPEGVideo", _ 0, 0, 0) lblCaption.Text = strFileNameTemp End If ErrorHandler: End Sub
There is an interesting problem with using the mciSendString method for playing MP3 audio files. The filename cannot be more than 8 characters followed by 26 characters as an extension. It's obviously not practical to limit your application to use only files named in this format, so we'll solve this by copying the file to the root directory of your hard drive and giving it a name of MCIPlay. We'll then use this filename to actually play the file. The mciSendString command is very strict about its syntax, uses quotation marks, and includes MPEGVideo as its type. Although it says Video, it is the correct type for MP3 audio files as well.
After you have opened the file, you can use the command buttons you created for playing, stopping, pausing, and so on. The programming that is used in all of the procedures is nearly identical. First, you need to see if a file is already playing by checking the blnPlaying variable, which is of type Boolean. A Boolean variable can display only two values 'True' or 'False'(could also be thought of as 0 or 1, Off or On). If a file is playing, you can send an MCI code to do the task. Lastly, you can change the lblCaption to reflect the command.
The following lists all of the procedures:
Private Sub cmdClose_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdClose.Click If blnPlaying Then mciSendString("close " & strFileName, 0, 0, 0) End If blnPlaying = False lblCaption.Text = " --No Media" End Sub Private Sub cmdPause_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdPause.Click If blnPlaying Then mciSendString("pause " & strFileName, 0, 0, 0) blnPlaying = False lblCaption.Text = OpenFileDialog1.Filename & " --Paused" End If End Sub Private Sub cmdPlay_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdPlay.Click If strFileName <> "" Then mciSendString("play " & strFileName, 0, 0, 0) blnPlaying = True lblCaption.Text = OpenFileDialog1.Filename & " -- Playing" End If End Sub Private Sub cmdStop_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdStop.Click If blnPlaying Then mciSendString("stop " & strFileName, 0, 0, 0) blnPlaying = False lblCaption.Text = OpenFileDialog1.Filename & " -- Stopped" End If End Sub
The only procedure that differs slightly is the cmdPlay_Click procedure, which does not check the status of a playing file. Rather, it only needs to determine if the strFileName variable contains information. If it does, it knows that it must have a file open. If not, it exits the procedure.
Figure 16.4 represents what the finished MP3 player should look like when playing a file. If you are interested, you can add common functions such as play lists or captions that display time-related information. This project is used in Chapter 17, Form Effects, to add some interesting changes to the vanilla-looking GUI.
Figure 16.4: Playing an MP3 file.
At this point, the application doesn't really offer any features that would make it specifically useful for a Tablet PC. In this section, we add some functions that allow us to open, close, and pause the player by using only the pen. Obviously, because the stylus acts as a mouse, you could click the buttons to execute their respective tasks. However, we are going to write commands directly to the application to perform the tasks. You'll see that this isn't really much of a time-saver for a pen user, and we'll look at a shorthanded version of pen input, known as gestures in Chapter 18, Using Gestures to Control Tablet Media Player.
There are a number of ways in which we could proceed for a method to allow pen input, but perhaps the easiest way is to hide the command buttons we used to create the application by placing an InkEdit control over them as seen in Figure 16.5.
Figure 16.5: The InkEdit control roughly hides the command buttons.
Now that the buttons are not visible, we need to have a way to control the application functions via text entry. The first thing we need to do is change the Text property of the InkEdit control to an empty string using the Form_Load event:
InkEdit1.Text = ""
The remaining changes required for this application are very simple. We'll take advantage of the PerformClick method available for the existing buttons. Instead of requiring us to rewrite the existing code, we can simulate the buttons being pressed, which runs the code we have already written.
We'll use a Case statement to browse through the various options for checking the commands that are being entered into InkEdit. We can use the TextChanged event for InkEdit in which we take text from InkEdit, convert it to text, and then check this for the various commands (i.e., Play, Pause, and so on). We'll simulate the correct button press depending on the text entered into the InkEdit control. After we go through the various options, we need to set the InkEdit Text property to an empty string.
Here is the code:
Private Sub InkEdit1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles InkEdit1.TextChanged Select Case InkEdit1.Text.ToUpper Case "OPEN " ' needs space after this or could remove cmdOpen.PerformClick() Case "CLOSE " cmdClose.PerformClick() Case "PLAY " cmdPlay.PerformClick() Case "STOP " cmdStop.PerformClick() Case "PAUSE " cmdPause.PerformClick() Case "EXIT" End Case Else End Select InkEdit1.Text = "" End Sub
Our first step is to add a reference to the Tablet PC API (and Tablet PC API 1.5 if you want). Next, add the following declarations:
Public myInk() As Byte Public myInkString As String Dim WithEvents theInkCollector As InkCollector
In this chapter, we built a fully functional MP3 player and have used an InkEdit control to handle the functions it provides. You sent commands to the Winmm.dll file by using mciSendStrings, which played the MP3 files.