miércoles, 17 de junio de 2015

COMPONENTES O CONTROLES DE REPRODUCTOR DE AUDIO PARA UTILIZARLO EN VISUAL BASIC.NET





Reproducción de sonido por medio del control de multimedia




El control de multimedia posee una botonera con los clásicos botones de reproducción: play, stop, pause, adelantar, etc..




Si bien en este ejemplo se utilizará el control de multimedia , cabe aclarar que podemos ejecutar todas las funciones enteramente con código sin utilizar la interface del control, y crear nosotros una interface propia, ya que la que presenta el control no es muy estética que digamos. Esto se logra ocultando el control con la propiedad visible del mismo en False y creando nuestra interface y manipular el mismo mediante código.

Lo primero que se debe tener en cuenta para utilizar el control de multimedia es que antes de reproducir un archivo de sonido debemos indicarle al mismo que tipo de archivo se trata, utilizando para ello la propiedad DevaiceType.

Propiedad DevaiceType


Esta propiedad que lleva un dato de tipo string, debemos indicarle los siguientes valores, dependiendo del archivo a reproducir:
·        WaveAudio : Para archivos con extención wav.
·        Sequencer: archivos midi
·        Cdaudio: archivos de musica de cd
·        Avivideo: archivos de video con extención avi

Para definir mediante código en tiempo de ejecución el dispositivo que se utilizará se haría de la siguiente forma:
Esto prepara al control de multimedia para reproducir un cd de música


MMControl1.DeviceType = "cdaudio"  



Cargar un archivo para reproducción

Luego de definir el tipo de dispositivo a utilizar, debemos indicarle al control cual es el archivo que queremos abrir, indicando el path o ruta completa del mismo mediante la propiedad FileName. ejemplo:


1.  Option Explicit  
2.    
3.  Private Sub Form_Load()  
4.        
5.      With MMControl1  
6.         .FileName = "c:\windows\archivo.wav"  
7.         .Command = "open"  
8.      End With  
9.    
10. End Sub  


Importante Definiendo el archivo de esta manera, no haremos que se comience la reproducción, solo lo estamos cargando en la memoria para poder utilizarlo. Primero indicamos la ruta del archivo y luego mediante una propiedad que veremos en detalle en las próximas líneas, llamada Command, le pasamos el valor "Open" para que abra el archivo indicado y lo cargue en la memoria.


Simple código fuente para utilizar el control Windows Media player y poder reproducir archivos de multimedia ( Mp3, avi, mpg, wav, etc..)




EJEMPLOS:



Como usar el control Activex Windows Media player desde visual basic ( wmp.dll )



Este código fuente para descargar, usa el control Windows Media para reproducir archivos de multimedia ( Mp3, Wav, Avi, Mpg etc..)











  • Tiene un menú de reproducción para usar los comandos básicos ( Play, Stop, Pause, Atrás, adelante )



  • Tiene otro menú con algunas otras opciones : para establecer el estilo de visualización del control ( Compacto, invisible, completo, hacer un Stretch del video ), para establecer el volumen , mute, hacer un Loop.



  • Tiene otro formulario para añadir un PlayList o lista de reproducción simple nada del otro mundo . ( usando los objetos o colecciones currentPlaylist y mediaCollection )






