jueves, 21 de noviembre de 2013

Código para Guardar el lienzo

Esta parte de código nos permite guardar el lienzo en la base de datos, aquí tenemos dos opciones:
-Actualizar el gráfico
-Guardar como nuevo gráfico
Para la definir si se actualiza o se guarda como otro gráfico dependerá del nombre con el que se le va a guardar el lienzo. Si es el mismo nombre se actualizará el lienzo en la base de datos, si se cambia de nombre se guardará como otro lienzo, y se indica por medio de un MessageBox si se guardo correctamente o se actualizo.
En la siguiente parte de código se indica como se desarrollo esta parte:
BibliotecaPaint.LienzoBDD usuarioGuardar = new LienzoBDD();
                // Guardar mensaje para poder guardar con el nombre adecuado
                Guardar mensaje = new Guardar(nombreLienzo);
                // Creo un dialog result para aceptar si debo guardarme o no el lienzo
                DialogResult s = mensaje.ShowDialog();
                // Si se acepta guardar
                if (s == DialogResult.OK)
                {
                    if (mensaje.nombreArchivo == nombreLienzo)
                    {
                        i = usuarioGuardar.ActualizarCliente(nombreLienzo, graficos.Figuras);
                    }
                    else
                    {
                        // Guardo al lienzo con el nombre especificado
                        nombreLienzo = mensaje.nombreArchivo;
                        // Compruebo que se ha verificado que se ha guardado el lienzo
                        i = usuarioGuardar.AgregarLienzo(nombreLienzo, contrasenia, graficos.Figuras);
                    }
                }
                // Si la variable es distinta de 0 quiere decir que se ha guardado
                if (i != 0)
                    // envío un mensaje que el lienzo se ha agregado
                    MessageBox.Show("Lienzo Agregado o Actualizado: " + nombreLienzo);

Selección de un Lienzo

Para el momento después de seleccionar el lienzo en el formulario de la lista de los lienzos, dependiendo de esa selección se accede a la base de datos o no, ya que, se tiene la opción nuevo lienzo el cual muestra un lienzo en blanco.
En la parte siguiente de código observamos como discriminamos de acuerdo a lo que seleccionemos, esta parte se encuentra en el evento load del formulario donde se presentarán las figuras y se podrá dibujar:

if (!nombreLienzo.Equals("Nuevo"))
            {
                // creo un nuevo objeto del tipo LienzoBDD que me servirá para obtener los lienzos que tiene el                   cliente
                LienzoBDD usuario = new LienzoBDD();
                // Llamo al métodoObtener lienzo por el nombre del lienzo y su contrasenia del cliente
                graficos.Figuras = usuario.ObtenerLienzo(nombreLienzo, contrasenia);
                // LLamo al método dibujar
                Dibujar();
            }

lunes, 11 de noviembre de 2013

Dibujando en el Paint.

Una vez verificado que el usuario exista entonces por default siempre va a existir en lienzo en blanco en el cuál los clientes podrán comenzar a disfrutar y dibujar en nuestro programa.

Una cosa muy importante aquí es que por debajo mientra el cliente dibuja con diferentes colores, grosores, con o sin relleno, los puntos iniciales y finales de cada figura, el tipo de figura ya que puede ser un círculo un cuadrado o una línea, cuantas figuras existes. Toda esta información se la va almacenando en bytes, para luego ser enviadas en formato binario y serializado a la base de datos. Para que al momento de acceder al lienzo con esta información sea capaz de reconstruir nuestro lienzo y mostrarnos tal y cual como lo guardamos.

