Delphi XE2

Embarcadero ha anunciado el lanzamiento del nuevo RAD Studio XE2 y con él el nuevo Delphi XE2. Aún no tenemos la fecha en la que estará dispnible al público (noviembre?) pero se esta organizando un World Tour por varias ciudades del mundo incluído Brasil y España (q pena q Perú no este incluído…) entre otros 30 países.

Se anuncia esta nueva versión como la más grande y mejor de todos los tiempos, y es verdad que trae una interesante grupo de novedades entre las que son dignas de mención:

  • Cross compiler para Windows y Mac OSX
  • Compilación para 64bits, con solo definir un nuevo Target de compilación
  • Nuevo motor gráfico Firemonkey, acelerado por GPU
  • VCL styles (temas?)
  • LiveBindings para conectar cualquier tipo de dato a un control
  • entre otros…

Realmente suena interesante!!

Si estas interesado puedes entrar al concurso por un RAD Studio XE2 gartis!! Búsca el banner en la página del Tour.

RAD Studio XE2 World Tour
RAD Studio XE2 World Tour
Anuncios

Sobre mi Avatar

Este es un post totalmente off-topic, pero la vez pasada me preguntaron en la universidad sobre mi avatar, algunos compañeros lanzaron algunas hipotesis, pero no acertaron.

El personaje es de una serie animada en Flash de la que mi hermano Tito me contó el 2009 o antes, creada por Ninjai Gang y  llamada Ninjai: The Little Ninja y que pueden ver en http://www.ninjai.com, por cierto es un poco violenta con sangre chispenado por todos lados.

Dibujando con Delphi (2 – GDI)

La mayoria de los controles visuales de Delphi incluyen un Canvas sonre el que éstos están dibujados.  Muchos controles exponen su propiedad Canvas como Public y otros a través de eventos como OnPaint o CustomDraw o parecidos.

Vamos a ver ahora el ejemplo más fácil de dibujo usando el Canvas del control TPaintBox (en la paleta System). El objeto Canvas de Delphi tiene un conjunto de Propiedades y Métodos que nos permitirán dibujar Línes, Círculos, Rectángulos usando colores y colores de borde.

Coloquemos un control TPaintBox en nuestro formulario y fijemos su tamaño (Height y Width) en 150 x 150. Con el control seleccionado veamos sus Eventos y ubiquemos el evento OnPaint, doble click para entrar a su implementación, luego agreguemos el siguiente código:

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
 // Fijamos el Color del Brush (el relleno) en verde
 PaintBox1.Canvas.Brush.Color := clGreen;
// Dibujamos un rectángulos desde las coordenadas 10,10 hasta las coordenadas 60,60
 PaintBox1.Canvas.Rectangle(10, 10 , 60, 60);

 // Cambiamos el color del Pen (el borde) a rojo
 PaintBox1.Canvas.Pen.Color := clRed;
 // y fijamos el ancho del la linea de borde a 4 pixeles
 PaintBox1.Canvas.Pen.Width := 4;
 // El color del Brush (relleno) lo ponemos a amarillo
 PaintBox1.Canvas.Brush.Color := clYellow;
 PaintBox1.Canvas.Rectangle(40, 40 , 100, 100);

 // Dibujamos un círculo
 PaintBox1.Canvas.Ellipse(50, 50, 20, 20);
end;

y obtendremos eun resultado como el siguiente:

Muy fácil!! Ahora fijemonos en algunos detalles:

  • Al dibujar el primer rectángulo,  las características del Pen (borde) se dejaron con los valores por defecto (negro, 1 pixel).
  • Al dibujar el círculo se usaron los valores fijados anteriormente tanto para el Pen como para el Brush.

Esta últma observación quiere decir que si no decimos lo contrario se usarán los últimos valores fijados para el canvas.

Otra observación es que el evento OnPaint del control TPaintBox se lanza cada vez que el control deba redibujarse, esto sucede cuando por ejemplo ocultamos la ventana con otra ventana y luego la volvemos a mostrar. Si haces la prueba notarás que el dibujo a cambiado y ahora se ve así:

