| vbAccelerator - Contents of code file: AudioCDWriterVB\frmAudioCDCreator.vbThis file is part of the download Audio CD Writer, which is described in the article Writing Audio CDs. Imports vbAccelerator.Components.ImapiWrapper
Imports System.IO
Imports System.Threading
Public Class frmAudioCDCreator
Inherits System.Windows.Forms.Form
Private WithEvents discMaster As discMaster = Nothing
Private redbookDiscMaster As RedbookDiscMaster = Nothing
Private creator As AudioCDCreator = Nothing
Private createCDHandler As CreateCDDelegate = Nothing
Private burnInProgress As Boolean = False
Private cancel As Boolean = False
Private preparingFlag As Boolean = False
Private lastCompleted As Integer = 0
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
AddHandler Application.ThreadException, AddressOf
application_ThreadException
Show()
Refresh()
' Create the disc master object and initialse the recorder list:
GetRecorders()
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents sbrMain As System.Windows.Forms.StatusBar
Friend WithEvents prgBurn As System.Windows.Forms.ProgressBar
Friend WithEvents chkEjectWhenComplete As System.Windows.Forms.CheckBox
Friend WithEvents chkSimulate As System.Windows.Forms.CheckBox
Friend WithEvents btnBurn As System.Windows.Forms.Button
Friend WithEvents btnRemove As System.Windows.Forms.Button
Friend WithEvents btnAdd As System.Windows.Forms.Button
Friend WithEvents btnMoveDown As System.Windows.Forms.Button
Friend WithEvents btnMoveUp As System.Windows.Forms.Button
Friend WithEvents lstFiles As System.Windows.Forms.ListBox
Friend WithEvents lblFiles As System.Windows.Forms.Label
Friend WithEvents cboRecorder As System.Windows.Forms.ComboBox
Friend WithEvents lblRecorder As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Dim resources As System.Resources.ResourceManager = New
System.Resources.ResourceManager(GetType(frmAudioCDCreator))
Me.sbrMain = New System.Windows.Forms.StatusBar()
Me.prgBurn = New System.Windows.Forms.ProgressBar()
Me.chkEjectWhenComplete = New System.Windows.Forms.CheckBox()
Me.chkSimulate = New System.Windows.Forms.CheckBox()
Me.btnBurn = New System.Windows.Forms.Button()
Me.btnRemove = New System.Windows.Forms.Button()
Me.btnAdd = New System.Windows.Forms.Button()
Me.btnMoveDown = New System.Windows.Forms.Button()
Me.btnMoveUp = New System.Windows.Forms.Button()
Me.lstFiles = New System.Windows.Forms.ListBox()
Me.lblFiles = New System.Windows.Forms.Label()
Me.cboRecorder = New System.Windows.Forms.ComboBox()
Me.lblRecorder = New System.Windows.Forms.Label()
Me.SuspendLayout()
'
'sbrMain
'
Me.sbrMain.Location = New System.Drawing.Point(0, 418)
Me.sbrMain.Name = "sbrMain"
Me.sbrMain.Size = New System.Drawing.Size(500, 20)
Me.sbrMain.TabIndex = 25
'
'prgBurn
'
Me.prgBurn.Location = New System.Drawing.Point(96, 392)
Me.prgBurn.Name = "prgBurn"
Me.prgBurn.Size = New System.Drawing.Size(400, 20)
Me.prgBurn.TabIndex = 24
'
'chkEjectWhenComplete
'
Me.chkEjectWhenComplete.Checked = True
Me.chkEjectWhenComplete.CheckState =
System.Windows.Forms.CheckState.Checked
Me.chkEjectWhenComplete.FlatStyle =
System.Windows.Forms.FlatStyle.System
Me.chkEjectWhenComplete.Location = New System.Drawing.Point(188, 360)
Me.chkEjectWhenComplete.Name = "chkEjectWhenComplete"
Me.chkEjectWhenComplete.Size = New System.Drawing.Size(236, 16)
Me.chkEjectWhenComplete.TabIndex = 23
Me.chkEjectWhenComplete.Text = "&Eject When Complete"
'
'chkSimulate
'
Me.chkSimulate.Checked = True
Me.chkSimulate.CheckState = System.Windows.Forms.CheckState.Checked
Me.chkSimulate.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.chkSimulate.Location = New System.Drawing.Point(188, 340)
Me.chkSimulate.Name = "chkSimulate"
Me.chkSimulate.Size = New System.Drawing.Size(236, 16)
Me.chkSimulate.TabIndex = 22
Me.chkSimulate.Text = "&Simulate"
'
'btnBurn
'
Me.btnBurn.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnBurn.Location = New System.Drawing.Point(96, 340)
Me.btnBurn.Name = "btnBurn"
Me.btnBurn.Size = New System.Drawing.Size(88, 24)
Me.btnBurn.TabIndex = 21
Me.btnBurn.Text = "&Burn"
'
'btnRemove
'
Me.btnRemove.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnRemove.Location = New System.Drawing.Point(188, 296)
Me.btnRemove.Name = "btnRemove"
Me.btnRemove.Size = New System.Drawing.Size(88, 24)
Me.btnRemove.TabIndex = 20
Me.btnRemove.Text = "&Remove..."
'
'btnAdd
'
Me.btnAdd.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnAdd.Location = New System.Drawing.Point(96, 296)
Me.btnAdd.Name = "btnAdd"
Me.btnAdd.Size = New System.Drawing.Size(88, 24)
Me.btnAdd.TabIndex = 19
Me.btnAdd.Text = "&Add..."
'
'btnMoveDown
'
Me.btnMoveDown.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnMoveDown.Font = New System.Drawing.Font("Wingdings", 8.25!,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
CType(2, Byte))
Me.btnMoveDown.Location = New System.Drawing.Point(476, 156)
Me.btnMoveDown.Name = "btnMoveDown"
Me.btnMoveDown.Size = New System.Drawing.Size(20, 20)
Me.btnMoveDown.TabIndex = 18
Me.btnMoveDown.Text = ""
'
'btnMoveUp
'
Me.btnMoveUp.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnMoveUp.Font = New System.Drawing.Font("Wingdings", 8.25!,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
CType(2, Byte))
Me.btnMoveUp.Location = New System.Drawing.Point(476, 132)
Me.btnMoveUp.Name = "btnMoveUp"
Me.btnMoveUp.Size = New System.Drawing.Size(20, 20)
Me.btnMoveUp.TabIndex = 17
Me.btnMoveUp.Text = ""
'
'lstFiles
'
Me.lstFiles.Location = New System.Drawing.Point(92, 40)
Me.lstFiles.Name = "lstFiles"
Me.lstFiles.SelectionMode =
System.Windows.Forms.SelectionMode.MultiExtended
Me.lstFiles.Size = New System.Drawing.Size(380, 251)
Me.lstFiles.TabIndex = 16
'
'lblFiles
'
Me.lblFiles.Font = New System.Drawing.Font("Tahoma", 8.25!,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
CType(0, Byte))
Me.lblFiles.Location = New System.Drawing.Point(8, 44)
Me.lblFiles.Name = "lblFiles"
Me.lblFiles.Size = New System.Drawing.Size(76, 16)
Me.lblFiles.TabIndex = 15
Me.lblFiles.Text = "&Files:"
'
'cboRecorder
'
Me.cboRecorder.DropDownStyle =
System.Windows.Forms.ComboBoxStyle.DropDownList
Me.cboRecorder.Location = New System.Drawing.Point(92, 8)
Me.cboRecorder.Name = "cboRecorder"
Me.cboRecorder.Size = New System.Drawing.Size(404, 21)
Me.cboRecorder.TabIndex = 14
'
'lblRecorder
'
Me.lblRecorder.Font = New System.Drawing.Font("Tahoma", 8.25!,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
CType(0, Byte))
Me.lblRecorder.Location = New System.Drawing.Point(8, 12)
Me.lblRecorder.Name = "lblRecorder"
Me.lblRecorder.Size = New System.Drawing.Size(76, 16)
Me.lblRecorder.TabIndex = 13
Me.lblRecorder.Text = "&Recorder:"
'
'frmAudioCDCreator
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 14)
Me.ClientSize = New System.Drawing.Size(500, 438)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.sbrMain,
Me.prgBurn, Me.chkEjectWhenComplete, Me.chkSimulate, Me.btnBurn,
Me.btnRemove, Me.btnAdd, Me.btnMoveDown, Me.btnMoveUp, Me.lstFiles,
Me.lblFiles, Me.cboRecorder, Me.lblRecorder})
Me.Font = New System.Drawing.Font("Tahoma", 8.25!,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
CType(0, Byte))
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.Name = "frmAudioCDCreator"
Me.Text = "vbAccelerator .NET Audio CD Creator"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub application_ThreadException(ByVal sender As Object, ByVal e As
ThreadExceptionEventArgs)
MessageBox.Show(Me, String.Format("An untrapped exception occurred:
{0}. The application will now close.", e.Exception), _
Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
Close()
End Sub
Private Sub GetRecorders()
Dim ex As Exception
Try
discMaster = New DiscMaster()
redbookDiscMaster = discMaster.RedbookDiscMaster()
Dim recorder As DiscRecorder
For Each recorder In discMaster.DiscRecorders
cboRecorder.Items.Add( _
New ComboRecorderWrapper(recorder))
Next
If (cboRecorder.Items.Count > 0) Then
cboRecorder.SelectedIndex = 0
End If
Catch ex
MessageBox.Show(Me, String.Format("Unable to initialise the IMAPI
library {0}", ex), _
Text, MessageBoxButtons.OK, MessageBoxIcon.Stop)
If Not (discMaster Is Nothing) Then
discMaster.Dispose()
End If
End Try
End Sub
''' <summary>
''' Slight class to wrap a file for purposes of associating it
''' with a list box
''' </summary>
Class FileWrapper
Private ReadOnly m_fileName As String
Private ReadOnly m_audioBytes As Integer
Public Sub New(ByVal fileName As String, ByVal audioBytes As Integer)
m_fileName = fileName
m_audioBytes = audioBytes
End Sub
Public ReadOnly Property AudioBytes() As Integer
Get
Return m_audioBytes
End Get
End Property
Public ReadOnly Property FileName() As String
Get
Return m_fileName
End Get
End Property
Public Overrides Function GetHashCode() As Integer
Return m_fileName.GetHashCode()
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
Dim isEqual As Boolean = False
Dim other As FileWrapper = obj
If (other.FileName.Equals(m_fileName)) Then
isEqual = True
End If
Return isEqual
End Function
Public Overrides Function ToString() As String
Return m_fileName
End Function
End Class
''' <summary>
''' Slight class to wrap a DiscRecorder allowing it to be associated
''' with a combo box.
''' </summary>
Class ComboRecorderWrapper
Private ReadOnly recorder As DiscRecorder
Public Sub New(ByVal recorderParam As DiscRecorder)
recorder = recorderParam
End Sub
Public ReadOnly Property DiscRecorder() As DiscRecorder
Get
Return recorder
End Get
End Property
Public Overrides Function ToString() As String
Return String.Format("{0} ({1} {2} {3})", _
recorder.DriveLetter, recorder.Vendor, recorder.Product,
recorder.Revision)
End Function
End Class
Protected Overrides Sub OnClosing(ByVal e As
System.ComponentModel.CancelEventArgs)
' Don't close if burn in progress
If (burnInProgress) Then
e.Cancel = True
MessageBox.Show(Me, "A CD burn is currently in progress. Cancel
the burn before closing this application.", _
Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
Return
End If
' Clear up:
MyBase.OnClosing(e)
Cursor.Current = Cursors.WaitCursor
sbrMain.Text = "Closing IMAPI interface..."
redbookDiscMaster.Dispose()
discMaster.Dispose()
Cursor.Current = Cursors.Default
End Sub
Private Sub btnAdd_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnAdd.Click
Dim filePicker As OpenFileDialog = New OpenFileDialog()
filePicker.Filter = "Wave Files (*.WAV)|*.WAV|All Files (*.*)|*.*"
filePicker.DefaultExt = "WAV"
filePicker.Multiselect = True
If (filePicker.ShowDialog(Me) = DialogResult.OK) Then
Dim file As String
For Each file In filePicker.FileNames
' Confirm that this is a 16 bit, stereo, 44.1kHz Wave:
Dim reader As WaveStreamReader = New WaveStreamReader(file)
If ((reader.Channels = 2) And (reader.BitsPerSample = 16) And _
(reader.SamplingFrequency = 44100)) Then
' Add to the ListBox
Dim wrapper As FileWrapper = New FileWrapper(file,
reader.Length)
If Not (lstFiles.Items.Contains(wrapper)) Then
lstFiles.Items.Add(wrapper)
Else
MessageBox.Show(Me, String.Format("The file {0} has
already been added.", file), _
Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Else
MessageBox.Show(Me, String.Format("The file {0} is not a
suitable wave file. Only 16 bit stereo 44.1kHz PCM files
can be added.", file), _
Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Next
End If
End Sub
Private Sub btnRemove_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnRemove.Click
If (lstFiles.SelectedIndices.Count > 0) Then
Dim selected(lstFiles.SelectedIndices.Count - 1) As Object
lstFiles.SelectedItems.CopyTo(selected, 0)
Dim obj As Object
For Each obj In selected
lstFiles.Items.Remove(obj)
Next
End If
End Sub
Private Sub btnMoveUp_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnMoveUp.Click
If (lstFiles.SelectedIndices.Count > 0) Then
Dim selected(lstFiles.SelectedIndices.Count - 1) As Integer
lstFiles.SelectedIndices.CopyTo(selected, 0)
Dim i As Integer
For i = 0 To selected.Length - 1
If (selected(i) > 0) Then
Dim swap As Object = lstFiles.Items(selected(i) - 1)
lstFiles.Items(selected(i) - 1) =
lstFiles.Items(selected(i))
lstFiles.Items(selected(i)) = swap
lstFiles.SetSelected(selected(i) - 1, True)
End If
Next i
End If
End Sub
Private Sub btnMoveDown_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnMoveDown.Click
If (lstFiles.SelectedIndices.Count > 0) Then
Dim selected(lstFiles.SelectedIndices.Count - 1) As Integer
lstFiles.SelectedIndices.CopyTo(selected, 0)
Dim i As Integer
For i = 0 To selected.Length - 1
If (selected(i) < (lstFiles.Items.Count - 1)) Then
Dim swap As Object = lstFiles.Items(selected(i) + 1)
lstFiles.Items(selected(i) + 1) =
lstFiles.Items(selected(i))
lstFiles.Items(selected(i)) = swap
lstFiles.SetSelected(selected(i) + 1, True)
End If
Next i
End If
End Sub
Private Sub btnBurn_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnBurn.Click
If (burnInProgress) Then
cancel = True
Else
BurnCd(chkSimulate.Checked, chkEjectWhenComplete.Checked)
End If
End Sub
''' <summary>
''' Sets the application's mode
''' </summary>
''' <param name="burning"><c>true</c> if a burn is in progress</param>
Private Sub SetApplicationMode(ByVal burning As Boolean)
If (burning) Then
burnInProgress = True
cancel = False
btnBurn.Text = "Cancel"
btnMoveUp.Enabled = False
btnMoveDown.Enabled = False
btnAdd.Enabled = False
btnRemove.Enabled = False
lstFiles.Enabled = False
cboRecorder.Enabled = False
Else
burnInProgress = False
btnBurn.Text = "&Burn"
btnMoveUp.Enabled = True
btnMoveDown.Enabled = True
btnAdd.Enabled = True
btnRemove.Enabled = True
lstFiles.Enabled = True
cboRecorder.Enabled = True
End If
End Sub
''' <summary>
''' Checks the media in the drive.
''' </summary>
''' <returns></returns>
Private Function CheckMedia() As Boolean
Dim mediaOk As Boolean = False
sbrMain.Text = "Checking media in recorder..."
Cursor.Current = Cursors.WaitCursor
Dim recorder As DiscRecorder = cboRecorder.SelectedItem.DiscRecorder
recorder.OpenExclusive()
Dim media As MediaDetails = recorder.GetMediaDetails()
recorder.CloseExclusive()
Cursor.Current = Cursors.Default
If (media.MediaPresent) Then
If ( _
((media.MediaFlags & MEDIA_FLAGS.MEDIA_BLANK) =
MEDIA_FLAGS.MEDIA_BLANK) _
And ((media.MediaFlags & MEDIA_FLAGS.MEDIA_WRITABLE) =
MEDIA_FLAGS.MEDIA_WRITABLE) _
) Then
sbrMain.Text = "Preparing to burn CD."
mediaOk = True
Else
sbrMain.Text = "Media cannot be written to."
MessageBox.Show(Me, _
String.Format("The disc in drive {0} ({1}) is either not blank
or cannot be written to.", recorder.DriveLetter,
recorder.PnPID), _
Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Else
sbrMain.Text = "No media in drive."
MessageBox.Show(Me, _
String.Format("Please insert blank, writable media into drive {0}
({1})", recorder.DriveLetter, recorder.PnPID), _
Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Return mediaOk
End Function
''' <summary>
''' Burns the CD asynchronously
''' </summary>
''' <param name="simulate"><c>true</c> to simulate, <c>false</c> to really
burn</param>
''' <param name="ejectWhenComplete"><c>true</c> if the tray should be
ejected once
''' burn has finished.</param>
Private Sub BurnCd(ByVal simulate As Boolean, ByVal ejectWhenComplete As
Boolean)
' Check that we have media:
If (CheckMedia()) Then
' Determine number of progress chunks:
InitialiseProgress()
' Asynchronously invoke the creator
creator = New AudioCDCreator(discMaster, redbookDiscMaster)
Dim wrapper As FileWrapper
For Each wrapper In lstFiles.Items
creator.AddFile(wrapper.FileName)
Next
createCDHandler = AddressOf creator.CreateCD
Dim callback As AsyncCallback = AddressOf createCD_Complete
Dim ar As IAsyncResult = createCDHandler.BeginInvoke( _
simulate, ejectWhenComplete, callback, Nothing)
SetApplicationMode(True)
End If
End Sub
''' <summary>
''' Called when CD creation completes
''' </summary>
''' <param name="ar">Result of method call (none)</param>
Private Sub createCD_Complete(ByVal ar As IAsyncResult)
SetApplicationMode(False)
Dim ex As Exception
Try
createCDHandler.EndInvoke(ar)
Catch ex
MessageBox.Show(Me, String.Format("CD creation failed: Exception:
{0}", ex, _
Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation))
End Try
End Sub
Private Sub InitialiseProgress()
Dim totalBlocks As Integer = 0
Dim file As FileWrapper
For Each file In lstFiles.Items
' Add blocks twice; once for staging, once for burning
totalBlocks += (file.AudioBytes / redbookDiscMaster.AudioBlockSize)
* 2
Next
' Add 2 x 100 for preparing burn and closing disc
totalBlocks += 200
prgBurn.Maximum = totalBlocks
End Sub
Private Sub discMaster_AddProgress(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.ProgressEventArgs) Handles
discMaster.AddProgress
sbrMain.Text = String.Format("Adding {0} of {1}", args.Completed,
args.Total)
If (args.Completed < lastCompleted) Then
lastCompleted = 0
End If
prgBurn.Value += (args.Completed - lastCompleted)
lastCompleted = args.Completed
End Sub
Private Sub discMaster_BlockProgress(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.ProgressEventArgs) Handles
discMaster.BlockProgress
sbrMain.Text = String.Format("Block {0} of {1}", args.Completed,
args.Total)
If (preparingFlag) Then
prgBurn.Value += 100
preparingFlag = False
lastCompleted = 0
End If
If (args.Completed < lastCompleted) Then
lastCompleted = 0
End If
prgBurn.Value += (args.Completed - lastCompleted)
lastCompleted = args.Completed
End Sub
Private Sub discMaster_BurnComplete(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.CompletionStatusEventArgs) Handles
discMaster.BurnComplete
prgBurn.Value += 100
sbrMain.Text = String.Format("Burn Complete!")
End Sub
Private Sub discMaster_ClosingDisc(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.EstimatedTimeOperationEventArgs)
Handles discMaster.ClosingDisc
sbrMain.Text = String.Format("Closing disc (estimated time {0}s)...", _
args.EstimatedSeconds)
End Sub
Private Sub discMaster_EraseComplete(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.CompletionStatusEventArgs) Handles
discMaster.EraseComplete
sbrMain.Text = String.Format("Erase Complete!")
End Sub
Private Sub discMaster_PnPActivity(ByVal sender As Object, ByVal e As
System.EventArgs) Handles discMaster.PnPActivity
End Sub
Private Sub discMaster_PreparingBurn(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.EstimatedTimeOperationEventArgs)
Handles discMaster.PreparingBurn
sbrMain.Text = String.Format("Preparing to burn disc (estimated time
{0}s)...", _
args.EstimatedSeconds)
preparingFlag = True
End Sub
Private Sub discMaster_QueryCancel(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.QueryCancelEventArgs) Handles
discMaster.QueryCancel
args.Cancel = cancel
End Sub
Private Sub discMaster_TrackProgress(ByVal sender As Object, ByVal args As
vbAccelerator.Components.ImapiWrapper.ProgressEventArgs) Handles
discMaster.TrackProgress
If (args.Completed < args.Total) Then
sbrMain.Text = String.Format("Track {0} of {1}", args.Completed +
1, args.Total)
Else
sbrMain.Text = String.Format("Completed adding last track")
End If
End Sub
End Class
| |||
|
|
||||