Este es una parte fundamental de nuestro proyecto ya que en estos dos métodos que presentamos a continuación son el de Serializar los datos binarios el De-Serializar.

   public byte[] Serializar(List<Figura> objSerializable)
        {
            // Vamos a controlar el tiempo de vida de los objetos mediante el uso de Using y creamos una memoria de flujos
            // que me permitirá almacenar de forma binaria la inforamción de las figuras
            using (MemoryStream stream = new MemoryStream())
            {
                // Creo el formato binario para enviar de esta forma a la base de datos y poder enviar como bytes
                BinaryFormatter binario = new BinaryFormatter();
                // Serializo los datos que voy a enviar en este caso el arreglo de figuras
                binario.Serialize(stream, objSerializable);
                // Me retorna el flujo y lo convierto a un arreglo de bytes
                return stream.ToArray();
            }
        }

        // Método que me permitirá deserializar lso objetos que hemos enviado para poder regenerar la imagen(Lienzo) y poder de nuevo
        // obtener
        public object Deserializar(byte[] objDeserializable)
        {
            // Vamos a controlar el tiempo de vida de los objetos mediante el uso de Using y creamos una memoria de flujos
            // que me permitirá almacenar de forma binaria la inforamción de las figuras
            using (MemoryStream stream = new MemoryStream(objDeserializable))
            {
                // Creo el formato binario para enviar de esta forma a la base de datos y poder enviar como bytes
                BinaryFormatter binario = new BinaryFormatter();
                // Comienzo a leer desde la posicion 0 elflujo
                stream.Position = 0;
                // Me retorna todo los datos serializados
                return binario.Deserialize(stream);
            }
        }

En el siguiente gráfico se ve como un cliente ha dibujado distintas figuras de distintos colores y tamaños con o sin relleno, como se mencionó antes toda esta información se va almacenando para luego ser transmitida.



En este gráfico podemos observar ya cuando el lienzo haya sido enviado a guardar en la base de datos, como podemos observar nosotros lo guardamos como binario pero lo transformamos a Hexadecimal ya que en este formato al momento de recuperar solo quitamos los "-" y podemos recuperar el lienzo. 





sábado, 9 de noviembre de 2013

Creación de la clase Lienzo

Esta clase me permitirá obtener todo lo de un lienzo, es decir un arreglo de figuras, que tipo de figuras las cuales se relacionarán con la contraseña del cliente y el nombre del Lienzo, ya que cabe recordar que un cliente puede tener varios lienzos.

A continuación la clase Lienzo:

 // Hago que la clase Figura sea serializable para que pueda ser enviado la información
    // por la red
    [Serializable]
    public class Lienzo
    {
        // Creo un arreglo de figuras para poder almacenar las figuras que han sido dibujadas 
        // en el lienzo
        private List<Figura> figuras;
        // Refactorizando para poder setar y obtener las figuras que han sido dibujadas en el lienzo
        public List<Figura> Figuras
        {
            get { return figuras; }
            set { figuras = value; }
        }
        // Creación de un objeto String contrasenia, el cuál me servirá para conocer la contraseña del cliente el cual
        // puede tener varios lienzos guardados 
        private string contrasenia;
        // Refactorización de la contrasenia que me permitirá obtener y setear la constraseña del cliente 
        public string Contrasenia
        {
            get { return contrasenia; }
            set { contrasenia = value; }
        }

        // Creación de un objeto String nombre, el cuál me servirá para conocer el nombre del lienzo el cual puede tener
        // varias figuras
        private string nombre;
        // Refactorización del nombre del lienzo que me permitirá obtener y setear el nombre de los lienzos
        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }

        // Creación de un objeto Bitmap imagen, el cuál me servirá para hacer el bitmap en el cual vamos a dibujar los lienzos 
        private Bitmap imagen;
        // Refactorización del bitmap que me permitirá obtener y setear bitmaps del Cliente        
        public Bitmap Imagen
        {
            get { return imagen; }
            set { imagen = value; }
        }

        // Constructor de la clase Lienzo que me aceptará un arreglo de figuras para poder enviar esa información
        public Lienzo()
        {
            figuras = new List<Figura>();
        }
    }

jueves, 7 de noviembre de 2013

Creación de la Clase LienzoBDD la cual contendrá la lógica del manejo de la Base de Datos

Esta clase es de suma importancia ya que tendrá toda la lógica del acceso, actualización y lectura de nuestra Base de Datos que como se dijo constará de la tabla Usuario y Lienzo, en la cuál un Usuario puede tener varios Lienzos.