¿Por qué el borde del primer rectángulo cambió a rojo y es más grueso? La respuesta es que el evento OnPaint se volvió a lanzar y volvió a hacer el dibujo, sólo que las propiedades de Pen han quedado con los últimos valores que le dimos. Para evitar este efecto debes asegurarte de fijar los valores de Pen y Brush tal como quieres que se vean, es decir debimos fijar el color del Pen a clBlack y el Width del Pen a 1 antes de dibujar el primer rectángulo.

Si quieres forzar el repintado de un control puedes llamar al método Invalidate del control, por ejemplo cuando quieres cambiar programáticamente algún color.

Bueno eso es lo básico del Dibujo usando el Canvas, algunos usos interesantes son:

  • Crear tus propios controles con diseños propios.
  • Cambiar los colores en las celdas de una grilla, por ejemplo poner las filas impares de otro color, o los valores negativos con fondo rojo, dibujar indicadores especiales, etc

Más adelante veremos de hacer algunos ejemplos de éstos.

Dibujando con Delphi (1)

Delphi tiene varios mecanismos que permiten dibujar en una aplicación. Para empezar vamos a ver algunas cosas básicas.

Pensando como un niño de 5 años para dibujar necesitamos un papel en blanco un lápiz y crayones. En principio en Delphi es igual, el papel se llama Canvas, al lápiz Pen y a los crayones de colores Brush.

Nota: para avanzados: Canvas, Pen y Brush son conceptos de alto nivel, Windows tiene sus API que son un poco diferentes.

Todo lo que se ve en la pantalla en una aplicación Delphi está dibujado sobre algún Canvas.

Muchos controles tienen su propiedad Canvas como pública, lo que nos permite dibujar directamente sobre ellos. En otros casos podemos sobreescribir la forma como se dibuja un control usando el evento OnCustomDrawCell que pasa como parámetro el Canvas del control. Esto es muy potente y nos permite personalizar el aspecto visual de casi cualquier control.

Existen varias APIs que nos permiten dibujar en Delphi. Cuando usamos los métodos del objeto Canvas estaremos usando GDI de Windows que es la forma básica de dibujar, y nos permite cosas como dibujar lineas, circulos, cuadrados, texto.

Otra API más avanzada es GDI+ (GDI plus), que está disponible desde Windows XP, esta API tiene funciones mucho más avanzadas que GDI, permitiendo degradados, transparencias, dibujar 2D emplenado antaliasing (lo que permite lineas menos pixeleadas),  trasnformaciones y más. Delphi no incluye un componente ni funciones para trabajar con GDI+ directamente, pero existen varios componentes y librerías de terceros que nos permiten usar GDI+, por ejemplo http://www.bilsen.com/gdiplus/, o http://www.mitov.com/html/igdi_.html.

A partir de Windows 7, Microsoft ha introducido una API aún más avanzada llamada Direct2D, aquí si Delphi incluye soporte para esta API directamente en Delphi 2010.

Aparte de las APIs propias de Windows existen muchas otras librerias, algunas de mejor calidad, otras orientadas a la velocidad, otras para 3D.

Por ejemplo tenemos SDL, OpenGL, DirectX.

Una librería muy interesante es AggPas que es un port de AGG (Anti Grain Geometry), muy fácil de usar.

En el siguiente post veremos algunos ejemplos de algunas de éstas librerías.

Delphi y XML (y 3)

Para terminar con XML vamos a ver como nos podemos pasear por los nodos del documento.

Para este ejemplo vamos  usar un ejemplo un poco más extenso que los usados anteriormente:

<libros>
  <libro tipo="novela">
    <nombre>La casa verde</nombre>
    <autor>Mario Vargas Llosa</autor>
  </libro>
  <libro tipo="novela">
    <nombre>Un mundo para Julius</nombre>
    <autor>Alfredo Bryce Echenique</autor>
  </libro>
</libros>
</pre>

A continuación vamos a listar todos los elementos <libro> hijos del elemento <libros> y mostraremos el nombre y el autor de cada uno.

<pre>procedure TForm1.Button2Click(Sender: TObject);
var
  ANode: IXMLNode;
  I: integer;
  CadenaLibro,
  CadenaSalida: string;
