Navegador web en VB.NET (2)

Navegador Web escrito con Visual Basic 2005 usando la clase WebBrowser, añadiendo formulario de opciones y localización (2ª parte)

Resumen del ejercicio

Continuando con un ejercicio anterior “Navegador Web escrito con Visual Basic 2005” (aquí) se modifica la aplicación para poner en práctica propuestas de localización e internacionalización del programa.

En esta entrega se añade un formulario de opciones que permite configurar el programa, tanto en lo que respecta a si preferimos que arranque en ventana o a pantalla completa como a la hora de cambiar el idioma utilizado (restringido a 2: español e inglés). Aparte de ello se plantea la lectura y escritura de claves en el registro de Windows para que podamos añadir la aplicación a la lista de navegadores del sistema y a la lista de aplicaciones.

Añadiendo configuraciones

A las configuraciones existentes que guardaban las medidas de la ventana cuando ésta se cerraba (width, height, left, top) se añaden otras 2: una para guardar el modo de inicio de la aplicación (en ventana o a pantalla completa) y otra para guardar el nombre de la cultura por defecto (español):

Se accede a ellas mediante la clase MySettings usando la palabra clave My, como vemos en este código referido a Ventana:

'obtener los datos de la configuración guardada al cerrar el formulario por última vez
Select Case My.Settings.Ventana
'si se configura para arrancar en ventana
Case "full_no"
Me.Width = My.Settings.Anchura
Me.Height = My.Settings.Altura
Me.Left = My.Settings.Izquierda
Me.Top = My.Settings.Derecha
'si se configura para arrancar a pantalla completa
Case "full"
Me.WindowState = FormWindowState.Maximized
End Select

Y también se puede modificar su valor y guardarlo al salir de la aplicación; el método específico que guarda la configuración es ChangeAndPersistSettings() pero también se puede utilizar en su lugar la opción “Save My.Settings on shutdown” de la pestaña Application en las propiedades del proyecto; lo vemos de nuevo referido a Ventana:

'método específico que guarda la configuración, también se puede utilizar en su lugar la opción
'<Save My.Settings on shutdown> de la pestaña Application en las propiedades del proyecto
Sub ChangeAndPersistSettings()
'guardar las medidas de la ventana sólo si no está maximizada o minimizada
'y si My.Settings.Ventana está configurado como "full_no"
If (Me.WindowState = FormWindowState.Normal) AndAlso (My.Settings.Ventana = "full_no") Then
My.Settings.Altura = Me.Height
My.Settings.Anchura = Me.Width
My.Settings.Izquierda = Me.Left
My.Settings.Derecha = Me.Top
End If
'My.Settings.Cultura = lengua
'guardar la configuración
My.Settings.Save()
End Sub


Añadiendo el formulario de opciones

Siempre resulta más cómodo que los programas tengan un formulario centralizado en el que poder modificar sus parámetros. En este ejercicio se consigue mediante un formulario de tipo modal (diálogo) que permite al usuario seleccionar entre varias opciones o realizar alguna acción:

– elegir el modo de inicio de la aplicación: ventana o pantalla completa
– elegir el idioma de la interfaz (castellano o inglés)
– registrar la aplicación en la lista de aplicaciones y navegadores.

Al cambiar la elección del idioma, ha de modificarse en todos los formularios de la aplicación, incluido por supuesto el de opciones. Como ejemplo, éste es el formulario de opciones cuando la interfaz está en inglés (al inicio del artículo se muestra el mismo formulario con la intefaz en castellano):

Cambio de idioma: cerrar y reiniciar el programa

El cambio instantáneo del idioma de la interfaz se puede conseguir fácilmente mediante la propiedad CurrentCulture del hilo actual, como en este código:

Select Case cbIdiomas.SelectedIndex
'el ítem 1 (índice 0) es "Español (España)"
Case 0
lengua = "es-ES"
Case 1
'el ítem 2 (índice 1) es "Inglés (Estados Unidos)"
lengua = "en-US"
End Select
My.Settings.Cultura = lengua
Thread.CurrentThread.CurrentCulture = New CultureInfo(lengua)
Thread.CurrentThread.CurrentUICulture = New CultureInfo(lengua)

Pero he optado por cerrar el hilo actual del programa y arrancar un hilo nuevo con la cultura (idioma) recién seleccionada. Para ello, desde el formulario de opciones llamo a un método del formulario principal:

