|
PLAYER
In questa sezione tratteremo la parte
dettagliata del programma riguardante il riproduttore multimediale.
È stato
inserito un particolare oggetto chiamato AxWindowsMediaPlayer, vale a dire un
ActiveX per la gestione dei file multimediali. L'oggetto propone al
programmatore una serie di eventi e metodi tipici di Windows Media Player, per
esempio:
Immagini a tutto
schermo
Gestione del
volume
Bilanciamento casse
Ecc,ecc..
Detto questo ci basta generare l'evento
desiderato e gestirlo di conseguenza, ad esempio:
Private
Sub
canzoni_DoubleClick(ByVal
sender
As
Object,
ByVal
e
As
System.EventArgs)
Handles
canzoni.DoubleClick
Titolo.Text = "Titolo: "
Autore.Text = "Autore: "
Album.Text
= "Album: "
directory.SelectedIndex = canzoni.SelectedIndex
AxWindowsMediaPlayer1.URL = GetItemText(canzoni.SelectedIndex)
AxWindowsMediaPlayer1.newMedia(AxWindowsMediaPlayer1.URL)
cursore.Maximum =
CInt(AxWindowsMediaPlayer1.currentMedia.duration())
cursore.Value = 0
Timer_song.Start()
Timer_tag.Start()
playy.Visible =
False
pausee.Visible =
True
paused.Visible =
True
playd.Visible =
False
scorre.Text = " " & canzoni.SelectedItem
End
Sub
Private
Sub
canzoni_KeyPress(ByVal
sender
As
Object,
ByVal
e
As
System.Windows.Forms.KeyPressEventArgs)
Handles
canzoni.KeyPress
If
e.KeyChar = Microsoft.VisualBasic.ChrW(13)
Then
Titolo.Text =
"Titolo: "
Autore.Text = "Autore: "
Album.Text = "Album: "
directory.SelectedIndex = canzoni.SelectedIndex
AxWindowsMediaPlayer1.URL = GetItemText(canzoni.SelectedIndex)
AxWindowsMediaPlayer1.newMedia(AxWindowsMediaPlayer1.URL)
cursore.Maximum =
CInt(AxWindowsMediaPlayer1.currentMedia.duration())
cursore.Value = 0
Timer_song.Start()
Timer_tag.Start()
playy.Visible =
False
pausee.Visible =
True
paused.Visible =
True
playd.Visible =
False
scorre.Text = " " & canzoni.SelectedItem
End
If
End
Sub
Il codice
di cui sopra serve per la gestione delle canzoni selezionate da una listbox
chiamata canzoni. Tenendo
conto che l'oggetto ActiveX è ingordo di suonare solo percorsi standard, è
necessario sincronizzare la lista canzoni con una lista directory col seguente
metodo:
directory.SelectedIndex
= canzoni.SelectedIndex
il resto
del codice è semplice, queste due righe servono appunto a riprodurre il file
selezionato:
AxWindowsMediaPlayer1.URL
= GetItemText(canzoni.SelectedIndex)
AxWindowsMediaPlayer1.newMedia(AxWindowsMediaPlayer1.URL)
È
possibile notare un metodo particolare associato alla list box : GetItemText. Il
metodo restituisce il testo associato all'indice della lista box che gli viene
passato come parametro. Il procedimento come si può vedere non è difficile
bisogna solo entrare nell'ottica di gestione di ogni singolo evento che l'utente
può generare.La parte più complessa è stata la gestione del tempo e del cursore
di posizione. Il valore del cursore di posizione (da qui in poi seek) dove
assumere il valore della posizione della canzone in quell'istante.
Ecco il
codice:
#Region
"Tempo traccia"
Private
Sub
Timer_song_Tick(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
Timer_song.Tick
total =
CInt(AxWindowsMediaPlayer1.Ctlcontrols.currentPosition())
cursore.Maximum =
CInt(AxWindowsMediaPlayer1.currentMedia.duration())
cursore.Value = total
second =
CInt(AxWindowsMediaPlayer1.Ctlcontrols.currentPosition())
ore =
second \ 3600
min =
second \ 60
sec =
second - (min * 60)
ore = 0
If
sec = "-1"
Then
sec = "0"
If min >= 60
Then
min = min - 60
ore = ore + 1
End
If
If
sec < 10
And
min < 10
Then
tempo.Text =
CStr(canzoni.SelectedItem)
& " " & "0" & ore & ":0" & min & ":0" & sec
ElseIf
sec >= 10
And
min >= 10
Then
tempo.Text =
CStr(canzoni.SelectedItem)
& " " & "0" & ore & ":" & min & ":" & sec
ElseIf
sec < 10
And
min >= 10
Then
tempo.Text =
CStr(canzoni.SelectedItem)
& " " & "0" & ore & ":" & min & ":0" & sec
ElseIf
sec >= 10
And
min < 10
Then
tempo.Text =
CStr(canzoni.SelectedItem)
& " " & "0" & ore & ":0" & min & ":" & sec
End
If
End
Sub
#End
Region
Come
intercettare la posizione della canzone?
L'activeX
ci viene in aiuto:
cursore.value=AxWindowsMediaPlayer.CurrentMedia.CurrentPosition
La
proprietà CurrentMedia ci consente di intercettare il file che si sta
utilizzando e CurrentPosition catture la sua posizione espressi in secondi
dall'inizio del file.Date queste brevi premesse parleremo ora delle parti più
interessanti del programma dividendole in parte Multimediale e Browser. Perchè
all'inizio e alla fine di ogni blocco di codice compare
#Region
"[testo]"
#End
Region
?
Questa semplice istruzione
permette di racchiuder il codice un un'area facilmente riconoscibile grazie la
testo che noi scriviamo tra i due apici (al posto della scritta [testo]). In
pratica è utile per individuare le parti del programma o che non funzionano
correttamente o da cambiare, oppure semplicemente per organizzare il codice in
modo che sia più comprensibile. Di
seguito viene commentato tutto l'algoritmo utilizzato per aprire i file
multimediali:
Private
Sub
MenuItem2_Click(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
MenuItem2.Click
On
Error
GoTo
Fix
OpenFileDialog2.Filter = "ALL MUSIC FILES|*.mp3;*.wma;*.wave;*.wav;*.mid;*.midi;*.cda|Video
Formats|*.avi;*.divx; *.xvid; *.vob;*.mpeg"
Il blocco sopra definisce semplicemente quali tipi di file devono essere
riprodotti
OpenFileDialog2.ShowDialog()
Viene mostrata la finestra di apertura
If
OpenFileDialog2.FileNames.Length > 0
Then
Per avere la selezione multipla delle canzoni basta utilizzare la proprietà
filenames
directory.Items.Clear()
canzoni.Items.Clear()
Me.AxWindowsMediaPlayer1.Ctlcontrols.stop()
Qui vengono aggiornate le liste con le nuove canzoni cancellando le vecchie. La
proprietà filenames mi restituisce una matrice che è quindi necessario scorrere
vere potere "utilizzare" tutte le voci in essa contenute, ecco come:
Dim
canzone
As
String
For
Each
canzone
In
OpenFileDialog2.FileNames
Dim
file
As
String
= canzone
directory.Items.Add(file)
Le seguenti variabile mi servono per gestire la visualizzazione del solo titolo
della canzone
Dim
s
As
String
Dim
s2
As
Object
Dim
sR
As
String
s =
canzone
dichiarazione
della canzone(in realtà si tratta della path)
sR = StrReverse(s)
Questo
blocco mi rovescia la stringa
s2 =
s.Substring(Len(s) - sR.IndexOf("\"))
Dalla stringa rovesciata posso prelevare tutto ciò che è dopo la \ (vale a dire
il titolo della canzone più la sua estensione), e l'aggiungo alle altre
canzoni.Items.Add(s2)
ripetuto
per tutte le voci della matrice
canzoni.SelectedItem = s2
OpenFileDialog2.FileName = ""
Next
End
If
Qui
sotto vengono azzerate le etichette per la visualizzazione dei tag:
Titolo.Text = "Titolo: "
Autore.Text = "Autore: "
Album.Text
= "Album: "
Seleziono poi la prima voce:
directory.SelectedIndex = 0
canzoni.SelectedIndex = 0
Sincronizzo le due liste:
canzoni.SelectedIndex
= directory.SelectedIndex
Visualizzo i pulsanti che mi interessano
pausee.Visible =
False
playy.Visible =
True
playd.Visible =
True
paused.Visible =
False
Fix:
Exit
Sub
End
Sub
La parte che segue è un
commento allo sviluppo del movimento della barra di seek
#Region
"Barra di scorrimento"
Private
Sub
cursore_Scroll(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
cursore.Scroll
'Decido il punto della canzone
AxWindowsMediaPlayer1.Ctlcontrols.currentPosition = cursore.Value
End
Sub
Private
Sub
cursore_ValueChanged(ByVal
sender
As
Object,
ByVal
e
As
System.EventArgs)
Handles
cursore.ValueChanged
If
cursore.Value = cursore.Maximum - 1
Then
If
canzoni.SelectedIndex = canzoni.Items.Count
Then
'se è l'ultimo elemento mi fermo
Me.AxWindowsMediaPlayer1.Ctlcontrols.stop()
Me.AxWindowsMediaPlayer1.URL
= ""
Me.AxWindowsMediaPlayer1.newMedia("")
End
If
If
caso.Checked =
True
Then
v = objRandom.Next(0, (directory.Items.Count))
directory.SelectedIndex = v
v = objRandom.Next(0, (canzoni.Items.Count))
canzoni.SelectedIndex = v
directory.SelectedIndex = canzoni.SelectedIndex
Me.AxWindowsMediaPlayer1.URL
= GetItemText(directory.SelectedIndex)
Me.AxWindowsMediaPlayer1.newMedia(Me.AxWindowsMediaPlayer1.URL)
scorre.Text = canzoni.SelectedItem
End
If
If
directory.SelectedIndex < directory.Items.Count - 1
Then
directory.SelectedIndex = canzoni.SelectedIndex
directory.SelectedIndex = directory.SelectedIndex + 1
canzoni.SelectedIndex = canzoni.SelectedIndex + 1
directory.SelectedIndex = canzoni.SelectedIndex
AxWindowsMediaPlayer1.URL = GetItemText(directory.SelectedIndex)
AxWindowsMediaPlayer1.newMedia(AxWindowsMediaPlayer1.URL)
scorre.Text = canzoni.SelectedItem
End
If
End
If
voice.Visible =
False
mute.Visible =
True
End
Sub
#End
Region
Questa
parte di codice, fa questa semplice operazione: ogni volta che la posizione
della barra seek cambia, viene controllata se questo valore corrisponde al
valore massimo meno uno della barra stessa, in caso affermativo, viene
controllato se la voce riproduzione casuale è selezionata, se si, si riproduce
casualmente un brano, altrimenti si somma uno si alla lista delle path, sia alla
lista dei titoli delle canzoni, le sincronizzo col solito metodo, poi le suono.
Ogni player che si rispetti permette anche la creazione delle plyelist,
ovviamente il nostro non poteva essere da meno.Per
farle abbiamo deciso di utilizzare una potente tecnologia messa a disposizione
dallo stesso ambiente di sviluppo: XML
Ecco il
metodo utilizzato per scrivere un file XML:
Private
Sub
Write_XML()
Dim
XMLobj
As
Xml.XmlTextWriter
Dim
ue
As
New
System.[Text].UnicodeEncoding
XMLobj =
New
Xml.XmlTextWriter(Application.StartupPath & "\" & "Playlist" & "\" & titololista.Text
& ".xml", ue)
XMLobj.Formatting = Xml.Formatting.Indented
XMLobj.Indentation = 3
XMLobj.WriteStartDocument()
XMLobj.WriteStartElement("List")
Dim
i
As
Integer
For
i = 0
To
directory.Items.Count - 1
XMLobj.WriteStartElement("MP3_File")
Dim
temp
As
String
= ""
Dim
temp1
As
String
= ""
directory.SetSelected(i,
True)
canzoni.SetSelected(i,
True)
temp = directory.SelectedItem
temp1 = canzoni.SelectedItem
XMLobj.WriteAttributeString("File", temp)
XMLobj.WriteAttributeString("Title", temp1)
XMLobj.WriteEndElement()
Next
XMLobj.WriteEndElement()
XMLobj.Close()
End
Sub
Il
codice sovrastante ha come effetto un file XML strutturato così:

Il file ha una struttura
molto semplice: nel tag file viene scritto il percorso, nel tag titolo il solo
titolo del brano o del video in modo che in lettura siano facilmente
recuperabili tramite il codice che segue:
Private
Sub
Read_XML()
Dim
XMLReader
As
Xml.XmlReader
XMLReader =
New
Xml.XmlTextReader(fl.Path & "\" & fl.Text)
While
XMLReader.Read
Select
Case
XMLReader.NodeType
Case
Xml.XmlNodeType.Element
If
XMLReader.AttributeCount > 0
Then
While
XMLReader.MoveToNextAttribute
If
XMLReader.Name = "File"
Then
directory.Items.Add(XMLReader.Value)
ElseIf
XMLReader.Name = "Title"
Then
canzoni.Items.Add(XMLReader.Value)
Else
' Do Nothing
End
If
End
While
End
If
End
Select
End
While
XMLReader.Close()
playy.Visible =
False
'play
pausee.Visible =
True
'pausa
paused.Visible =
True
'pausa
playd.Visible =
False
'play
End
Sub
In questa
funzione viene letto campo per campo e aggiornate le liste di conseguenza. Ogni
lista viene aggiornata con la voce opportuna. Abbiamo optato per la scelta di
questo strumento per la sua semplicità di utilizzo per l'immediatezza della
comprensione. La regolazione del volume è stato per una intera settimana il
nostro maggiore grattacapo perché non riuscivamo a gestirlo in tempo reale poi
abbiamo deciso di utilizzare una variabile per intercettare il valore del
cursore utilizzato per la regolazione del volume e assegnare poi questo valore
alla proprietà volume dell'ActiveX.
Private
Sub
volume_Scroll(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
volume.Scroll
Dim
vo
As
Integer
'variabile per il volume
'
vo =
volume.Value
'Settaggio volume
Me.AxWindowsMediaPlayer1.settings.volume
= vo
Dim
foo
As
Integer
On
Error
GoTo
Fix
'valore del volume
foo =
volume.Value
tivol.Text = "Volume: " & foo & "%"
Fix:
Exit
Sub
Idem
dicasi per il bilanciamento delle casse:
Abbiamo settato prima il valore minimo (-500) e poi il valore massimo (500) e
poi abbiamo intercettato il valore del cursore utilizzato per la gestione del
bilanciamento e assegnato questo valore alla proprietà balance dell'ActiveX.
Private
Sub
bil_Scroll(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
bil.Scroll
On
Error
GoTo
Fix
Dim
bila
As
Integer
bila = bil.Value * (-1)
If
bil.Value > -500
And
bil.Value < 500
Then
tibil.Text = "Bilanciamento: Centro"
End
If
If
bil.Value < -500
Then
Me.AxWindowsMediaPlayer1.settings.balance
=
Me.AxWindowsMediaPlayer1.settings.balance
/ 50
tibil.Text = "Bilanciamento: Sinistra"
End
If
If
bil.Value > 500
Then
Me.AxWindowsMediaPlayer1.settings.balance
=
Me.AxWindowsMediaPlayer1.settings.balance
/ 50
tibil.Text = "Bilanciamento: Destra"
End
If
Me.AxWindowsMediaPlayer1.settings.balance
= bila
Fix:
Exit
Sub
End
Sub
Un altro problema che ci siamo posti è sto quello di evitare di usare la solita
forma della finestra di programmazione. A questo riguardo ci siamo serviti di
una libreria per il disegno 2d
Imports
System.Drawing.Drawing2D
Istanziando
poi questa libreria abbiamo ottenuto una form non più rettangolare
Private
Sub SetFormRegion()
'Preferisco non esprimermi
gp.AddLine(16,
0, Width - 32, 0)
gp.AddArc(Width - 32, 0, 32, 32, 270, 90)
gp.AddLine(Width, 16, Width, Height - 32)
gp.AddArc(Width - 32, Height - 32, 32, 32, 0, 90)
gp.AddLine(Width - 32, Height, 16, Height)
gp.AddArc(0, Height - 32, 32, 32, 90, 90)
gp.AddLine(0, Height - 32, 0, 32)
gp.AddArc(0, 0, 32, 32, 180, 90)
gp.CloseFigure()
Me.Region
=
New
Region(gp)
End
Sub
Poi basta chiamare questa
funzione (call SetFormRegion) quando lo si ritiene necessario (preferibilmente
nell'evento load del form). Qui di seguito viene riportata la procedura per
avere form con forme molto diverse:
La creazione di form non
rettangolari è costituita da due parti: la creazione del form con la forma
desiderata e la creazione della logica di programmazione per consentire lo
spostamento e la chiusura del form. Questa seconda fase è necessaria poiché un
form con una forma personalizzata non ha barra del titolo e non dispone di
funzionalità intrinseche, come la possibilità di spostamento sullo schermo e di
chiusura. È pertanto necessario scrivere il codice appropriato per replicare
queste funzionalità. La creazione di un form non rettangolare è costituita da
tre fasi: Creare una bitmap con la funzione di superficie del form. Si tratta in
effetti di ritagliare la forma desiderata da un rettangolo. Creare un
progetto di applicazione Windows e impostarne le proprietà in modo da eliminare
la barra del titolo e utilizzare la bitmap come sfondo del form. Immettere
il codice per ricreare le funzionalità fornite dalla barra del titolo, ad
esempio lo spostamento e la chiusura del form.
Per creare un form con forma
personalizzata
Creare una bitmap di forma non
rettangolare di un colore con uno sfondo in un altro colore. Utilizzare il
programma di disegno desiderato. Poiché la forma disegnata corrisponderà al form,
realizzare un disegno di dimensioni sufficientemente grandi.
Nota:
Scegliere
un colore di sfondo facile da ricordare, come il blu, poiché sarà importante in
seguito.
Nella finestra Proprietà:
Impostare la proprietà FormBorderStyle su None. Viene rimossa la barra del
titolo dal form. Vengono anche rimosse le funzionalità fornite dalla barra del
titolo, come la possibilità di chiudere e di spostare il form. Questo problema
verrà risolto nel codice in un secondo momento. Impostare la proprietà
BackgroundImage del form sul file bitmap creato in precedenza.Non occorre
aggiungere il file al sistema del progetto, poiché questa operazione è
automatica quando si specifica il file come immagine di sfondo. Con questa
proprietà l'immagine bitmap viene impostata come sfondo del form. Quando la si
utilizza con la proprietà TransparencyKey specificata di seguito, questa
proprietà definisce la forma del form. Impostare la proprietà TransparencyKey
sul colore di sfondo del file bitmap. Con questa proprietà si segnala
all'applicazione quali parti del form saranno trasparenti.
Nota:
È possibile che sui monitor impostati con un'intensità colore
superiore a 24 bit si presentino problemi di visualizzazione, con la conseguenza
che determinate parti del form non appaiano trasparenti nonostante
l'impostazione della proprietà TransparencyKey. Per evitare questo problema,
accertarsi che l'intensità colore del monitor sia impostata su un valore
inferiore a 24 bit nel pannello di controllo Schermo.
Nello sviluppo di
applicazioni che prevedono l'applicazione della trasparenza, è opportuno
informare gli utenti in merito a questo inconveniente.
Per scrivere il codice per
chiudere il form
Aggiungere un controllo Button
al form. Aggiungere codice per consentire all'utente di chiudere il form
richiamando il metodo Close. Nell'esempio seguente viene illustrato come
aggiungere un pulsante mediante la scelta del quale sia possibile chiudere il
form.
Private
Sub Button1_Click(ByVal sender As System.Object, _
ByVal e
As System.EventArgs) Handles Button1.Click
Me.Close()
End Sub
Per scrivere il codice per
spostare il form (facoltativo)
Creare una routine per
spostare il form quando lo si trascina. Immettere codice simile a quello
riportato di seguito per creare un nuovo oggetto Point. Questo codice avrà la
funzione di una variabile quando si calcola come spostare il form. Il campo
isMouseDown viene utilizzato per tenere traccia della pressione del pulsante del
mouse. Il form verrà spostato solo mentre si tiene premuto il pulsante del
mouse.
' Visual
Basic
Private
mouseOffset As Point
Private
isMouseDown As Boolean = False
' Visual
Basic
Private
Sub Form1_MouseDown(ByVal sender As Object, _
ByVal
e As MouseEventArgs) Handles MyBase.MouseDown
Dim
xOffset As Integer
Dim
yOffset As Integer
If
e.Button = MouseButtons.Left Then
xOffset = -e.X - SystemInformation.FrameBorderSize.Width
yOffset = -e.Y - SystemInformation.CaptionHeight - _
SystemInformation.FrameBorderSize.Height
mouseOffset = New Point(xOffset, yOffset)
isMouseDown = True
End If
End Sub
Creare un gestore eventi per
l'evento MouseMove del form.
Immettere codice simile a
quello riportato di seguito. Quando si fa clic sul pulsante sinistro e si
trascina il mouse, la proprietà Location del form viene impostata sulla nuova
posizione.
' Visual
Basic
Private
Sub Form1_MouseMove(ByVal sender As Object, _
ByVal
e As MouseEventArgs) Handles MyBase.MouseMove
If
isMouseDown Then
Dim mousePos As Point = Control.MousePosition
mousePos.Offset(mouseOffset.X, mouseOffset.Y)
Location = mousePos
End If
End Sub
Creare un
gestore eventi per l'evento MouseUp del form.
Immettere codice simile a quello riportato di seguito.
Private
Sub Form1_MouseUp(ByVal sender As Object, _
ByVal
e As MouseEventArgs) Handles MyBase.MouseUp
'
Changes the isMouseDown field so that the form does
' not
move unless the user is pressing the left mouse button.
If
e.Button = MouseButtons.Left Then
isMouseDown = False
End If
End Sub
Il
programma prevede anche la lettura dei tag.Questo
avviene tramite dei metodi dell'ActiveX (GetItemByInfo) e passandogli per
parametro il nome del tag che vogliamo leggere, questa informazione ci verrà
restituita sottoforma di stringhe. Per visualizzarle basterà abbinare le
stringhe a un qualsiasi oggetto che preveda un testo (es. textbox,label ecc.)
Ecco il
risultato di tutto

|