begin
  for I := 0 to XMLDocument1.DocumentElement.ChildNodes.Count - 1 do begin
    ANode := XMLDocument1.DocumentElement.ChildNodes[I];
    if ANode.NodeType = ntElement then begin
      CadenaLibro := ANode.ChildNodes['nombre'].Text + ' - ' + ANode.ChildNodes['autor'].Text;
      CadenaSalida := CadenaSalida + CadenaLibro + #13#10;
    end;
  end;
  ShowMessage(CadenaSalida);
end;

Algunas observaciones:

  • Si inspeccionamos el valor de XMLDocument1.DocumentElement.ChildNodes.Count nos devuelve el valor de 7, a pesar de solo haber agregado 2 nodos!! Si vamos al detalle descubriremos que lo 5 nodos extras tienen la propiedad NodeType igual a ntText y los 2 que nos interesan son de tipo ntElement. ¿Por qué se agregaron esos nodos de texto (en blanco por cierto)?. Es por que hemos puesto la propiedad Options/doNodeAutoIndent en True. Esto hace que internamente se agregen los saltos de línea y los espacios en blanco de la indentación. Si ponemos este valor a False y volvemos a hacer la prueba veremos que nos devuelve sólo 2 elementos.
  • Notemos que podemos referenciar los nodos hijos en ChildNodes tanto por su índice como por su nombre.
  • Finalmente, aunque creo que ya es obvio a este punto, XML sólo maneja texto y sólo texto, es decir que si queremos guardar el valor 125.56 tendremos que hacerlo como cadena, igualmente al momento de recuperarlo será como cadena y luego habrá que convertirlo al tipo correcto. Esto no quiere decir que no exista forma de guardar data binaria en un documento XML. Para poder hacer esto deberíamos primero codificar esta data binaria en algún formato de sólo texto como por ejemplo Base64 , UUEncode o algún otro.
  • XML sigue las mismas reglas que HTML sobre el uso de caracteres especiales, por lo que no se puede agregar directamente como texto caracteres como < ó >.

Otras funciones que nos permiten recorrer los elementos del documento son PreviousSibling y NextSibling así como ParentNode.

Delphi 2010 y XML (2)

Siguiendo con el tópico de XML veamos ahora algo de código. Como ejemplo tomaremos la estructuta XML del post anterior y lo crearemos por código.

A la hora de trabajar con documentos XML lo podemos hacer creando una instancia de la clase TXMLDocument o usando el control del mismo nombre que encontraremnos en la paleta de controles bajo Internet.

Un par de cosas antes de continuar, un nodo como por ejemplo <libro> se denomnina elemento, en XML todos lo que se crean son nodos, elemento por ejemplo es un tipo especial de nodo, un atributo también es un tipo de nodo, el contenido de un elemento tambien es un tipo de nodo.

Creemos una ventana como la que sigue para hacer nuestras pruebas:

Elijamos el  control creado y en la venatana de Propiedades podemos ver una llamada DOMVendor, en ella podremos elejir entre las disponibles, actualmente MSXML, Xerces y ADOM. Cual elejimos? depende de nuestras preferencia y el uso que le demos, si no sabes cual, apunta a lo seguro (¿?) y elije MSXML de Microsoft. Para fnes de este ejecicio expandimos la propiedad Options y ponemos a True doNodeAutoIndent, esto permitira que el texto que obtengamos aparezca indentado para ver mejor la jerarquía (esto es opcional, el formato XML no rquiere indentación e incluso todo el texto puede ir en una sola línea).

Ahora en el evento OnClick de nuestro botón agregaremos algo de código para crear la estructura planteada:

procedure TForm1.Button1Click(Sender: TObject);
var
DatoNode,
LibroNode,
RootNode: IXMLNode;
XMLString: string;
begin
XMLDocument1.Active := True;                // Debemos activar el Documento para poder trabajar
RootNode := XMLDocument1.AddChild('libros');  // Creamos el nodo raíz
LibroNode := RootNode.AddChild('libro');      // Agregamos un elemento debajo de raíz
LibroNode.Attributes['tipo'] := 'novela';     // Le agregamos un atributo a nuestro elemento
DatoNode := LibroNode.AddChild('nombre');     // Agregamos 2 nodos debajo del elemento Libro
DatoNode.Text := 'La Casa Verde';
DatoNode := LibroNode.AddChild('autor');
DatoNode.Text := 'Vargas Llosa';

XMLDocument1.SaveToXML(XMLString);            // Grabamos el documento en texto
Memo1.Text := XMLString;                      // y lo mostramos
end;