'si el ítem seleccionado del comboBox no se corresponde con el valor
'de la cultura del hilo actual, llamar al método nuevoHilo()
If Not (Thread.CurrentThread.CurrentCulture.Name = lengua) Then
Call nuevoHilo()
End If

El método nuevoHilo crea un nuevo hilo (thread) para enlazar con el método nuevoForm que arranca una instancia diferente del formulario, después de que se cierre la instancia actual. Antes de poder arrancar el nuevo proceso con un control ActiveX de la clase WebBrowser es necesario configurar su “ApartmentState”, por ello antes de arrancar el segundo proceso se configura su “ApartmentState” al modo STA (un apartamento -Apartment- es un contenedor lógico dentro de un proceso para los objetos que tienen las mismas características de comunicación con los subprocesos):

Public Shared Sub nuevoHilo()
'cerrar el formulario y que se vuelva a abrir automáticamente para que
'en el nuevo inicio lea correctamente la configuración de idioma y cultura
'
'crear un nuevo hilo (thread) para enlazar con el método nuevoForm() que arranca
'otra instancia diferente de Form1 después de que se cierre la instancia actual
Dim hilo As New Thread(AddressOf nuevoForm)
hilo.SetApartmentState(ApartmentState.STA)
hilo.Start()
'cerrar la aplicación y su hilo actual
Application.Exit()
End Sub
 
'método que inicia de nuevo la aplicación
Shared Sub nuevoForm()
'detenerse 0,4 segundos
Thread.Sleep(400)
'iniciar de nuevo la aplicación en el nuevo hilo
Application.Run(New Form1)
End Sub

No hay que olvidar traducir los cuadros de diálogo o cualquier otro elemento cuyo aspecto dependa de la cultura activa:

'mensaje después de la operación, diferente según la cultura
Select Case lengua.Substring(0, 2).ToLower()
Case "es"
MsgBox("Operación completada correctamente.", MsgBoxStyle.Information, "Info")
Case Else
MsgBox("Operation succesfully completed.", MsgBoxStyle.Information, "Info")
End Select


Cambiar el idioma inmediatamente

Para cambiar el idioma de la interfaz sin reiniciar la aplicación es necesario cambiar la propiedad CurrentCulture del hilo actual y volver a recrear el formulario y todos sus controles (en caso de no hacerlo así, nos encontraríamos con controles duplicados, uno por cada idioma, conservaríamos los del idioma anterior y aparecerían los del idioma recién seleccionado):

'ADOPTAR EL IDIOMA SELECCIONADO EN EL FORMULARIO Dialog1.vb Y
'RECREAR EL FORMULARIO Y SUS CONTROLES PARA QUE SE MUESTREN EN EL IDIOMA CORRECTO
Shared Sub cambiarIdioma()
'
My.Settings.urlIdioma = Form1.wbHtml.Url.ToString
'guardar las medidas de la ventana sólo si no está maximizada o minimizada
'y si My.Settings.Ventana está configurado como "full_no"
If (Form1.WindowState = FormWindowState.Normal) Then
My.Settings.Altura = Form1.Height
My.Settings.Anchura = Form1.Width
My.Settings.Izquierda = Form1.Left
My.Settings.Arriba = Form1.Top
End If

'aplicar el idioma seleccionado en cbIdiomas al hilo actual del programa
Thread.CurrentThread.CurrentCulture = New CultureInfo(lengua)
Thread.CurrentThread.CurrentUICulture = New CultureInfo(lengua)
'
'recrear el formulario y sus controles para que se muestren en el idioma correcto
Form1.Controls.Clear()
Form1.InitializeComponent()

'conservar el tamaño de la ventana al cambiar de idioma
Select Case My.Settings.Ventana
'si se configura para arrancar en ventana
Case "full_no"
Form1.Width = My.Settings.Anchura
Form1.Height = My.Settings.Altura
Form1.Left = My.Settings.Izquierda
Form1.Top = My.Settings.Arriba
'si se configura para arrancar a pantalla completa
Case "full"
Form1.WindowState = FormWindowState.Maximized
End Select

Form1.Navegar(My.Settings.urlIdioma)
End Sub


Aplicación completa en Visual Basic 2005

Cambiando de idioma sobre la marcha: emiweb1

Cambiando de idioma reiniciando el programa: emiWeb2

<< Primera parte