Personalizar celulares Motorola Vxxx(Editando los SEEMS con una aplicación escrita en VB .NET)
Fecha: 27/Ene/2006 (26/01/2006)
|
En este tutorial veremos como crear una pequeña aplicación en VB .NET, para modificar los SEEMS de los celulares (móviles, como le llaman por otros pagos) Motorola Vxxx. Especificamente, lo he probado con los modelos v186, v220, v220i y v300, aunque debería funcionar con el resto de los modelos Vxxx.
Para los que se esten preguntando de que se trata esto de "modificar los SEEMS" y para que sirve, voy a hacer una breve introducción.
Introducción
Los telefonos celulares actuales presentan una gran cantidad de funciones, llendo mucho mas alla de brindar sólo la posibilidad de hablar; y de hecho, podemos decir que: "hablar por telefono", es solo una función mas. Día a día se parecen mas a una de nuestras computadoras de escritorio: Internet, juegos, aplicaciones, e-mail, chat, etc.
El vocabulario que usamos para referirnos a muchas de las acciones que hacemos en la computadora y en el celular, es cada vez mas parecido: instalar y desinstalar programas, configurar, personalizar, guardar, eliminar y renombrar archivos, espacio disponible, cantidad de memoria y una larga lista de términos mas.
Claro esta, que las diferencias en cuanto a capacidad de procesamiento, almacenamiento, tamaño de la pantalla, etc. son enormes, pero si nos remontamos a un par de años atrás, nos daremos cuenta que estos pequeños equipos, superan a las PCs de esos tiempos en muchos aspectos; por lo que no seria de extrañar que tuvieramos celulares con procesadores cada vez mas rápidos, mayor capacidad de almacenamiento y mas cantidad de memoria, entre otras características.
En forma casi natural, para los que estamos en el mundo de la programación, al utilizar un programa en nuestra computadora, siempre nos interesa tratar de ver como funciona, como lo podemos configurar, modificar, mejorar, buscar opciones que a simple vista no se encuentran, y todo lo referido a investigarlo, para conocerlo a fondo y así poder trabajar de manera comoda con el programa o tal vez crear otra versión nosotros mismo desde cero y a nuestro gusto.
Al ver a los telefonos celulares cada vez mas parecidos a una computadora de escritorio, esto despierta en uno ese instinto casi natural del que hablaba antes, y es por eso que me puse a investigar un poco, para lograr habilitar (y deshabilitar) opciones ocultas, cambiar ciertos comportamientos, o el aspecto del celular; como lo hariamos con nuestra computadora.
Como punto de partida, debemos saber que cuando vamos navegando por los distintos menues de nuestro celular, y cambiamos opciones, lo que estamos haciendo es modificar ciertos archivos y SEEMS del equipo. Los SEEMS son pequeñas porciones de la memoria del celular, donde se encuentra la mayor parte de la información referida a la configuración del mismo. Muchas de las funciones de los telefonos celulares, no se pueden modificar desde la propia interfaz del equipo, y es aquí donde entra en juego este tutorial, con el cual desarrollaremos una aplicación en VB .NET, para poder editar estos SEEMS a los que haciamos referencia.
Con la aplicación que desarrollaremos, podremos modificar 6 opciones de los celulares Motorola Vxxx:
1- Habilitar/deshabilitar el cargador de aplicaciones Java.
2- Habilitar/deshabilitar la animación de Motorola al encender el telefono.
3- Habilitar/deshabilitar la animación de Motorola al apagar el telefono.
4- Personalizar el texto de la pantalla externa.
5- Personalizar el sonido de encendido.
6- Personalizar el sonido de apagado.
Esto no quiere decir que sea lo único que podemos modificar, pero intente elegir las opciones mas comunes que creo la mayoría de la gente quiere cambiar de su telefono, al poco tiempo de adquirirlo.
Antes de ponernos a trabajar en nuestra aplicación, necesitamos saber como descargar y subir un SEEM al telefono. Para llevar a cabo esta tarea, primero lo debes conectar a la computadora (vía cable, infrarrojo, etc) y tener instalado los drivers necesarios para que tu celular sea reconocido correctamente. Una vez que tu celular esta instalado, podemos proseguir a descargar un SEEM del celular.
Descargar un SEEM
Uno de los programas mas utilizados para descargar y subir SEEMS, es el P2K Phone File Manager. A continuación mostrare un ejemplo de como descargar el SEEM 0032_0001 (que es uno de los que usaremos).
Al abrir el P2K Manager, este detecta el celular que tenemos conectado y cargara la lista de archivos que se encuentran en el telefono. En la imagen que se presenta a continuación, se puede ver que el telefono se encuentra conectado y que es un Motorola v220 (Ver en la parte izquierda de la barra de estado).
Imagen 1
Si todo va bien, estamos en condiciones de descargar el SEEM. Para esto, en la sección donde dice SEEM, ponemos el numero 0032 en el campo "De:" y el numero 0001 en el campo "a:" (Como se muestra en la imagen 1). Luego pulsamos el botón "Bajar Seem" y nos aparecera un cuadro de dialogo para elegir donde guardar el archivo. Como nombre de archivo dejamos el que nos sugiere (xxxx_yyyy.seem), con lo cual, en este caso, el nombre del archivo seria 0032_ 0001.seem. Listo, ya hemos bajado un SEEM.
Ahora, nos queda bajar dos SEEMS mas con los que trabajaremos, estos son: El SEEM 004a_0001 y el 0061_0001. O sea, una vez que bajaste el 0032_0001, escribes 004a en el campo "De:" y el valor 0001 en el campo "a:" de la sección Seem, y pulsas nuevamente el botón "Bajar seem", y así sucesivamente con todo lo que necesites bajar.
Subir un SEEM
Al igual que para descargar un SEEM, usaremos el P2K Manager para subirlo. Los pasos para subir un SEEM son básicamente los mismos que para bajarlo. En este caso, si quisiéramos subir el SEEM 0032_0001 escribiríamos el numero 0032 en el campo "Seem:" y el numero 0001 en el campo "rec" (Como se muestra en la imagen 2). Luego pulsamos el botón "Subir seem" y elegimos el archivo 0001_0032.seem que bajamos anteriormente.
Imagen 2
¿Como se modifica un SEEM?
Un SEEM no es mas que un conjunto de bytes, donde cada uno de estos representa alguna característica del celular. Por ejemplo, si abrimos el SEEM 0061_0001 con un editor hexadecimal veremos algo como esto:
Imagen 3
La idea básica detras de nuestro proyecto es saber que bytes debemos modificar y con que valores, para que al volver a subir el SEEM al celular logremos nuestro objetivo. Nosotros no lo modificaremos con un editor hexadecimal, sino que haremos un pequeña aplicación que se encargara de esto, de una manera mucho mas amigable.
Conclusión
Espero no haberte aburrido con toda esta introducción; pero creo que era lo básico que debías saber para poder continuar con este proyecto. Como resumen podemos decir que para personalizar nuestro celular modificando sus SEEMS, tenemos tres pasos básicos:
1- Bajar un SEEM
2- Modificar el SEEM bajado
3- Subir el SEEM modificado
Ya vimos como cumplir con el primero y el tercer paso, así que ahora solo nos queda trabajar en el segundo punto, por lo tanto... EMPECEMOS.
IMPORTANTE
1- Antes de modificar un SEEM, GUARDA una copia del archivo original, por si algo falla o quieres volver tu celular al estado original.
2- Luego de subir los SEEMS modificados, deberás apagar y volver a encender el equipo, para que los cambios tengan efecto
Desarrollando la aplicación
Clase cSeem
Objetivo
Esta sera la clase base que contiene las funciones comunes para trabajar con los SEEMS, y a partir de la cual crearemos otras clases que manipulen cada SEEM en particular.
Propiedades
NombreArchivo: Guarda y retorna el nombre del archivo (con la ruta completa) del SEEM que se quiere editar.
Metodos
Public Sub Abrir()
Carga en memoria el archivo especificado en la propiedad NombreArchivo para su edición.
Public Sub ModificarUnByte(ByVal NumByte As Long, ByVal Valor As Byte)
Modifica el contenido del byte especificado por el parametro "NumByte", con el contenido del parametro "Valor".
Public Function LeerUnByte(ByVal NumByte As Long) As Byte
Lee y retorna el contenido almacenado en el byte especificado por el parametro "NumByte"
Public Function LongitudDelArchivo() As Long
Retorna la longitud del archivo cargado tras ejecutar el metodo Abrir().
Public Sub GuardarArchivo()
Guarda el archivo con las modificaciones que hallamos realizado.
Código
Public Class cSeem 'Nombre del archivo (con el path completo) del seem a editar Private m_NombreArchivo As String 'Array que contiene el archivo cargado en memoria Private m_InfoArchivo() As Byte 'Guarda la longitud del archivo Private m_LongitudDelArchivo As Long Public Property NombreArchivo() As String Get Return m_NombreArchivo End Get Set(ByVal Value As String) m_NombreArchivo = Value End Set End Property Public Sub Abrir() Dim NumArch As Integer NumArch = FreeFile() 'Abro el SEEM en modo binario FileOpen(NumArch, Me.NombreArchivo, OpenMode.Binary) m_LongitudDelArchivo = FileLen(Me.NombreArchivo) 'Redimensiono el array que contendra el archivo, para poder cargarlo ReDim m_InfoArchivo(Me.LongitudDelArchivo - 1) 'Cargo el SEEM en memoria FileGet(NumArch, m_InfoArchivo) FileClose(NumArch) End Sub Public Sub ModificarUnByte(ByVal NumByte As Long, ByVal Valor As Byte) 'Modifico el archivo cargado en memoria, ' cambiando el contenido del byte especificado m_InfoArchivo(NumByte) = Valor End Sub Public Function LeerUnByte(ByVal NumByte As Long) As Byte 'Retorno el valor del byte solicitado del archivo cargado en memoria Return m_InfoArchivo(NumByte) End Function Public Function LongitudDelArchivo() As Long Return m_LongitudDelArchivo End Function Public Sub GuardarArchivo() Dim NumArch As Integer NumArch = FreeFile() FileOpen(NumArch, Me.NombreArchivo, OpenMode.Binary) 'Guardo el SEEM modificado FilePut(NumArch, m_InfoArchivo) FileClose(NumArch) End Sub End Class
Clase cSeem0032_0001Objetivo
Esta clase se deriva de la clase cSeem, y contiene 3 propiedades para modificar el SEEM 0032_0001.
Propiedades
Public Property HabilitarCargadorDeAplicacionesJava() As Boolean
Habilita o deshabilita el cargador de aplicaciones Java. Esta opción nos permite cargar aplicación Java a nuestro celular sin necesidad de descargarlas desde Internet, sino que basta con que el telefono se encuentre conectado a nuestra computadora y usemos un programa como el Midway para subir las aplicaciones que queramos.
Public Property MostrarAnimacionDeMotorolaAlInicio() As Boolean
Habilita o deshabilita la animación de Motorola, que se muestra al encender el telefono, la cual puede resultar molesta despues de verla varias veces.
Public Property MostrarAnimacionDeMotorolaAlApagar() As Boolean
Habilita o deshabilita la animación de Motorola, que se muestra al apagar el telefono, la cual al igual que la de inicio, puede resultar molesta despues de un tiempo.
Código
Public Class cSeem0032_0001 Inherits cSeem Public Property HabilitarCargadorDeAplicacionesJava() As Boolean Get 'Si el valor guardado en el byte 67 es el &HF7... If Me.LeerUnByte(67) = &HF7 Then '...el cargador de aplicaciones Java esta habilitado Return True Else '...el cargador de aplicaciones Java esta deshabilitado Return False End If End Get Set(ByVal Value As Boolean) If Value = True Then 'Establezco el valor &HF7 en el byte 67, para ' habilitar el cargador de aplicaciones Java Me.ModificarUnByte(67, &HF7) Else 'Establezco el valor &HF6 en el byte 67, para ' deshabilitar el cargador de aplicaciones Java Me.ModificarUnByte(67, &HF6) End If End Set End Property Public Property MostrarAnimacionDeMotorolaAlInicio() As Boolean Get 'Si el valor guardado en el byte 29 es el &H38... If Me.LeerUnByte(29) = &H38 Then '...la animacion de Motorola al encender el tel. esta habilitada Return True Else '...la animacion de Motorola al encender el tel. esta deshabilitada Return False End If End Get Set(ByVal Value As Boolean) If Value = True Then 'Establezco el valor &H38 en el byte 29, para ' habilitar la animacion de Motorola al encender el tel. Me.ModificarUnByte(29, &H38) Else 'Establezco el valor &H30 en el byte 29, para ' deshabilitar la animacion de Motorola al encender el tel. Me.ModificarUnByte(29, &H30) End If End Set End Property Public Property MostrarAnimacionDeMotorolaAlApagar() As Boolean Get 'Si el valor guardado en el byte 49 es el &H2D... If Me.LeerUnByte(49) = &H2D Then '...la animacion de Motorola al apagar el tel. esta habilitada Return True Else '..la animacion de Motorola al apagar el tel. esta deshabilitada Return False End If End Get Set(ByVal Value As Boolean) If Value = True Then 'Establezco el valor &H2D en el byte 49, para ' habilitar la animacion de Motorola al apagar el tel. Me.ModificarUnByte(49, &H2D) Else 'Establezco el valor &H2C en el byte 49, para ' deshabilitar la animacion de Motorola al apagar el tel. Me.ModificarUnByte(49, &H2C) End If End Set End Property End ClassClase cSeem004a_0001
Objetivo
Esta clase se deriva de la clase cSeem, y contiene 3 propiedades para modificar el SEEM 004a_0001.
Propiedades
Public Property UsarTextoPantallaExteriorPersonalizado() As Boolean
Habilita o deshabilita la posibilidad de usar un texto personalizado en la pantalla exterior del celular, cuando la tapa de este se encuentra abierta. Si se activa esta opción, luego se debe modificar el SEEM 0061_0001 con el texto personalizado que se desea mostrar.
Public Property UsarSonidoDeInicioPersonalizado() As Boolean
Si esta propiedad se activa, podremos reproducir un sonido personalizado al encender nuestro telefono. Tras activar esta opción, el celular usara como sonido de inicio, el archivo que se llame Cust_Start~up.mp3.
Public Property UsarSonidoDeApagadoPersonalizado() As Boolean
Si esta propiedad esta activada, podremos reproducir un sonido personalizado al apagar nuestro telefono. Tras activar esta opción, el celular usara como sonido de apagado, el archivo que se llame Power~down.mp3.
Código
Public Class cSeem004a_0001 Inherits cSeem Public Property UsarTextoPantallaExteriorPersonalizado() As Boolean Get 'Si el valor guardado en el byte 39 es el 1... If Me.LeerUnByte(39) = 1 Then '...el texto personalizado de la pantalla exterior ' esta habilitado Return True Else '...el texto personalizado de la pantalla exterior ' esta deshabilitado Return False End If End Get Set(ByVal Value As Boolean) If Value = True Then 'Establezco el valor 1 en el byte 39, para ' habilitar el texto personalizado de la pantalla exterior Me.ModificarUnByte(39, 1) Else 'Establezco el valor 2 en el byte 39, para ' deshabilitar el texto personalizado de la pantalla exterior Me.ModificarUnByte(39, 2) End If End Set End Property Public Property UsarSonidoDeInicioPersonalizado() As Boolean Get 'Si el valor guardado en el byte 34 es el 1... If Me.LeerUnByte(34) = 1 Then '...el sonido de inicio personalizado esta habilitado Return True Else '...el sonido de inicio personalizado esta deshabilitado Return False End If End Get Set(ByVal Value As Boolean) If Value = True Then 'Establezco el valor 1 en el byte 34, para ' habilitar el sonido de inicio personalizado Me.ModificarUnByte(34, 1) Else 'Establezco el valor 0 en el byte 34, para ' deshabilitar el sonido de inicio personalizado Me.ModificarUnByte(34, 0) End If End Set End Property Public Property UsarSonidoDeApagadoPersonalizado() As Boolean Get 'Si el valor guardado en el byte 36 es el 1... If Me.LeerUnByte(36) = 1 Then '...el sonido de apagado personalizado esta habilitado Return True Else '...el sonido de apagado personalizado esta deshabilitado Return False End If End Get Set(ByVal Value As Boolean) If Value = True Then 'Establezco el valor 1 en el byte 36, para ' habilitar el sonido de apagado personalizado Me.ModificarUnByte(36, 1) Else 'Establezco el valor 0 en el byte 36, para ' deshabilitar el sonido de apagado personalizado Me.ModificarUnByte(36, 0) End If End Set End Property End ClassClase cSeem0061_0001
Objetivo
Esta clase se deriva de la clase cSeem, y contiene 1 sola propiedad para modificar el SEEM 0061_0001.
Propiedades
Public Property TextoPantallaExterior() As String
Esta propiedad nos permite leer o especificar el texto que se muestra en la pantalla exterior del celular (Si la tapa esta abierta). Para que este texto se muestre, debemos activar la opción en el SEEM 004a_0001.
Código
Public Class cSeem0061_0001 Inherits cSeem '1- El texto personalizado de la pantalla exterior, se guarda en UNICODE, ' por lo que cada caracter ocupa dos bytes, por ejemplo: si tenemos ' guardada la cadena "AB", al leerla de a un byte obtendriamos lo siguiente: ' ' 41 00 42 00 ' ' O sea: leemos cuatro bytes para dos caracteres, por lo que al guardar el archivo, guardo ' primero el ASCII del caracter y luego un byte con el valor "00". ' Si alguien tiene otra solucion mas optima, por favor comunicarse conmigo a ' mi e-mail ([email protected]) ' '2- Otra cuestion a saber, es que al finalizar el texto personalizado guardado ' en el archivo, hay un byte con el valor 00 y luego se rellena hasta ' completar 48 bytes con el ASCII 255. ' '3- Por ultimo, decir que el primer byte contiene el valor "00". Public Property TextoPantallaExterior() As String Get Dim Texto As String = "" Dim i As Integer Dim Caracter As Byte 'Recorro el archivo cargado en memoria, byte a byte For i = 0 To LongitudDelArchivo - 1 'Leo un byte Caracter = LeerUnByte(i) 'Si el byte leido no es "0" y tampoco "255" (ya que esto es relleno) If (Caracter > 0) And (Caracter < 255) Then 'Voy armando la cadena Texto = Texto & Chr(Caracter) End If Next Return Texto End Get Set(ByVal Texto As String) Dim i As Integer 'Numero de byte guardado 'Indica que caracter se esta leyendo del texto a guardar Dim PosEnTextoOriginal As Integer PosEnTextoOriginal = 1 'El primer byte del archivo debe ser 00 ModificarUnByte(0, 0) i = 1 'Guardo 48 bytes en el archivo Do While i < 48 If PosEnTextoOriginal <= Texto.Length Then 'Guardo el ASCII del caracter ModificarUnByte(i, Asc(Mid(Texto, PosEnTextoOriginal, 1))) 'Guardo un 0, para completar los dos bytes del caracter UNICODE ModificarUnByte(i + 1, 0) i = i + 2 If PosEnTextoOriginal = Texto.Length Then 'Al terminar el texto, y antes del relleno, debe haber un 'byte con el valor 00 ModificarUnByte(i, 0) i += 1 End If 'Avanzo una posicion en la cadena de texto que estoy guardando PosEnTextoOriginal = PosEnTextoOriginal + 1 Else 'Guardo un byte de relleno con el valor 255 ModificarUnByte(i, 255) i = i + 1 End If Loop End Set End Property End Class
Formulario frmAdministrador
Imagen 4
Descripción
Este formulario, posee un control TabControl, con tres TabPages: 0032_0001, 004a_0001 y 0061_0001 (Como se puede ver en la imagen 4). En tiempo de diseño cada TabPage esta vacía, ya que luego en tiempo de ejecución, se le asignara en forma dinámica un formulario a cada una. De esta se forma se nos hara mas fácil mantener la aplicación si luego queremos agregar nuevos formularios editores de SEEMS.
Podemos ver que posee una "barra de estado", que nos informa del estado del archivo ("Cerrado", "Cargado y GUARDADO" y "Cargado y SIN GUARDAR").
Por ultimo, podemos notar que existen tres botones que se explican por si solos: "Abrir", "Guardar" y "Cerrar Archivo".
Código
Option Strict Off Option Explicit On Public Class frmAdministrador Inherits System.Windows.Forms.Form #Region "Código generado por el Diseñador de Windows Forms" 'Declaro los editores de cada SEEM Private EditorSeem0061_0001 As New frmEditorSeem0061_0001() Private EditorSeem004a_0001 As New frmEditorSeem004a_0001() Private EditorSeem0032_0001 As New frmEditorSeem0032_0001() 'Creo una coleccion para poder recorrer de manera sencilla, 'los editores de SEEMS Private EditoresDeSeems As New Collection() 'Hace referencia al editor de SEEM que el usuario esta usando Private EditorDeSeemActivo As frmEditorDeSeem Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Agrego los editores al control TabControl Call AgregarEditor(tpSeem0061_0001, EditorSeem0061_0001) Call AgregarEditor(tpSeem004a_0001, EditorSeem004a_0001) Call AgregarEditor(tpSeem0032_0001, EditorSeem0032_0001) 'Establezco el editor activo de inicio EditorDeSeemActivo = EditorSeem0032_0001 End Sub Private Sub AgregarEditor(ByVal Solapa As TabPage, ByVal FormularioDeEdicion As frmEditorDeSeem) With FormularioDeEdicion .FormularioPadre = Me .TopLevel = False 'Agrego el editor de SEEM (FormularioDeEdicion) a la 'solapa especificada por el parametro "Solapa" Solapa.Controls.Add(FormularioDeEdicion) 'Modifico el tamaño del editor para que ocupe toda la 'superficie del TabPage .SetBounds(0, 0, Solapa.Width - 110, Solapa.Height) 'Le resto 110 al ancho, para descontar 'los bordes laterales .Anchor = AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top 'Muestro el editor .Show() End With 'Agrego el editor de SEEM a la coleccion de editores EditoresDeSeems.Add(FormularioDeEdicion) End Sub Private Sub btnAbrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnAbrir.Click 'Creo un filtro para que aparezca el nombre del archivo que se debe cargar Me.OpenSeemDialog.Filter = EditorDeSeemActivo.NombreDelArchivoOriginal & _ "|" & EditorDeSeemActivo.NombreDelArchivoOriginal 'Muestro el dialogo de Abrir SEEM Me.OpenSeemDialog.ShowDialog() End Sub Private Sub OpenSeemDialog_FileOk(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles OpenSeemDialog.FileOk 'Establezco el nombre del archivo que eligio el usario para abrir EditorDeSeemActivo.NombreDelArchivo = OpenSeemDialog.FileName 'Cargo el SEEM en el editor activo EditorDeSeemActivo.CargarSeem() End Sub Private Sub btnGuardar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnGuardar.Click 'Guardo el SEEM modificado EditorDeSeemActivo.GuardarSeem() End Sub Private Sub tcSeems_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles tcSeems.SelectedIndexChanged 'Establezco el editor de SEEM activo EditorDeSeemActivo = Me.tcSeems.SelectedTab.Controls(0) 'Actualizo la barra de estado, segun el estado de edicion en el que se encuentra el 'archivo del editor activo Call Me.CambiarEstadoDelArchivo(EditorDeSeemActivo.EstadoDelArchivo) End Sub Public Sub CambiarEstadoDelArchivo(ByVal Estado As frmEditorDeSeem.eEstadosDelArchivo) 'Actualizo la barra de estado, segun el parametro "Estado" y habilito o deshabilito 'los controles de "Guardar" y "Cerrar archivo" Select Case Estado Case frmEditorDeSeem.eEstadosDelArchivo.Cerrado lblEstadoDelArchivo.Text = "Archivo CERRADO" HabilitarControlesDeEdicion(False) Case frmEditorDeSeem.eEstadosDelArchivo.Guardado lblEstadoDelArchivo.Text = "Archivo cargado y GUARDADO" HabilitarControlesDeEdicion(True) btnGuardar.Enabled = False Case frmEditorDeSeem.eEstadosDelArchivo.SinGuardar lblEstadoDelArchivo.Text = "Archivo cargado y SIN GUARDAR" HabilitarControlesDeEdicion(True) End Select End Sub Private Sub btnCerrarArchivo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnCerrarArchivo.Click 'Cambio el estado del SEEM a "Cerrado" EditorDeSeemActivo.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Cerrado End Sub Private Sub HabilitarControlesDeEdicion(ByVal Estado As Boolean) 'Habilito o deshabilito el boton "Guardar" y "Cerrar archivo" btnCerrarArchivo.Enabled = Estado btnGuardar.Enabled = Estado End Sub Private Sub frmAdministrador_Closing(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles MyBase.Closing Dim UnEditor As frmEditorDeSeem Dim HayArchivosSinGuardar As Boolean 'Al cerrar el programa, determino si hay archivos sin guardar For Each UnEditor In EditoresDeSeems If UnEditor.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar Then HayArchivosSinGuardar = True Exit For End If Next 'Si hay archivos sin guardar, pregunto si realmente quiere salir o no If HayArchivosSinGuardar Then If MsgBox("Existen archivos que aún no han sido guardados." & _ Chr(Keys.Return) & _ "¿Realmente desea salir del programa?", _ MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.No Then 'No salir e.Cancel = True End If End If End Sub End ClassFormulario frmEditorDeSeem
Imagen 5
Descripción
Como podemos ver en la imagen, este formulario no tiene ningún control, sino que la idea aquí es crear un formulario base de edición. de SEEMS, para luego crear nuevos formularios que nos permitan editar cada SEEM en particular.
Código
Public Class frmEditorDeSeem Inherits System.Windows.Forms.Form #Region "Código generado por el Diseñador de Windows Forms" 'Defino los tres estados de edicion en los que puede estar el 'archivo de SEEM Public Enum eEstadosDelArchivo Cerrado SinGuardar Guardado End Enum 'Nombre del archivo cargado (podria ser distinto del original) Private m_NombreDelArchivo As String Private m_EstadoDelArchivo As eEstadosDelArchivo 'Formulario al que se le debe comunicar informacion acerca del estado de edicion Private m_FormularioPadre As Form 'Nombre original del archivo (Ej: 0032_0001.seem), usado para crear 'el filtro del cuadro de dialogo "Abrir SEEM" Private m_NombreDelArchivoOriginal As String 'Evento que informa que el estado de edicion del archivo ha cambiado Public Event CambioElEstadoDelArchivo() Public ReadOnly Property NombreDelArchivoOriginal() As String Get Return m_NombreDelArchivoOriginal End Get End Property Public Property NombreDelArchivo() As String Get Return m_NombreDelArchivo End Get Set(ByVal Value As String) m_NombreDelArchivo = Value End Set End Property Public Property EstadoDelArchivo() As eEstadosDelArchivo Get Return m_EstadoDelArchivo End Get Set(ByVal Estado As eEstadosDelArchivo) m_EstadoDelArchivo = Estado RaiseEvent CambioElEstadoDelArchivo() NotificarEstadoDelArchivo() End Set End Property Private Sub frmEditorDeSeem_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Cuando se carga el editor, el estado de edicion del archivo del SEEM es "cerrado" Me.EstadoDelArchivo = eEstadosDelArchivo.Cerrado End Sub Public Property FormularioPadre() As frmAdministrador Get Return m_FormularioPadre End Get Set(ByVal NombreFormulario As frmAdministrador) m_FormularioPadre = NombreFormulario End Set End Property Private Sub NotificarEstadoDelArchivo() 'Si hay un formulario a quien comunicarle el cambio de estado de edicion del archivo, 'llamo al metodo "CambiarEstadoDelArchivo" del formulario en cuestion If Not (FormularioPadre Is Nothing) Then FormularioPadre.CambiarEstadoDelArchivo(Me.EstadoDelArchivo) End If End Sub Public Overridable Function CargarSeem() As Boolean End Function Public Overridable Function GuardarSeem() As Boolean End Function End ClassFormulario frmEditorSeem0032_0001
Imagen 6
Descripción
Este formulario hereda de la clase frmEditorDeSeem, y es una interfaz para manejar las tres propiedades de un objeto de la clase cSeem0032_0001.
Código
Public Class frmEditorSeem0032_0001 Inherits frmEditorDeSeem #Region "Código generado por el Diseñador de Windows Forms" 'Objeto para editar el archivo de SEEM 0032_0001 Private Seem As New cSeem0032_0001() Public Overrides Function CargarSeem() As Boolean With Seem .NombreArchivo = Me.NombreDelArchivo .Abrir() 'Actualizo los controles, segun el archivo leido chkHabilitarCargadorApJava.Checked = .HabilitarCargadorDeAplicacionesJava chkAnimacionMotorolaAlEncender.Checked = .MostrarAnimacionDeMotorolaAlInicio chkAnimacionMotorolaAlApagar.Checked = .MostrarAnimacionDeMotorolaAlApagar End With 'Al cargar el archivo, el estado de edicion de este es: GUARDADO Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Guardado Return True End Function Public Overrides Function GuardarSeem() As Boolean 'Guardo el archivo del SEEM, con las modificaciones que se le hayan realizado With Seem .HabilitarCargadorDeAplicacionesJava = chkHabilitarCargadorApJava.Checked .MostrarAnimacionDeMotorolaAlInicio = chkAnimacionMotorolaAlEncender.Checked .MostrarAnimacionDeMotorolaAlApagar = chkAnimacionMotorolaAlApagar.Checked .GuardarArchivo() End With Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Guardado End Function Private Sub frmEditorSeem0061_0001_CambioElEstadoDelArchivo() Handles MyBase.CambioElEstadoDelArchivo 'Actualizo la interfaz segun el estado de edicion del archivo Select Case Me.EstadoDelArchivo Case frmEditorDeSeem.eEstadosDelArchivo.Cerrado Me.chkHabilitarCargadorApJava.Enabled = False Me.chkAnimacionMotorolaAlEncender.Enabled = False Me.chkAnimacionMotorolaAlApagar.Enabled = False Case Else Me.chkHabilitarCargadorApJava.Enabled = True Me.chkAnimacionMotorolaAlEncender.Enabled = True Me.chkAnimacionMotorolaAlApagar.Enabled = True End Select End Sub Private Sub chkHabilitarCargadorApJava_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles chkHabilitarCargadorApJava.CheckedChanged 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End Sub Private Sub chkAnimacionMotorolaAlEncender_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles chkAnimacionMotorolaAlEncender.CheckedChanged 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End Sub Private Sub chkAnimacionMotorolaAlApagar_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles chkAnimacionMotorolaAlApagar.CheckedChanged 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End Sub End ClassFormulario frmEditorSeem004a_0001
Imagen 7
Descripción
Este formulario hereda de la clase frmEditorDeSeem, y es una interfaz para manejar las tres propiedades de un objeto de la clase cSeem004a_0001.
Código
Public Class frmEditorSeem004a_0001 Inherits Proyecto1.frmEditorDeSeem #Region " Código generado por el Diseñador de Windows Forms " 'Objeto para editar el archivo de SEEM 004a_0001 Private Seem As New cSeem004a_0001() Public Overrides Function CargarSeem() As Boolean With Seem .NombreArchivo = Me.NombreDelArchivo .Abrir() 'Actualizo los controles, segun el archivo leido Me.chkTextoLCDPersonalizado.Checked = .UsarTextoPantallaExteriorPersonalizado Me.chkSonidoDeEncendidoPersonalizado.Checked = .UsarSonidoDeInicioPersonalizado Me.chkSonidoDeApagadoPersonalizado.Checked = .UsarSonidoDeApagadoPersonalizado End With 'Al cargar el archivo, el estado de edicion de este es: GUARDADO Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Guardado Return True End Function Public Overrides Function GuardarSeem() As Boolean 'Guardo el archivo del SEEM, con las modificaciones que se le hayan realizado With Seem .UsarTextoPantallaExteriorPersonalizado = Me.chkTextoLCDPersonalizado.Checked .UsarSonidoDeInicioPersonalizado = Me.chkSonidoDeEncendidoPersonalizado.Checked .UsarSonidoDeApagadoPersonalizado = Me.chkSonidoDeApagadoPersonalizado.Checked .GuardarArchivo() End With Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Guardado End Function Private Sub chkTextoLCDPersonalizado_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles chkTextoLCDPersonalizado.CheckedChanged 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End Sub Private Sub chkSonidoDeEncendidoPersonalizado_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles chkSonidoDeEncendidoPersonalizado.CheckedChanged 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End Sub Private Sub chkSonidoDeApagadoPersonalizado_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles chkSonidoDeApagadoPersonalizado.CheckedChanged 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End Sub Private Sub frmEditorSeem004a_0001_CambioElEstadoDelArchivo() Handles MyBase.CambioElEstadoDelArchivo 'Actualizo la interfaz segun el estado de edicion del archivo Select Case Me.EstadoDelArchivo Case frmEditorDeSeem.eEstadosDelArchivo.Cerrado Me.chkSonidoDeApagadoPersonalizado.Enabled = False Me.chkSonidoDeEncendidoPersonalizado.Enabled = False Me.chkTextoLCDPersonalizado.Enabled = False Case Else Me.chkSonidoDeApagadoPersonalizado.Enabled = True Me.chkSonidoDeEncendidoPersonalizado.Enabled = True Me.chkTextoLCDPersonalizado.Enabled = True End Select End Sub End ClassFormulario frmEditorSeem0061_0001
Imagen 8
Descripción
Este formulario hereda de la clase frmEditorDeSeem, y es una interfaz para manejar un objeto de la clase cSeem0061_0001.
Código
Public Class frmEditorSeem0061_0001 Inherits frmEditorDeSeem #Region " Código generado por el Diseñador de Windows Forms " 'Objeto para editar el archivo de SEEM 0061_0001 Private Seem As New cSeem0061_0001() Public Overrides Function CargarSeem() As Boolean With Seem .NombreArchivo = Me.NombreDelArchivo .Abrir() 'Actualizo los controles, segun el archivo leido txtLCDExterno.Text = .TextoPantallaExterior With txtLCDExterno .Enabled = True .SelectAll() .Focus() End With End With 'Al cargar el archivo, el estado de edicion de este es: GUARDADO Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Guardado Return True End Function Public Overrides Function GuardarSeem() As Boolean 'Guardo el archivo del SEEM, con las modificaciones que se le hayan realizado With Seem .TextoPantallaExterior = txtLCDExterno.Text .GuardarArchivo() End With Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.Guardado End Function Private Sub txtLCDExterno_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles txtLCDExterno.TextChanged If Me.EstadoDelArchivo <> frmEditorDeSeem.eEstadosDelArchivo.Cerrado Then 'Hubo modificaciones en el archivo Me.EstadoDelArchivo = frmEditorDeSeem.eEstadosDelArchivo.SinGuardar End If End Sub Private Sub frmEditorSeem0061_0001_CambioElEstadoDelArchivo() Handles MyBase.CambioElEstadoDelArchivo 'Actualizo la interfaz segun el estado de edicion del archivo Select Case Me.EstadoDelArchivo Case frmEditorDeSeem.eEstadosDelArchivo.Cerrado With txtLCDExterno .Text = "" .Enabled = False End With Case Else Me.txtLCDExterno.Enabled = True End Select End Sub End Class
Hasta aquí hemos llegado por el momento y espero estar escribiendo otro tutorial en breve, y así poder seguir colaborando con este sitio, que tanto me ha ayudado.
Si bien he intentado ser lo mas claro posible, como para que no tengan dudas sobre el proyecto; es casi de seguro que muchos de los que lo lean, si las tendrán, y es por eso que invito a todos ellos a escribirme a mi e-mail ([email protected]) y así intentar resolver las dudas particulares de cada uno, y a los que no le haya quedado ninguna duda, también los invito a escribirme para poder saber su opinión o que me envien sugerencias, para poder seguir mejorando los tutoriales futuros.
Hasta pronto,
Pablo Tilli.
Espacios de nombres usados en el código de este artículo:
System.Windows.Forms
Microsoft.VisualBasic
Fichero con el código de ejemplo: tillipablo_MotorolaVxxxConfig.zip - 26,3 KB
(MD5 checksum: 5d56af951ae8022098431d760db2a1fa)