Boletín Pascal #19 - 25-MAR-2001
INDICE
1. UNAS PALABRAS DEL EDITOR
2. PROGRAMACION EN DELPHI - EVALUACION DE EXPRESIONES AL MODO XBASE
- INTRODUCCION
- EVALUAR EXPRESIONES DADAS COMO CADENAS DE CARACTERES
- SER O NO SER HE ALLI EL DILEMA
- ¿COMO SE EVALUAN EXPRESIONES?
- ¿Y LAS VARIABLES?
- NO PODEMOS USAR CASE...OF
- BUSQUEDA BINARIA
- IMPLEMENTACION DE BUSQUEDAS POR "HASHING"
- DONDE SQL NO HA IDO JAMAS
- NOTAS RESPECTO AL EJEMPLO
- VOLVIENDO AL PAQUETE
- LO PROXIMO
3. CAPTURANDO MENSAJES DE LA APLICACION
4. ARREGLOS DINAMICOS
- ARREGLOS DINAMICOS MULTIDIMENSIONALES
5. ARTICULOS EN LA COMUNIDAD BORLAND
- DELPHI
· Construcción de componentes para el profesional - por Ray Konopka
· Migrando de Visual Basic a Delphi - por el Personal de Borland
· Fundido de imágenes - Reporte de laboratorio de Earl F. Glynn II
· Usando efectivamente listas de acciones - por Ray Konopka
· Recursos matemáticos para Delphi
- KYLIX
· ¿Está listo para Kylix? - por David Intersimone
· Aventuras en Kylix - por James R. Knowles
· Código fuente de FreeCLX disponible en SourceForge - por John Ray
Thomas
- INTERBASE
· 30 días de Paradox a InterBase - por Skip Rowland
· InterBase V6 - Mejoras de Rendimiento - por Dave Schnepper
· Los ABCs de migrar de InterBase 5 a InterBase 6 - por Mark
Duquette
· APIs de instalación y licencias de InterBase - por Personal de
Inprise
________________________________________________________________________
1. UNAS PALABRAS DEL EDITOR
Me complace anunciar que el ganador de la licencia de la Librería
JfControls es Santiago Cubero, un joven programador de Barcelona
(España), quien tenía asignado el número 62.
En esta edición tengo el agrado de presentar otro gran artículo de
Alirio Gavidia que en esta oportunidad nos mostrará cómo evaluar
expresiones en tiempo de ejecución en nuestras aplicaciones Delphi.
Saludos,
Ernesto De Spirito
eds2008 @ latiumsoftware.com
________________________________________________________________________
JfControls Lib. Multilenguaje. Multiapariencia. Skins. Privilegios. Más
de 40 componentes integrados y personalizables. Múltiples problemas de
programación resueltos. Administración centralizada de recursos. Para
Delphi 3-2006 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm
________________________________________________________________________
2. PROGRAMACION EN DELPHI - EVALUACION DE EXPRESIONES AL MODO XBASE
Por Alirio A. Gavidia B.
INTRODUCCION
------------
Hace un par de años se me encargó resolver un problema común de
"Compatibilidad". Este era el poder evaluar desde Delphi expresiones
xBase (por xBase entendemos a dBase y sus derivados como Clipper y
FoxPro).
Todo este asunto sucede porque los lenguajes xBase basados todos en
alguna forma de interpretación soportan lo que se conoce como "Macros"
(no confundir el almacenamiento de una serie de comandos y acciones
para su repetición posterior). Los programadores, en muchas ocasiones,
solicitan del usuario la definición de filtros para luego aplicarlos
directamente como expresiones (mala práctica si el usuario no sabe
escribir expresiones aritméticas bajo la sintaxis requerida).
EVALUAR EXPRESIONES DADAS COMO CADENAS DE CARACTERES
----------------------------------------------------
La aplicación creada en aquella oportunidad solicita expresiones al
usuario como filtros para búsquedas, consultas y reportes, pero cada vez
que lo hace presenta un botón que despliega un formulario de diálogo con
los elementos para construir la expresión. La expresión es tipo xBase
así que si el usuario conoce aplicaciones de ese tipo puede dar su
expresión directamente.
SER O NO SER HE ALLI EL DILEMA
------------------------------
En principio se presentaron dos alternativas:
1.- Crear un control para evaluar expresiones xBase.
2.- Usar un control ya existente.
La tercera, enseñarle SQL a los usuarios fue desechada por el principio
de compatibilidad con la aplicación anterior.
Existen algunos componentes interesantes a este respecto, de hecho
encontré que existen dos conjuntos de componentes para ello: Orientados
a aritmética y Orientados a bases de datos. Los primeros son prácticos,
bonitos, baratos (hay varios freeware) pero suelen estar orientados a la
resolución de gráficas y problemas matemáticos. Los segundos consideran
el asunto de los campos, me interesé por los componentes del segundo
tipo. Terminé usando un reemplazo del BDE con soporte para archivos de
Clipper que acepta expresiones xBase como filtros.
Sin embargo, paralelamente desarrollé algunas funciones para evaluar
expresiones (están en mi página personal y son gratuitas, sólo
documentadas en español) como parte de esta artículo presento la clase
Texpression. Por otro lado desarrollé un conjunto de componentes (estos
si son shareware en inglés y con documentación inglés/español) que
permiten evaluar expresiones del tipo:
(CLIENTE->FECNAC>CTOD('01/01/1900')) .AND. CREDITO
cuando la mayoría de los componentes para evaluar fórmulas no pasan de
expresiones constantes como:
3-2/3.14
¿COMO SE EVALUAN EXPRESIONES?
-----------------------------
Por lo general hay dos pasos: el análisis (búsqueda) de patrones y como
segundo la combinación de los valores obtenidos en el paso previo para
obtener un resultado.
La búsqueda de patrones (lexicografía) permite reconocer entre una serie
de caracteres el tipo y funcionalidad de ciertos patrones. Por ejemplo
reconocer si una palabra empieza por un dígito indica que posiblemente
es un número constante (o un error), si no es así posiblemente la
palabra es un identificador que define algún valor u operador que altera
un valor.
Descubiertos los patrones estos de almacenan en alguna estructura de
datos (normalmente una pila, lo he visto con dos pilas también) y se
reducen en combinando valores según corresponda a los identificadores.
Al final lo que queda es el resultado de la expresión en la pila.
¿Y LAS VARIABLES?
-----------------
Las variables y las constantes y en fin cualquier cosa asociada a un
identificador debe ser provisto por el programador a través de un evento
o una lista. Los componentes que presento consideran estas dos vías.
También consideran arreglos y funciones (varias predefinidas,
fundamentalmente similares a las de Clipper).
Por ejemplo:
HalSimpleExpr.Eval('Variable*Pi()')
En este caso hay dos identificadores "Variable" y "Pi". Como el segundo
es seguido por un par de paréntesis es una función. El componente
dispara el evento OnRequestIdentifier (para evaluar Variable) y
OnRequestFunction (para evaluar Pi).
La evaluación de Pi sería manejada así:
procedure TForm1.HalSimpleExpr1RequestFunction(Sender: TObject;
ident: String; var value: Variant; var cancel: Boolean);
Var
col, row : integer;
begin
if CompareText(ident,'Pi')=0 then
value := Pi
else
cancel := true
end;
Nota: Debo señalar que hay un gran ausente entre los parámetros del
evento; este es un arreglo con los argumentos de la función. Para una
próxima versión el argumento de la función evaluada será parte de los
parámetros por lo pronto es sólo un campo público en la clase.
Por cierto verán que si la función no es Pi el control dispara una
excepción (eso define el parámetro "cancel"). La solución para evaluar
"Variable" es análoga pero con otro evento. Todo esto funciona muy bien
hasta que tenemos unas 50 funciones.
NO PODEMOS USAR CASE...OF
-------------------------
No es posible el uso de la sentencia "case" debido a que esta funciona
para tipos "contables" (enteros, caracteres, boléanos y similares) y la
alternativa de implementar un "if" tras otro es eficiente para el primer
identificador pero terrible para los últimos. El siguiente paso es usar
una lista, pero ordenada.
BUSQUEDA BINARIA
----------------
La búsqueda binaria sobre listas ordenadas parece una buena alternativa,
si hablamos de 1000 elementos podremos hallar cualquier valor el 50% de
las veces en unos 10 pasos (el otro 50% en menos). En la mayoría de los
casos esto es muy bueno, sin embargo hay una alternativa digna de
estudio.
IMPLEMENTACION DE BUSQUEDAS POR "HASHING"
-----------------------------------------
Mejor que revisar una lista es tener una función que de antemano señale
la posición del identificador en la lista. Por ejemplo una función que
sume el primer carácter, el último menos 97 y la longitud de la cadena,
así si buscamos la palabra "program" aplicaríamos algo como
IndexOf("program") que resultaría en Ord('p') + Ord('m') +
Length('program'). Esto es 112 + 109 + 7 – 97 -> 131. De allí a la
posición 131 de la tabla.
Como se entiende la búsqueda por tablas de "Hash" mejoran los esfuerzos
de búsqueda notablemente. Sin embargo, desperdician memoria. Queda al
programador definir que camino usar, sin embargo, lo componentes que
refiero como shareware presentan listas de este tipo como parte de su
funcionamiento intrínseco.
DONDE SQL NO HA IDO JAMAS
-------------------------
Resulta que SQL resuelve bien los problemas en cuanto a filtros y
búsquedas. Pero que pasa si quiero hacer algo menos voluminoso como una
pequeña hoja de cálculo definible en sus formulas por el usuario. Por
ello anexo un ejemplo usando un "stringrid" y la clase TExpression. Creo
que en general hay pequeñas necesidades en las cuales puede resultar
conveniente el uso de un evaluador de formulas más allá de querer imitar
las macros xBase.
NOTAS RESPECTO AL EJEMPLO
-------------------------
El ejemplo es un control "TstringGrid" donde se hace uso de las
propiedades "Cells" y "Objects". La primera presenta el resultado de un
formula que es almacenado en "Objects". Los "strings" deben ser
especificados con comillas simples. Los archivos que salva/carga son de
texto simple. Cada fórmula definida requiere la presión de la tecla 'ok'
para ser almacenada. Hay definido un evento para manejar la función
"Cell(c,r)" donde 'c' es columna y 'r' fila.
VOLVIENDO AL PAQUETE
--------------------
El uso es simple, un método: eval. Con un parámetro la expresión dada
como un "string". Sin embargo, hay diferentes métodos según el tipo a
manejar.
Los componentes consideran distintos tipos de sintaxis: xBase, Basic,
Pascal y Java. Fundamentalmente alterando el uso de operadores lógicos
entre puntos como lo hacen en expresiones xBase.
Tres componentes con distintos alcances: ThalSimpleExpr, ThalMacroExpr y
ThalArithmeticExpr.
El primero carece de funciones y manejo de listas de identificadores, el
segundo implementa unas 75 funciones, el manejo de listas y referencias
a datasets. El tercero no tiene el manejo de "alias" ni datasets, sin
embargo, soporta muchas de las funciones predefinidas.
Los detalles están documentados con el paquete y hay ejemplos incluidos.
Espero lo disfruten.
Pueden bajar el demo shareware directamente de mi página personal en
http://www.gavidia.org/he-shareware.zip
También lo pueden solicitar a la dirección de correo delphi@gavidia.org.
Para el ejemplo adjunto a este artículo
http://www.latiumsoftware.com/es/file.php?id=p19
En http://www.gavidia.org/pod hay material freeware relacionado con el
tema.
LO PROXIMO
----------
Me tomaré el tiempo para dar información respecto a las listas por
"Hashing" que aquí mencioné. Para la próxima entrega ese será el tema.
------------------------------
Copyright © 2001 por Alirio A. Gavidia B. Todos los derechos reservados.
Se permite la publicación de este material por cualquier medio por parte
de cualquiera siempre que este no sea modificado en contenido y se cite
la fuente original.
________________________________________________________________________
3. CAPTURANDO MENSAJES DE LA APLICACION
A veces necesitamos capturar los mensajes de Windows a nivel de la
aplicación. Una forma es con un "hook" (gancho), y la otra es usando
el evento Message del objeto Application que se produce cada vez que
la aplicación recibe un mensaje de Windows. Vamos a seguir el segundo
camino. Hay dos formas de establecer un manejador para este evento: una
es usando un objeto ApplicationEvents que viene con Delphi 5 (simple-
mente hay que hacer doble-clic en el cuadro combinado del evento
OnMessage en el Inspector de Objetos) y la otra es haciéndolo "a mano":
1) En la sección privada de su formulario principal agregue la
siguiente declaración:
procedure ApplicationMessage(var Msg: TMsg; var Handled: Boolean);
2) Asigne la propiedad OnMessage en el evento Create del formulario,
por ejemplo:
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := ApplicationMessage;
end;
3) Cuando desee dejar de capturar mensajes todo lo que tiene que hacer
es establecer OnMessage en nil:
procedure TForm1.FormDestroy(Sender: TObject);
begin
Application.OnMessage := nil;
end;
Finalmente debe implementar el procedimiento. Por ejemplo, vamos a
atrapar los mensajes de teclado WM_KEYUP y WM_KEYDOWN para convertir el
punto decimal del teclado numérico en una coma (esto es útil en
aplicaciones hispanas).
procedure TForm1.ApplicationMessage(var Msg: TMsg;
var Handled: Boolean);
begin
case Msg.Message of
WM_KEYDOWN, WM_KEYUP:
case Msg.wParam of
// Reemplazar el punto del teclado numerico (key code = 110)
// por una coma (key code = 188).
110: Msg.wParam := 188;
end;
end;
end;
Ahora puede colocar un control Edit en su formulario y probarlo.
________________________________________________________________________
4. ARREGLOS DINAMICOS
Los arreglos dinámicos son arreglos que pueden crecer o achicarse en
tiempo de ejecución para acomodar más o menos elementos. La declaración
de un arreglo dinámico es parecida a la de un arreglo estático, excepto
que el rango de índices se omite. Por ejemplo:
var
a: array of integer;
Un arreglo dinámico inicialmente no tiene elementos. Puede usar el
procedimiento SetLength en su código para asignar el número de elementos
que necesita. Puede llamar a SetLength tantas veces como sea necesario.
Si la nueva longitud es mayor que el número actual de elementos, se
agrega espacio para nuevos elementos, y si es menor entonces los últimos
elementos del arreglo son descartados.
Por ejemplo SetLength(a, 10) asigna espacio para 10 elementos. Los
elementos en un arreglo dinámico se indexan comenzando por 0 hasta uno
menos que la longitud del arreglo, así que por ejemplo el siguiente
código se puede usar para inicializar los elementos de un arreglo en
cero:
for i := 0 to Length(a)-1 do
a[i] := 0;
En el ejemplo adjunto a este artículo verá el uso de un arreglo dinámico
para guardar los nombres de los archivos en un directorio. Naturalmente,
una lista de cadenas (stringlist) sería mejor para la tarea, pero se usó
un arreglo dinámico por propósitos pedagógicos.
ARREGLOS DINAMICOS MULTIDIMENSIONALES
-----------------------------------
Un arreglo dinámico de dos dimensiones puede declararse así:
var
a: array of array of integer;
De esta forma podrá asignar ambas dimensiones en tiempo de ejecución. El
procedimiento SetLength admite tantos parámetros "NewLength" (nueva
longitud) como dimensiones. Por ejemplo SetLength(a, 10, 10)
establecería un arreglo cuadrado de 10 x 10.
Un cosa interesante es que en vez de ver el arreglo como una matriz (es
decir rectangular) puede verse como un vector de vectores que no necesa-
riamente tienen que tener el mismo número de elementos. Por ejemplo el
siguiente código crea un arreglo "triangular" e inicializa sus
elementos con números consecutivos:
k := 0;
SetLength(a, 4); // 4 filas
for i := 0 to 3 do begin // Por cada fila
SetLength(a[i], i + 1); // Establece el número de columnas
for j := 0 to i do begin // Inicializa la fila
a[i,j] := k;
inc(k);
end;
end;
0 1 2 3
+---+
0 | 0 |
+---+---+
1 | 1 | 2 |
+---+---+---+
2 | 3 | 4 | 5 |
+---+---+---+---+
3 | 6 | 7 | 8 | 9 |
+---+---+---+---+
________________________________________________________________________
5. ARTICULOS EN LA COMUNIDAD BORLAND
Este mes se pueden encontrar algunas cosas interesantes en la Comunidad
Borland. Todo en inglés, claro, pero bueno...
DELPHI
======
* Construcción de componentes para el profesional - por Ray Konopka
Este artículo describe los críticos pasos extra que deben seguirse
para desarrollar componentes profesionales de calidad profesional.
Temas específicos incluyen creación de ayuda del componente en línea,
diseño efectivo de paquetes para la distribución del componente,
soporte de múltiples versiones de Delphi, y cómo soportar la
instalación automática de en un solo paso.
http://community.borland.com/article/0,1410,27057,00.html
* Migrando de Visual Basic a Delphi - por el Personal de Borland
http://community.borland.com/article/images/26225/vbtodelphi.pdf
* Fundido de imágenes - Reporte de laboratorio de Earl F. Glynn II
Este artículo demuestra cómo fundir un fondo y una imagen de frente
desvaneciendo de una imagen a la otra, pero sólo a lo largo de un
borde de transición dibujado con una simple herramienta de dibujo.
http://www.efg2.com/Lab/ImageProcessing/Feathering.htm
* Usando efectivamente listas de acciones - por Ray Konopka
Este artículo describe, en detalle, lo que las acciones y las
listas de acciones pueden hacer por una aplicación.
http://community.borland.com/article/0,1410,27058,00.html
* Recursos matemáticos para Delphi
He aquí un compendio de recursos matemáticos para Delphi
http://www.efg2.com/Lab/Library/Delphi/MathInfo/Resources.htm
KYLIX
=====
* ¿Está listo para Kylix? - por David Intersimone
¿Está listo para Kylix? Por supuesto que lo está. ¿Está su sistema
listo para Kylix? He aquí una forma de averiguarlo.
http://community.borland.com/article/0,1410,26998,00.html
* Aventuras en Kylix - por James R. Knowles
Descripción de una primera experiencia con Kylix
http://www.ifm-services.com/people/jamesk/kylix/
* Código fuente de FreeCLX disponible en SourceForge - por John Ray
Thomas
FreeCLX, el proyecto código abierto de la Librería de Componentes
CLX de Borland para Linux ahora está abierto para colaboración.
http://community.borland.com/article/0,1410,27100,00.html
INTERBASE
=========
* 30 días de Paradox a InterBase - por Skip Rowland
Este artículo examina los problemas, las "curitas", las soluciones, y
los éxitos encontrados durante una gran migración de Paradox a
InterBase
http://community.borland.com/article/0,1410,27006,00.html
* InterBase V6 - Mejoras de Rendimiento - por Dave Schnepper
Este artículo cubre cambios en InterBase 6 que directa o indirec-
tamente mejorarán la velocidad y rendimento general de las consultas.
http://community.borland.com/article/0,1410,27005,00.html
* Los ABCs de migrar de InterBase 5 a InterBase 6 - por Mark Duquette
Este artículo técnico es para ayudarlo a aprender los detalles a la
vsta y ocultos de migrar sus aplicaciones desde InterBase 5 hacia
InterBase 6.
http://community.borland.com/article/0,1410,27004,00.html
* APIs de instalación y licencias de InterBase - por Personal de Inprise
InterBase 6 tiene una nueva API de instalación que automatiza muchas
tareas involucradas en la incrustación de bases de datos en una
aplicación. Esta sesión describe la API y cómo usarla.
http://community.borland.com/article/0,1410,26415,00.html
________________________________________________________________________
¡TÚ PUEDES AYUDARNOS!
Necesitamos tu ayuda para que este boletín pueda continuar y crecer. Una
forma en que puedes ayudarnos es enviando este enlace a tus amigos:
http://www.latiumsoftware.com/es/pascal/index.php
Otra forma es votándonos en alguno de estos rankings para darle más
visibilidad a nuestro sitio web y aumentar así el número de suscrip-
ciones al boletín, que esperamos en el futuro se traduzca también en un
mayor número de colaboraciones de artículos, trucos, etc.:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
http://www.lawebdelprogramador.com/buscar/votar.php?id=615
Por favor vota. Son sólo unos segundos para ti que REALMENTE pueden
hacer la diferencia. Necesitamos tu ayuda para poder continuar.
________________________________________________________________________
Si no has recibido el archivo con el código fuente completo de los
ejemplos que se presentan en este boletín, puedes descargarlo de la
siguiente dirección: http://www.latiumsoftware.com/es/file.php?id=p19
________________________________________________________________________
Página principal: http://www.latiumsoftware.com/es/pascal/index.php
Página del grupo: http://espanol.groups.yahoo.com/group/boletin-pascal/
Para suscribirse / apuntarse: boletin-pascal-subscribe@gruposyahoo.com
Para cancelar / removerse: boletin-pascal-unsubscribe@gruposyahoo.com
Para reportar problemas con la suscripción: eds2008 @ latiumsoftware.com
________________________________________________________________________
Este boletín se provee "TAL Y COMO ESTA", sin garantía de ninguna clase.
Su uso implica la aceptación de nuestros términos de licencia y de la
ausencia de garantía que puedes leer en nuestro sitio web. Allí también
encontrarás una nota sobre marcas registradas. Te animamos a que redis-
tribuyas este boletín, siempre y cuando lo hagas en forma completa
(incluyendo la información de copyright), sin modificaciones y de manera
gratuita. Los artículos son copyright de sus respectivos autores y se
reproducen aquí con el permiso de los mismos.
________________________________________________________________________
Latium Software http://www.latiumsoftware.com/es/index.php
Copyright (c) 2001 por Ernesto De Spirito. Todos los derechos reservados
________________________________________________________________________
|