Además esta clase nos permitirá almacenar, todos los datos serializados de nuestro lienzo en el cual contendrá que tipo de figura es si es un cuadrado, círculo o una línea así como sus propiedades que es color de borde, grosor, si tiene o no relleno en el caso de tenerlo que color es, las coordenadas del punto inicial y final, en fin todo lo necesario para que al momento que desea leer el lienzo pueda reconstruirse.

Además aquí consta los dos métodos que me servirán para serializar el envío de mis datos y para cuando quiera acceder el proceso contrario es decir deserializar. Esto lo hicimos con el fin de simplificar el envío y la recepción de datos.

Otra cosa muy importante esta clase va a ser la que va a heredar de MarshallByRefObject para hacerlo y poder ocupar el Remoting.

A continuación se muestra la clase antes mencionada:

public class LienzoBDD : MarshalByRefObject
    {
        // Defino un String estático para la conexión de la base de datos    
        public static string cadenaConexion = "Data Source=Cristian-PC;Initial Catalog=Paint_Proyecto;Integrated Security=True";

        // Método ObtenerCliente que me permitirá obtener el Cliente mediante el idCliente en el formulario LoginUsuario
        public int ObtenerCliente(string idCliente, string nombreCliente)
        {
            //int dato = Convert.ToInt32(idCliente.ToString());
            // Uso en un string la sentencia De SQL para la búsqueda del Cliente mediante
            // el ID
            string sentenciaSql = "SELECT COUNT (*) from Usuario";
            sentenciaSql += " WHERE contrasenia=" +"'"+idCliente+"'";
            sentenciaSql += " AND usuario="+"'"+nombreCliente+"'";
            //MessageBox.Show(sentenciaSql);
            // Hago la conexión a la base de Datos la cual le paso la cadena de consulta
            // y la conexión
            SqlConnection conexion = new SqlConnection(cadenaConexion);
            SqlCommand comando = new SqlCommand(sentenciaSql, conexion);
            // Creo un Cliente con los datos, y le inicializamos como nulo
            /*string usuarioNombre = null;
            string contrasenia = null;
            string[] cliente = new string[2];*/
            int i = 0;
            // Captura de Excepciones
            try
            {
                // Abro la conexión
                conexion.Open();
                // Creo un SqlReader para leer las filas y lo inicio en null
                //SqlDataReader leer = null;
                // Asigno a la variable el leer que lo que la ejecución de la consulta realizada
                //leer = comando.ExecuteNonQuery;
                
                i = (Int32)comando.ExecuteScalar();
                // Si me leyó la conslta enviada
                /*if (leer.Read())
                {
                    // Creo un nuevo ClienteDetalle con los campos clienteID, NombreCompleto
                    // Contraseña y Correo
                    usuarioNombre = leer["usuario"].ToString().Trim();
                    contrasenia = leer["contrasenia"].ToString().Trim();
                    cliente[0] = usuarioNombre;
                    cliente[1] = contrasenia;
                }*/
            }
            // Captura de la excepción del tipo SQL
            catch (SqlException e)
            {
                //MessageBox.Show(e.ToString());
                // Defino a cliente como null
                i = 0;
            }
            // Esto pasará ocurra o no la excepción
            finally
            {
                // Cierro la conexión
                conexion.Close();
            }
            
            // Me retorna un cliente
            return i;
        }

        // Método ObtenerCliente que me permitirá obtener el Cliente mediante el idCliente en el formulario LoginUsuario
        public List<string> ObtenerLienzos(string idCliente)
        {
            //int dato = Convert.ToInt32(idCliente.ToString());
            // Uso en un string la sentencia De SQL para la búsqueda del Cliente mediante
            // el ID
            string sentenciaSql = "SELECT nombreLienzo from Lienzo";
            sentenciaSql += " WHERE contrasenia=" + "'" + idCliente + "'";

            // Hago la conexión a la base de Datos la cual le paso la cadena de consulta
            // y la conexión
            SqlConnection conexion = new SqlConnection(cadenaConexion);
            SqlCommand comando = new SqlCommand(sentenciaSql, conexion);
            // Creo un Cliente con los datos, y le inicializamos como nulo
            List<string> lienzos = new List<string>();
            // Captura de Excepciones
            try
            {
                // Abro la conexión
                conexion.Open();
                // Creo un SqlReader para leer las filas y lo inicio en null
                SqlDataReader leer = null;
                // Asigno a la variable el leer que lo que la ejecución de la consulta realizada
                leer = comando.ExecuteReader();
                // Si me leyó la conslta enviada
                while (leer.Read())
                {
                    // Creo un nuevo ClienteDetalle con los campos clienteID, NombreCompleto
                    // Contraseña y Correo
                    lienzos.Add(leer["nombreLienzo"].ToString().Trim());
                }
            }
            // Captura de la excepción del tipo SQL
            catch (SqlException)
            {
                // Defino a cliente como null
                lienzos = null;
            }
            // Esto pasará ocurra o no la excepción
            finally
            {
                // Cierro la conexión
                conexion.Close();
            }

            // Me retorna un cliente
            return lienzos;
        }
        // Método para Agregar un Cliente que toma por argumentos un objeto ClienteDetalle
        public int AgregarCliente(string clienteNombre, string contrasenia)
        {
            // Ingreso la sentencia para realizar la inserción de un usuario en la base de datos
            // Mediate sentencias SQL
            string sentenciaSql = "INSERT INTO Usuario ";
            sentenciaSql += "(usuario, contrasenia) VALUES ('";
            // Añado el Nombre
            sentenciaSql += clienteNombre + "', '";
            // Añado el Password
            sentenciaSql += contrasenia + "')";
            // Esto hago para que me realice la conexión a la Base de Datos y me pueda actualizar
            // Para ello llamo al método EjecutarSentencias
            return EjecutarSentencia(sentenciaSql);
        }


        public int AgregarLienzo(string nombreLienzo, string contrasenia, List<Figura> objetos)
        {
            // Ingreso la sentencia para realizar la inserción de un usuario en la base de datos
            // Mediate sentencias SQL
            byte[] datos = Serializar(objetos);
            string parametro = BitConverter.ToString(datos);
            string sentenciaSql = "INSERT INTO Lienzo";
            sentenciaSql += "(nombreLienzo, contrasenia, datos) VALUES ('";
            // Añado el Nombre
            sentenciaSql += nombreLienzo + "', '";
            // Añado el Password
            sentenciaSql += contrasenia + "', '";
            sentenciaSql += parametro +"')";
            // Esto hago para que me realice la conexión a la Base de Datos y me pueda actualizar
            // Para ello llamo al método EjecutarSentencias
            return EjecutarSentencia(sentenciaSql);
            
        }
        
        // Método que me permite ActualizarCliente y que me acepta como parámetro de entrada un objeto
        // ClienteDetalle
        public int ActualizarCliente(string nombreLienzo, List<Figura> objetos)
        {
            // Ingreso la sentencia para realizar la inserción de un usuario en la base de datos
            // Mediate sentencias SQL
            byte[] datos = Serializar(objetos);
            string parametro = BitConverter.ToString(datos);
            // Ingreso la sentencia para realizar la actualización de un usuario en la base de datos
            // Mediate sentencias SQL 
            string sentenciaSql = "UPDATE Lienzo SET ";
            // Modifico el Nombre del Cliente
            sentenciaSql += "datos='" + parametro + "'";
            // Para llevar el proceso de actualización lo ubico al cliente mediante el clienteId
            sentenciaSql += " WHERE nombreLienzo='" + nombreLienzo + "'";
            // Esto hago para que me realice la conexión a la Base de Datos y me pueda actualizar
            // Para ello llamo al método EjecutarSentencias
            return EjecutarSentencia(sentenciaSql);
        }

        // Método para Eliminar un Cliente o para esto ingreso el ID del cliente
        public List<Figura> ObtenerLienzo(string nombreLienzo, string contrasenia)
        {
            string sentenciaSql = "SELECT datos from Lienzo";
            sentenciaSql += " WHERE contrasenia=" + "'" + contrasenia + "'";
            sentenciaSql += " AND nombreLienzo=" + "'" + nombreLienzo + "'";

            // Hago la conexión a la base de Datos la cual le paso la cadena de consulta
            // y la conexión
            SqlConnection conexion = new SqlConnection(cadenaConexion);
            SqlCommand comando = new SqlCommand(sentenciaSql, conexion);
            // Creo un Cliente con los datos, y le inicializamos como nulo
            List<Figura> figuras = null;
            // Captura de Excepciones
            try
            {
                // Abro la conexión
                conexion.Open();
                // Creo un SqlReader para leer las filas y lo inicio en null
                SqlDataReader leer = null;
                // Asigno a la variable el leer que lo que la ejecución de la consulta realizada
                leer = comando.ExecuteReader();
                // Si me leyó la conslta enviada
                if (leer.Read())
                {
                    // Creo un nuevo ClienteDetalle con los campos clienteID, NombreCompleto
                    // Contraseña y Correo
                    string datos = leer["datos"].ToString().Trim();
                    string datosValidos = datos.Replace("-",string.Empty);
                    int numeroCaracteres = datosValidos.Length;
                    byte[] bytes = new byte[numeroCaracteres/2];
                    for (int i = 0; i < numeroCaracteres; i += 2)
                        bytes[i / 2] = Convert.ToByte(datosValidos.Substring(i, 2), 16);
                    figuras = (List<Figura>)Deserializar(bytes);

                    /*using (var sr = new StringReader(datosValidos))
                    {
                        for (int i = 0; i < datosValidos.Length; i++)
                            bytes[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
                            MessageBox.Show(bytes[1].ToString());
                    }
                    figuras = (List<Figura>)Deserializar(bytes);
                    */
                }
            }
            // Captura de la excepción del tipo SQL
            catch (SqlException)
            {
                // Defino a cliente como null
                figuras = null;
            }
            // Esto pasará ocurra o no la excepción
            finally
            {
                // Cierro la conexión
                conexion.Close();
            }

            // Me retorna un cliente
            return figuras;
        }

        // Método que me permitirá realizar la conexión a la Base de datos
        // Mediante sentencias SQL
        private int EjecutarSentencia(string sentenciaSql)
        {
            // Realizo una nueva conexion SQL mediante la cadena de conexion
            SqlConnection conexion = new SqlConnection(cadenaConexion);
            // Creo un SQL comando y le ingreso la sentencia que deseo que realice y la conexión
            SqlCommand comando = new SqlCommand(sentenciaSql, conexion);
            // Creo un a variable entera resultado y la inicializo en 0
            int resultado = 0;
            // Captura de Excepciones
            try
            {
                // Abro la conexión
                conexion.Open();
                // Asigno a resultado el número de filas afectadas por la consulta SQL
                resultado = comando.ExecuteNonQuery();
            }
            // Captura de la excepción
            catch (SqlException)
            {
                // Cuando no haya ninguna fila afectada el resultado es 0
                resultado = 0;
            }
            // Finalmente esto pasará ocurra o no la excepción
            finally
            {
                // Cierro la conexión
                conexion.Close();
            }
            // Me retorna el resultado
            return resultado;
        }
        /*
        public string ObtenerDominioActual()
        {
            // Me retorna el dominio actual
            return AppDomain.CurrentDomain.FriendlyName;
        }
        */

        // Método que me retorna un arreglo de bytes y me va a permitir serailizar todas las figuras que tengamos en nuestro
        // Lienzo
        public byte[] Serializar(List<Figura> objSerializable)
        {
            // Vamos a controlar el tiempo de vida de los objetos mediante el uso de Using y creamos una memoria de flujos
            // que me permitirá almacenar de forma binaria la inforamción de las figuras
            using (MemoryStream stream = new MemoryStream())
            {
                // Creo el formato binario para enviar de esta forma a la base de datos y poder enviar como bytes
                BinaryFormatter binario = new BinaryFormatter();
                // Serializo los datos que voy a enviar en este caso el arreglo de figuras
                binario.Serialize(stream, objSerializable);
                // Me retorna el flujo y lo convierto a un arreglo de bytes
                return stream.ToArray();
            }
        }

        // Método que me permitirá deserializar lso objetos que hemos enviado para poder regenerar la imagen(Lienzo) y poder de nuevo
        // obtener
        public object Deserializar(byte[] objDeserializable)
        {
            // Vamos a controlar el tiempo de vida de los objetos mediante el uso de Using y creamos una memoria de flujos
            // que me permitirá almacenar de forma binaria la inforamción de las figuras
            using (MemoryStream stream = new MemoryStream(objDeserializable))
            {
                // Creo el formato binario para enviar de esta forma a la base de datos y poder enviar como bytes
                BinaryFormatter binario = new BinaryFormatter();
                // Comienzo a leer desde la posicion 0 elflujo
                stream.Position = 0;
                // Me retorna todo los datos serializados
                return binario.Deserialize(stream);
            }
        }
    }