También tiene otro form, que visualiza en un ListView con dos columnas ( Atributo / valor ), con los datos del archivo de medios que se está reproduciendo actualmente, por ejemplo :
·        El author ( atributo Author )
·        El título ( Atributo Title )
·        La ruta ( Source Url )
·        La duración ( Duration )
·        El bitrate ( Atributo Bitrate )
·        El tamaño del archivo ( Filesize )
·        El tipo si es Audio / Video ( MediaType )

  • El formato ( FileType 



Toda esta información, accediendo mediante la colección currentMedia, usando los métodos getAttributeName y getItemInfo para recuperar dichos valores





Por último, tiene un Statusbar, con dos paneles, en uno se visualiza el estado actual del archivo que se está Reproduciendo (si está detenido, si está en play etc... ), y otro panel para ver el tipo de medio (Audio / video )
Se le pueden agregar muchas opciones, por ejemplo, agregarle código para hacer un drag drop de archivos hacia el playlist , ponerle controles de reproducción propios, etc..

Nota: en el ejemplo, para abrir y cargar un archivo para la reproducción, se crea una lista de reproducción. Pero si no es necesario manejar un playlist , se puede cargar un archivo y reproducirlo, usando la propiedad Url , e indicándole el path , por ejemplo :




WindowsMediaPlayer1.URL = "c:\a.mp3"





Este ejemplo usa el Api mciExecute para reproducir archivos Wav, Mp3 y Midi.


Parece un poco largo el código, pero en realidad es corto ya que la mayoría es para habilitar o deshabilitar los controles de Play, Pause y Stop..
Para el ejemplo colocar los siguientes controles en un form:
·        4 CommandButton: Command1 (Play) , Command2(stop) , Command3 (Pause) y Command4 (Abrir archivo)
·        Un Commondialog1

·        Un Label1: Para mostrar el Path


Código en un formulario



1.  Option Explicit  
2.  'Función Api GetShortPathName para obtener _  
3.  los paths de los archivos en formato corto  
4.  Private Declare Function GetShortPathName _  
5.      Lib "kernel32" _  
6.      Alias "GetShortPathNameA" ( _  
7.          ByVal lpszLongPath As String, _  
8.          ByVal lpszShortPath As String, _  
9.          ByVal lBuffer As LongAs Long  
10.   
11. 'Función Api mciExecute para reproducir los archivos de música  
12. Private Declare Function mciExecute _  
13.     Lib "winmm.dll" ( _  
14.         ByVal lpstrCommand As StringAs Long  
15. Dim ret As Long, path As String  
16.   
17. 'Le pasamos el comando Play  
18. Private Sub Command1_Click()  
19.     ejecutar ("Play ")  
20.     Habilitar "Play"  
21. End Sub  
22.   
23. Private Sub Command2_Click()  
24.     'Le pasamos el comando Stop  
25.     ejecutar ("Stop ")  
26.     Habilitar "Stop"  
27. End Sub  
28.   
29. 'Le pasamos el comando Pause  
30. Private Sub Command3_Click()  
31.     ejecutar ("Pause ")  
32.     Habilitar "Pause"  
33. End Sub  
34.   
35. 'Le pasamos el comando Close a MciExecute para cerrar el dispositivo  
36. Private Sub Form_Unload(Cancel As Integer)  
37.     mciExecute "Close All"  
38. End Sub  
39.   
40. 'Botón para abrir seleccionar los archivos de audio  
41. Private Sub Command4_Click()  
42.     With CommonDialog1  
43.         .Filter = "Archivos Wav|*.wav|Archivos Mp3|*.mp3|Archivos MIDI|*.mid"  
44.         .ShowOpen  
45.         If .FileName = "" Then  
46.             Habilitar "Iniciar"  
47.             Exit Sub  
48.         Else  
49.             'Le pasamos a la sub que obtiene con _  
50.             el Api GetShortPathName el nombre corto del archivo  
51.             PathCorto .FileName  
52.             Label1 = .FileName  
53.             'cerramos todo  
54.             mciExecute "Close All"  
55.             'Para Habilitar y deshabilitar botones  
56.             Habilitar "Stop"  
57.         End If  
58.     End With  
59. End Sub  
60.   
61. 'Sub que obtiene el path corto del archivo a reproducir  
62. Private Sub PathCorto(archivo As String)  
63. Dim temp As String * 250 'Buffer  
64.     path = String(255, 0)  
65.     'Obtenemos el Path corto  
66.     ret = GetShortPathName(archivo, temp, 164)  
67.     'Sacamos los nulos al path  
68.     path = Replace(temp, Chr(0), "")  
69. End Sub  
70.   
71. 'Procedimiento que ejecuta el comando con el Api mciExecute  
72. '************************************************************  
73. Private Sub ejecutar(comando As String)  
74.     If path = "" Then MsgBox "Error", vbCritical: Exit Sub  
75.     'Llamamos a mciExecute pasandole un string que tiene el comando y la ruta  
76.   
77.     mciExecute comando & path  
78.   
79. End Sub  
80.   
81. Private Sub Form_Load()  
82.     Command1.Caption = "Play >>"  
83.     Command2.Caption = "Stop ||||"  
84.     Command3.Caption = "Pause ||"  
85.     Command4.Caption = ":::: Abrir archivo de música ::::"  
86.     Habilitar "Iniciar"  
87.     Label1 = "": Label1.AutoSize = True  
88. End Sub  
89.   
90. Private Sub Habilitar(Accion As String)  
91.     Select Case Accion  
92.         Case "Iniciar"  
93.             Command1.Enabled = False  
94.             Command2.Enabled = False  
95.             Command3.Enabled = False  
96.         Case "Play"  
97.             Command1.Enabled = False  
98.             Command2.Enabled = True  
99.             Command3.Enabled = True  
100.                 Case "Stop"  
101.                     Command1.Enabled = True  
102.                     Command2.Enabled = False  
103.                     Command3.Enabled = False  
104.                 Case "Pause"  
105.                     Command1.Enabled = True  
106.                     Command2.Enabled = True  
107.                     Command3.Enabled = False  
108.             End Select  
109.         End Sub  

-----------------------------------------------------------------------


REPRODUCTOR DE WINDOWS MEDIA PLAYER PARA VISUAL BASIC.NET


Cómo: Incrustar el Reproductor de Windows Media en un formulario


Puede incrustar el Reproductor de Windows Media en un formulario Windows Forms para proporcionar elementos multimedia en la aplicación. Primero debe agregar el control COM del Reproductor de Windows Media al cuadro de herramientas y, a continuación, puede agregar el control a la aplicación.

Para agregar el control del Reproductor de Windows Media al cuadro de herramientas

  1. En el menú Archivo, haga clic en Nuevo proyecto.
  2. En el cuadro de diálogo Nuevo proyecto, haga clic en Aplicación de Windows Forms y luego en Aceptar.
    Se abre un nuevo proyecto de formularios Windows Forms.
  3. Haga clic con el botón secundario en el Cuadro de herramientas y haga clic en Elegir elementos
  4. Se abre el cuadro de diálogo Personalizar elementos del cuadro de herramientas.
  5. En la ficha Componentes COM, active la casilla Reproductor de Windows Media y, a continuación, haga clic en Aceptar.
  6. El control del Reproductor de Windows Media aparece en la ficha Cuadro de herramientas actual.
    Al agregar el control del Reproductor de Windows Media al Cuadro de herramientas, Visual Studio se agregan automáticamente referencias a dos bibliotecas: AxWMPLib y WMPLib. El paso siguiente consiste en agregar el control al formulario Windows Forms.

    Para agregar el control del Reproductor de Windows Media a un formulario Windows Forms

    1. Arrastre el control del Reproductor de Windows Media desde el Cuadro de herramientas hasta el formulario Windows Forms.
    2. En la ventana Propiedades, establezca la propiedad Dock en Fill. Para ello, haga clic en el cuadrado del centro.
    3. Haga doble clic en la barra de título del formulario para agregar el evento Load predeterminado en el editor de código.
    4. Agregue el código siguiente al controlador de eventos Form_Load para cargar un vídeo cuando se abra la aplicación.
    5. axWindowsMediaPlayer1.URL =
      @"http://go.microsoft.com/fwlink/?LinkId=95772";
      Este código establece la dirección URL del Reproductor de Windows Media en el archivo multimedia que ha especificado. El Reproductor de Windows Media empezará la reproducción de forma automática al establecer la propiedad URL porque el valor predeterminado de la propiedad autoStart es true.
    6. Presione F5 para ejecutar el código.
    7. Cuando la aplicación se abra, cambie el tamaño del formulario a pantalla completa haciendo doble clic en la barra de título del mismo.
    __________________________________________________________________

    SS-TAB 

Descripción del control

El Control Tabbed Dialog, también denominado SStab, que es muy similar al que nos presenta el cuadro de diálogo de propiedades de pantalla de windows cuando presionamos el botón derecho en el escritorio, consta de una interface con "pestañas", en la que cada una de ellas nos sirve para mostrar una opción determinada.




Cada pestaña puede contener sus propios controles y es una buena opción para presentar interfaces de una forma organizada. Cada pestaña actúa como contenedor de los controles que insertamos
Para incorporarlo a un proyecto lo debemos agregar o añadir bajo el nombre de Microsoft Tabbed Dialog control 6.0 desde la opción agregar componentes del menú de Visual Basic como muestra el siguiente gráfico:

Ventana de componentes de Visual basic.






Una ves añadido el control , se visualizará con el siguiente ícono:





Página de propiedades

Para acceder a las propiedades mas importantes del SStab , podemos utilizar el cuadro de diálogo "Custom" o personalizado, desde la ventana de propiedades de visual basic.
O también para acceder a dicha ventana podemos seleccionar el Tabbed Dialog y con el botón derecho elegir la opción Propiedades
En cada pestaña del control podemos colocar controles y estos funcionarán de manera normal, como lo hacen siempre, y al colocarlos en cada pestaña estarán contenidos dentro de estas.
Para insertar un control dentro de una pestaña solo hay que dibujarlo dentro y ya quedará contenido, de igual manera a como se hace en un control PictureBox por ejemplo.
Apenas insertamos el TabbedDialog en el formulario, este presenta 3 pestañas por defecto.
Para agregar o especificar la cantidad de Tabs que queremos utilizar para el , se puede hacer desde el cuadro de diálogo "Custom" en la opción "contador" como está en la imagen:




También se puede especificar las pestañas a utilizar, desde la ventana de propiedades de Visual Basic en la propiedad "Tabs" indicando un valor numérico para el mismo.
importanete: Si nosotros hemos agregado pestañas al control y le hemos insertado controles a alguna de ellas y luego queremos eliminar alguna pestaña, hay que anteriormente retirar los controles de las pestañas o eliminarlos, ya que si están contenidos no lo permite.

Propiedad Orientation y Style


Estas son dos propiedades importantes referidas al aspecto gráfico del Tabbed Dialog y a su disposición.

Propiedad Style
Esta puede tener 2 valores, ssStylePropertyPage o ssStyleTabbedDialog
Una vista de estas 2 propiedades:





La propiedad Orientation
Establece la orientación y disposición de las pestañas en el control, es decir la alineación.
Los valores que puede tener son ssTabOrientationTop (pestañas arriba), ssTabOrientationLeft (Izquierda), ssTabOrientationRight (derecha) y ssTabOrientationBottom (abajo)
Una vista de estas de estas cuatro opciones:




Nota: Para poder utilizar las pestañas con la propiedad Orientation en ssTabOrientationLeft y ssTabOrientationRight, el tipo de fuente que debe tener configurado el TabbedDialog debe ser una fuente de tipo TrueType, de lo contrario se visualizará de forma incorrecta.


Otras propiedades del Tabbed Dialog


TabsPerRow

Devuelve o establece el número de fichas de cada fila de un control SSTab.
Puede usar esta propiedad junto con la propiedad Tabs en tiempo de diseño para determinar el número de filas que aparecen en el control. En tiempo de ejecución, utilice la propiedad Rows.

TabHeight

Devuelve o establece el alto de todas las fichas de un control SSTab.

TabMaxWidth

Devuelve o establece el ancho máximo de cada ficha
Nota : Cuando el valor de la propiedad Style es ssStyleTabbedDialog y el de TabMaxWidth es cero (0), el control SSTab ajusta automáticamente el tamaño de las fichas, según el valor de la propiedad TabsPerRow, para ajustarlas por igual al control.
Si selecciona el valor ssStylePropertyPage en la propiedad Style, se pasará por alto la propiedad TabMaxWidth. En este caso, el ancho de cada ficha se ajusta automáticamente a la longitud del texto de la propiedad TabCaption.

WordWrap

Devuelve o establece un valor que indica si el texto de cada ficha continúa en la línea siguiente cuando es demasiado largo y no cabe horizontalmente en una ficha de un control tabbed dialog.
Comentarios
Puede usar la propiedad WordWrap para determinar la forma en que el control SSTab muestra el texto en cada ficha. Por ejemplo, en un cuadro de diálogo con fichas que se modifica dinámicamente, el texto también puede cambiar. Para asegurarse de que no se truncará si es demasiado largo, establezca la propiedad WordWrap a True, la propiedad TabMaxWidth a cero (0) y la propiedad TabHeight a un alto que permita ver el texto más largo posible.

ShowFocusRect:

Establece mediante True o False si se dibuja un recuadro punteado en el tab cuando este tiene el foco

Picture

establece un gráfico para los Tabs
Comentarios
En tiempo de diseño puede establecer la propiedad Picture de una ficha si hace clic en ella y después establece la propiedad en la ventana Propiedades. En tiempo de ejecución puede establecer la propiedad Picture con la función LoadPicture o con la propiedad Picture de otro control o de otro objeto Form. Puede convertir cualquier ficha en la ficha activa si establece la propiedad Tab.
Al establecer la propiedad Picture en tiempo de diseño, el gráfico se guarda y se carga con el objeto Form que contiene el control SSTab. Si crea unarchivo ejecutable, el archivo contendrá la imagen. Al cargar un gráfico en tiempo de ejecución, el gráfico no se guarda con laaplicación.
Establecer la propiedad Picture afecta al valor de la propiedad TabPicture de la ficha actual y además aparece la imagen correspondiente en la ficha activa.
Ejemplo
Private Sub Command1_Click()
   SSTab1.Picture = LoadPicture("ruta de la imagen ")
End Sub 


TabCaption:

Comentarios
En tiempo de diseño, puede establecer la propiedad TabCaption si hace clic en una ficha y establece la propiedad Caption en la ventana Propiedades. También puede seleccionar (Custom) en la ventana Propiedades y establecer la propiedad TabCaption en la ficha General del cuadro de diálogo Propiedades.
En tiempo de ejecución puede leer o cambiar el título de cualquier ficha mediante la propiedad TabCaption. También puede usar la propiedad Caption para cambiar la propiedad TabCaption sólo para la ficha activa.
Puede usar la propiedad TabCaption para asignar a una ficha unatecla de acceso. En el valor de TabCaption, incluya el símbolo & inmediatamente antes del carácter que desea designar como tecla de acceso. Ese carácter aparecerá subrayado. Presione la tecla ALT y el carácter de subrayado para que la ficha pase a ser la ficha activa. Para incluir un símbolo & en el título sin crear una tecla de acceso, escriba dos símbolos seguidos (&&). En el título sólo aparecerá uno y no habrá ningún carácter subrayado.

Tab

Comentarios
La ficha actual se coloca en primer plano y pasa a ser la ficha activa.
Normalmente, el usuario de la aplicación hará clic en una ficha para convertirla en la ficha activa. Sin embargo, puede que tenga que seleccionarla en el código. Por ejemplo, puede que desee que cierta ficha sea la activa cada vez que se muestre un cuadro de diálogo determinado en la aplicación. Si abandona el cuadro de diálogo mediante el método Hide del objeto Form, la última ficha que estaba activa al ocultar el Form seguirá siendo la ficha activa cuando aparezca de nuevo el cuadro de diálogo. Puede establecer la propiedad Tab del control SSTab para que esté activa la misma ficha cada vez que aparezca el cuadro de diálogo.

Ejemplo
Este ejemplo hace que la ficha activa sea siempre la primera ficha del control SSTab justo antes de mostrar el formulario que contiene el control. Para probar este ejemplo, cree dos objetos Form. Coloque un control CommandButton en el Form1 y un control SSTab en el Form2. Pegue el código en el evento Click del control CommandButton del Form1 y después ejecute el ejemplo.
Private Sub Command1_Click()
   Form2.SSTab1.Tab = 1
   Form2.Show
End Sub
 

Rows

Devuelve el número de filas de fichas
Comentarios
El número de filas del control SSTab se especifica en tiempo de diseño mediante las propiedades Tabs y TabsPerRow.

TabEnabled

Determina si el Tab especificado está habilitado o deshabilitado
Comentarios
Cuando una ficha está desactivada, su texto aparece atenuado y el usuario no puede seleccionarla.
La propiedad TabEnabled activa o desactiva una única ficha. Para activar o desactivar todo el control SSTab, utilice la propiedad Enabled.

TabVisible:

Determina si el Tab especificado estará visible o no
Comentarios
La propiedad TabVisible muestra u oculta una única ficha. Puede usar la propiedad Visible para mostrar u ocultar todo el control SSTab.

Establecer un gráfico a un tab

Para establecerle un gráfico a un Tab, solo hay que seleccionar la pestaña que queremos y desde la ventana de propiedades seleccionar Picture y elegir el archivo gráfico.
Si quisiéremos hacerlo en tiempo de ejecución, podríamos hacerlo de esta forma refiriendonos a la propiedad TabPicture:

Private Sub Command1_Click()
'Le pasamos a la propiedad tabPicture el índice del tab.
El_SSTab.TabPicture(0) = LoadPicture(App.Path & "\imagen.ico") 
End Sub

Nota: también podríamos establecer gráficos a cada Tab en tiempo de ejecución que están cargados en un control ImageList.

Ejemplo para establecer en tiempo de ejecución el Caption de un Tab

Aquí cuando se presiona un Command1 se le establece el texto "Datos" al primer Tab, es decir el tab que tiene el índice número 0.
Private Sub Command1_Click()

'Le pasamos a la propiedad TabCaption el índice del tab y le asignamos un texto
SSTab1.TabCaption(0) = "Datos"

End Sub

Agregar Tabs o pestañas en tiempo de ejecución

Agregar un Tabbed Dialog llamado SSTab1, Colocar un Command1 y un Text1 en el formulario.
Luego cada ves que presiones el Command1, se agregará un nuevo Tab en tiempo de ejecución con el texto que se haya ingresado en el control Text1

Código fuente en el formulario
Private Sub Command1_Click()
    Call Agregar(Text1)
End Sub
 
Private Sub Agregar(Texto_Tab As String)
 
    SSTab1.Tabs = SSTab1.Tabs + 1
 
    SSTab1.TabCaption(SSTab1.Tabs - 1) = Texto_Tab
 
End Sub
 
Private Sub Form_Load()
 
    SSTab1.Tabs = 1
 
End Sub 

Eventos del Sstab

·        Click: Ocurre cuando el usuario presiona y suelta un botón del mouse sobre el control
·        DblClick: Ocurre al presionar y soltar un botón del mouse, y volver a presionarlo y soltarlo sobre el control
·        GotFocus: Ocurre cuando el mismo recibe el enfoque
·        LostFocus: Ocurre cuando el control pierde el enfoque
·        MouseDown: Ocurre cuando el usuario presiona el botón del mouse mientras el control tiene el enfoque
·        MouseMove: Se ejecuta cuando se mueve el mouse sobre el Sstab
·        MouseUp: Se ejcuta al soltar el botón del mouse cuando tiene el enfoque
·        Validate: Ocurre cuando el control pierde el enfoque en favor de un control que produce una validación, en este caso del Sstab

Como se ve en la descripción anterior, este no posee ningún evento propio, es decir tiene los eventos comunes que poseen la mayoría de los controles
Lo único que difiere, es el evento Click, en el cual posee un parámetro extra llamado PreviousTab
Private Sub SSTab1_Click(PreviousTab As Integer)

End Sub

Al hacer Click en el control, este parámetro nos devuelve el Tab anterior al cual se hizo click.
El siguiente ejemplo obtiene el Caption del Tab en el cual se hizo click ( Tab Activo ), y lo visualiza en la barra de título del formulario:

Private Sub SSTab1_Click(PreviousTab As Integer)
 
'Visualiza en la barra de título del form el caption _
del Tab activo
 
Me.Caption = SSTab1.TabCaption(SSTab1.Tab)
End Sub
 

Propiedad Container

El siguiente ejemplo, coloca en tiempo de ejecución, un control TextBox que se encuentra fuera del control SSTab, y lo hace en la ficha activa del mismo, utilizando la propiedad Container del textBox:

Private Sub Command1_Click()
 
 
' Coloca el Text1 en el tab activo
Set Text1.Container = SSTab1
 
' Redimensiona el control Text1 y lo posiciona
Text1.Move 50, SSTab1.TabHeight + 100, _
           SSTab1.Width - 100, _
           SSTab1.Height - SSTab1.TabHeight - 200
 
End Sub 

Redimensionar el SSTab en el Resize del Formulario


Este ejemplo, cuando se cambia de tamaño el Form, redimensiona y posiciona el control Tabbed dialog al ancho y alto que tenga el Form. También se redimensiona un control TextBox que se encuentra dentro de uno de los Tabs
Colocar un sstab y un Textbox dentro de un Tab

Private Sub Form_Resize()
 
 
' Posiciona y redimensiona el Sstab al ancho y alto del Fomulario
SSTab1.Move 10, 10, ScaleWidth - 10, ScaleHeight - 10
 
' Posiciona y redimensiona el TextBox
Text1.Move 50, SSTab1.TabHeight + 100, _
           SSTab1.Width - 100, _
           SSTab1.Height - SSTab1.TabHeight - 200
 
 
End Sub

_________________________________________