Ejecutemos el programa y obtendremos el siguiente resultado al hacer click en el boton.

En la línea 17 he usado XMLDocument1.SaveToXML(var XML: String) que toma la estructura creado y la convierte en texto. Del mismo modo pude haber usado SavetoFile() que grabariá el contenido en un archivo.

Lo mismo podemos hacer si usamos LoadFromXML() ó LoadFromFile().

Bueno eso es todo por ahora. En el siguiente post veremos como recorrer el Documento XML y obtener valores.

 

 

 

 

Delphi y XML (1)

XML que significa eXtenible Markup Language (lenguaje de marcas extensible) es para mi, muy a pesar de su nombre, no un lenguaje si no un formato para representar data/información arbitraria (por eso lo de extensible).

XML al igual que HTML son derivados de un concepto más genérico llamado SGML, por lo que comparten los conceptos jerárquicos así como la idea de tags o etiquetas, de ahi que ambos se vean muy parecidos a simple vista.

XML a cobrado notoriedad desde hace algunos años atrás como una forma muy legible (para humanos) de representar casi cualquier tipo información, al ser puramente texto con reglas explícitas para manejar caracteres especiales y no imprimibles, lo hace muy fácil de transportar entre plataformas y lenguajes.

XML tiene la particularidad de poder almacenar tanto la información en sí, como meta-información en la forma de tags y atributos, por ejemplo:

<libros>
  <libro tipo="novela">
    <nombre>La casa verde</nombre>
    <autor>Mario Vargas Llosa</autor>
  </libro>
</libros>

Como se ve no es necesario conocer la intención del autor para saber de que se trata. Es bastante autodescriptivo, incluso se puede notar la jerarquía entre los elemetos.

Estas características lo hacen muy interesante como medio de almacenar y transportar información entre sistemas diferentes, en plataformas diferentes o lenguajes de programación distintos. Sin embargo tanta maravilla no es gratis. La información así descrita ocupa mucho más espacio que otros formatos binarios, la tarea de “parsear” la información tanmbién es más pesada. La carga para el humano lector es más fácil, pero para la máquina es más costoso, claro que para eso están las máquinas, para reducir nuestro esfuerzo.  NOTA: Estas consideraciones deberían tomarse en cuenta cuando se transmite grandes volumenes de información y/o el tiempo de procesamiento debe ser mínimo.

Delphi puede manejar XML usando diferentes mecanismos. Delphi 2009/2010 incluye al menos 3 motores distintos, versiones previas usan el Microsoft MSXML, aunque también hay varios componentes de terceros, algunos comerciales y otros free.

En Delphi 2010 se incluyen:

  • MSXML, de Microsoft que usa la Msxml.dll
  • Xerces, es una librería escrita en C++, que es parte del proyecto Apache.
  • ADOM, Alternative Dom, que es una nueva versión de OpenXML, escrita integramente en Delphi por lo que no depende de ninguna librería externa.

Todas ellas permiten crear Documentos XML, cargar un Documento XML desde un archivo, grabrlo a un archivo, recorrerlo, y hacer búsquedas.

Para entender como se trabaja con XML debemos conocer algunos conceptos primero:

  • Un Documento XML está formado por un conjunto de nodos, organizados jeráquicamente.
  • Un nodo tiene una etiqueta o tag, puede tener atributos, y puede tener un contenido.
  • Un nodo esta limitado por una etiqueta de inicio y una de fin.
  • Un Docuemento XML tiene un solo nodo raíz, a partir del cual se arma toda la jerarquía.

Por ejemplo si el pedazo de código de líneas arriba es un documento XML entonces diriamos que:

<libros>

Es el nodo raíz, este nodo tiene una etiqueta de inicio que es “<libros>” y una etiqueta de fin que es “</libros>”

  <libro tipo="novela">

Este nodo tiene por etiqueta o tag <libro> , vemos que además tiene un atributo llamado tipo y cuyo valor es novela.

Finalmente en el siguiente nodo:

  <nombre>La casa verde</nombre>

Es un nodo de tag <nombre> y que tiene un contenido que es “La casa verde”.

Ya me cansé por hoy así que acá lo dejo.

En la siguiente entrada veremos código de como se maneja XML en Delphi.