Clase Figura

Para poder guardar en un documento de tamaño adecuado para el servidor, se decidió poner en este documento partes fundamentales de las figuras que se dibujan en el PAINT tales como: Punto inicial y final, color del borde de la figura, color del relleno de la figura, grosor del borde de la linea y por último el tipo de gráfico que estamos dibujando.
Está clase facilitara el manejo de la información de las figuras y para su uso esta clase será serializable para si poder guardarla con mayor facilidad.
Además esta clase será serializable ya que así podremos enviar estos datos como se indica en el siguiente código sobre la clase Figura:

[Serializable]
    public class Figura
    {
        // Creación de un objeto punto inicial, el cuál me servirá para conocer el punto inicial
        // de las figuras geométricas dibujadas en el lienzo
        private Point inicial;
        // Refactorización del puntoInicial que me permitirá obtener y setear las coordenadas del punto
        // inicial
        public Point Inicial
        {
            get { return inicial; }
            set { inicial = value; }
        }

        // Creación de un objeto punto final, el cuál me servirá para conocer el punto final
        // de las figuras geométricas dibujadas en el lienzo
        private Point final;
        // Refactorización del punto Final que me permitirá obtener y setear las coordenadas del punto
        // final
        public Point Final
        {
            get { return final; }
            set { final = value; }
        }

        // Creación de un objeto color relleno, el cuál me servirá para conocer si la figura dibujada
        // está con relleno y ver el color del relleno
        private Color relleno;
        // Refactorización del color relleno que me permitirá obtener y setear de la figura el color de relleno
        public Color Relleno
        {
            get { return relleno; }
            set { relleno = value; }
        }

        // Creación de un objeto color borde, el cuál me servirá para conocer el color del borde de la figura
        // dibujada
        private Color borde;
        // Refactorización del color borde que me permitirá obtener y setear de la figura el color del borde
        public Color Borde
        {
            get { return borde; }
            set { borde = value; }
        }

        // Creación de un objeto float grosor, el cuál me servirá para conocer el grosor del borde de la figura
        // dibujada
        private float grosor;
        // Refactorización del grosor del borde que me permitirá obtener y setear de la figura el grosor del borde
        public float Grosor
        {
            get { return grosor; }
            set { grosor = value; }
        }

        // Creación de un objeto string tipo, el cuál me servirá para conocer el tipo de figura
        // dibujada
        private string tipo;
        // Refactorización del tipo de figura que me permitirá obtener y setear de la figura su tipo
        // es decir si es un círculo, cuadrado o es una línea.
        public string Tipo
        {
            get { return tipo; }
            set { tipo = value; }
        }
        //Constructor de la clase Figura
        public Figura()
        {
         
        }
    }

sábado, 2 de noviembre de 2013

Validación de usuarios en la Base de Datos

El proceso de autentificar a cada uno de los clientes, se lo realizó mediante la base de datos. En el caso que el cliente sea nuevo o no exista en la base de datos, me aparecerá un mensaje informándome acerca de esto, la misma situación en el caso de que el cliente ya se haya registrado me enviará al siguiente formulario el cual contiene todos los lienzos del cliente que haya guardado.

En esta primera imagen se pude apreciar la pantalla en la cuál el cliente va a autentificar su información.


En esta pantalla en cambio me aparece el mensaje de información en el caso que el cliente haya ingresado mal sus datos o el cliente es un nuevo Usuario.


Se muestra a continuación el caso en el que el cliente exista en la base de datos por lo tanto este es el formulario donde se aparecerá todos los lienzos creados por el cliente.