Boletín Pascal #53 - 08-FEB-2005
Índice
1. Unas palabras del editor
2. Análisis de rendimiento del código con puntos de interrupción sin
interrupción (non-breaking breakpoints)
3. Presentando YAPI
4. Estableciendo el manejador de eventos predeterminado de un componente
5. Antivirus en Delphi: aRC-Anti WODE.JPG 1.0
6. Foros / listas de correo
7. Delphi en la Red
- Componentes, librerías y aplicaciones
· Shareware / Comercial
· Freeware
· Actualizaciones de productos Borland
- Artículos, trucos y consejos
- Tutoriales y capacitación
- Noticias
- Otros / Sitios misceláneos
________________________________________________________________________
Tecno Soft Solutions. Reseller Autorizado de Symbol Technologies, líder
mundial en captura de códigos de barras. >>> http://www.tecno-symbol.com
________________________________________________________________________
1. Unas palabras del editor
Finalmente me encuentro al día con las publicaciones. Es un gran alivio
para mí. Les agradezco el apoyo que me han brindado todo este tiempo
manteniendo vivo el interés en esta modesta publicación. Espero que en
el 2005 podamos mantener el calendario de publicación que nos hemos
propuesto.
Los usuarios de Hotmail que no hayan podido descargar el archivo con el
código fuente que acompañó al Boletin Pascal #52 debido a una falsa
alarma de virus producida por el análisis heurístico de Trend Micro (el
antivirus que usa Hotmail), pueden descargar dicho archivo desde mi
sitio web: http://www.latiumsoftware.com/es/file.php?id=p52
Bien, es hora de agradecer a los autores que contribuyeron su material
para hacer posible esta edición: Jim McKeeth, Owen Mooney, Peter Johnson
y Furious Logic. Nos complace entregar los premios de esta edición a:
* Peter Johnson - "Estableciendo el manejador de eventos..."
InstallAWARE 3.0 Express Edition - por MimarSinan Int. ($69.95)
Desarrolle instaladores para Windows Installer sin necesidad de
conocimiento previo de MSI. InstallAWARE automáticamente convierte en
tiempo de creación un script de flujo condicional en una base de datos
MSI que cumple con ICE, certificable con logotipo. El IDE ofrece una
interfaz visual que genera su script de instalación por usted
automáticamente y cuyo comportamiento puede ser completamente
adaptado. Sigue vigente la oferta especial por tiempo limitado para
los lectores del Boletín Pascal: 30% de descuento para todas las
ediciones. ¡La Edición Empresarial a tan sólo $559.95!
http://www.installaware.com/landingea.html
* Owen Mooney - "Presentando YAPI"
KnowedgeBASE Vortex 2.9 por Delphinium Software ($49.35)
El corazón de KnowledgeBASE es un árbol de información altamente
expandible y con gran capacidad de búsqueda, que puede verse como
esquema o auditado dentro de un procesador de textos incorporado.
Incluye una base de datos para referencias guardadas.
http://www.programurl.com/knowledgebase-vortex.htm
* Jim McKeeth - "Análisis de rendimiento del código..."
YAPI Professional - por Owen Mooney ($95)
Ofrece la más fácil y aún así poderosa capacidad de impresión desde
Delphi. Provee configuración WYSIWYG, vista preliminar, campos
independientes, campos enlazados a datos, texto, grids, tabs, mapas de
bits, operación con TCanvas, posicionamiento preciso o de flujo libre,
y todo usando sentencias "writeln" simples.
http://www.geocities.com/yapisoftware/
Agradecimientos especiales a Delphinium Software por donar KnowledgeBASE
Vortex y a Owen Mooney por donar YAPI Professional como premios
continuos para futuras ediciones. Para la próxima edición tenemos tres
premios para asignar entre los colaboradores de artículos en inglés:
InstallAWARE 3.0 Professional Edition, KnowedgeBASE Vortex y YAPI
Professional. La edición #54 será publicada en marzo, así que si tienen
una idea para un artículo y saben inglés, ¡vayan escribiendo!
Nos enorgullece continuar ofreciendo a los lectores un descuento
especial sobre InstallAWARE 3 para Windows Installer, gracias a la
linda gente de MimarSinan International. Por un tiempo limitado, los
lectores pueden obtener un 30% de descuento siguiente este enlace:
http://www.installaware.com/landingea.html
Y ahora, ¡vayamos al código!
Saludos,
Ernesto De Spirito y Dave Murray
boltin-pascal-owner@gruposyahoo.com
________________________________________________________________________
Help & Manual 3.50 por EC Software · Shareware ($ 279) - Una herramienta
visual de autoría de ayuda para generar archivos WinHelp (.HLP), Adobe
PDF, páginas HTML y los nuevos archivos HTML HELP (.CHM) introducidos
en Windows 98, así como otros formatos de archivo y documentación
impresa, todo desde una misma fuente. Una herramienta imprescindible
para cualquier desarrollador de software. http://www.helpandmanual.com/
________________________________________________________________________
2. Análisis de rendimiento del código con puntos de interrupción sin
interrupción (non-breaking breakpoints)
Por Jim McKeeth <jim at mckeeth dot org>
Resumen: A veces es bueno saber cuánto tiempo toma en ejecutarse una
porción específica de código. El IDE de Borland provee un medio para
lograr esto usando puntos de interrupción que no detienen la ejecución
(non-breaking breakpoints) y el registro de eventos (event log).
Este artículo fue publicado originalmente en la Borland Developer
Network (ver Referencias) e incluye varias imágenes, las que aquí se
publican en el archivo comprimido que acompaña este número.
Ya sea porque tenga un punto en su programa que corre más lento de lo
esperado, o porque está debatiendo cuál sería la forma más rápida de
hacer algo, necesita medir el rendimiento de una porción de código. En
los viejos tiempos añadiríamos algo de código a nuestros programas para
registrar la hora de inicio y final de procesos específicos. Luego lo
removeríamos o lo comentaríamos hasta que lo necesitáramos nuevamente.
Ahora usamos analizadores de rendimiento de código ("code profilers")
que cronometran la ejecución de cada línea de nuestro código y nos
proveen con reportes detallados y gráficos. Podríamos tomarnos
semanas examinando todos los datos disponibles.
Los analizadores de aplicaciones son muy lindos, pero a veces no
disponemos de uno conveniente, o realmente no queremos lidiar con uno
por tan sólo un par de líneas de código, o puede que insertar toda la
información de depuración adicional para que funcione el analizador
produzca un cambio en el comportamiento de nuestro programa. En vez de
volver al pasado y añadir todo ese código para registrar las horas de
inicio y fin, podemos usar puntos de interrupción sin interrupción.
La mayor ventaja de esta técnica comparada con el uso de un analizador
de rendimiento tradicional es cuando tenemos un programa bastante
complejo corriendo y queremos analizar algo de código en el momento, sin
tener que reiniciar el programa y ejecutar el analizador. Se puede
focalizar este análisis muy específicamente, de modo que no causaría el
impacto en el comportamiento general de nuestro programa que causarían
otros analizadores. En los casos en los que tenga unas pocas selectas
rutinas que desee analizar, encontrará esta técnica más rápida y fácil
de acometer.
Este artículo está escrito para Delphi 7, pero las técnicas deberían
trabajar con pocos o ningún cambio en otras versiones de Delphi, así
como C++ Builder y Kylix. El código adjunto es específico para Windows,
pero estoy seguro que un programador Kylix con recursos sabría qué
APIs de Linux usar en su lugar.
Antes de enseñarles como usar los puntos de interrupción sin
interrupción para analizar el rendimiento de su código, voy a cubrir
algunas bases sobre los puntos de interrupción sin interrupción. Si ya
se siente cómodo con las características avanzadas de los puntos de
interrupción, puede saltar a la sección sobre Análisis de Rendimiento.
¿Qué son los puntos de interrupción sin interrupción?
-----------------------------------------------------
Sé que probablemente estén pensando que un punto de interrupción sin
interrupción sea una contradicción. Como veremos a continuación, en
realidad no lo es. Cary Jensen ofrece un gran artículo titulado "Usando
puntos de interrupción sin interrupción en Delphi", disponible en la
Borland Developer Network (ver Referencias). No se preocupen si no lo
han leído. Cubriré todo lo que necesitan saber aquí.
El Free Online Dictionary of Computing (Diccionario Online Libre de
Computación) define un punto de interrupción como sigue:
Punto de interrupción
Un punto en un programa que, al ser alcanzado, genera algún
comportamiento útil al proceso de depuración. Generalmente, los puntos
de interrupción se usan para detener ("pausar") la ejecución del
programa, y/o volcar los valores de algunas o todas las variables del
programa. Los puntos de interrupción pueden ser parte del programa
mismo, o pueden ser establecidos por el programador como parte de una
sesión interactiva con una herramienta de depuración para escrutinizar
la ejecución del programa.
Así que los puntos de interrupción no siempre detienen (o "pausan") la
ejecución del programa. Un mejor nombre sería puntos de interrupción sin
detención, pero independientemente de cómo los llamemos, estamos usando
puntos de interrupción que no detienen la ejecución y aún así generan un
comportamiento especial. Así que, ¿cómo obtenemos uno de esos divertidos
puntos de interrupción? En realidad es muy simple:
1. Crear un punto de interrupción de la forma habitual (yo uso F5)
2. Traer el diálogo "Source Breakpoint Properties" (habitualmente yo
hago clic derecho sobre el punto de interrupción y selecciono
"Breakpoint Properties..." en el menú contextual)
3. Hacer clic en el botón "Advanced >>".
4. Desmarcar la casilla de verificación "Break".
5. Hacer clic en el botón "OK".
Fig 1. Basic Breakpoint Properties
Antes de presionar el botón "Advanced" (Avanzado), el diálogo "Source
Breakpoint Properties" muestra la configuración predeterminada del punto
de interrupción. Note que especifica el nombre de archivo y el número de
línea en el que se encuentra el punto de interrupción. Están en gris en
esta vista indicando que están deshabilitados porque estamos editando
las propiedades de un punto de interrupción existente. Si estuviéramos
creando o editando un punto de interrupción desde la "Breakpoint List"
([CTRL]+[ALT]+[B] para la lista, [CTRL]+[A] y [CTRL]+[E] para crear un
punto de interrupción) entonces estos campos no estarían deshabilitados y
los podríamos especificar.
Fig 2. Advanced Breakpoint Properties
El diálogo "Breakpoint Properties" después de hacer clic en el botón
"Advanced" incluye muchas características poderosas. Por ahora estamos
interesados en la casilla "Break" (interrupción). Desmárquela y haga
clic en "OK".
Su punto de interrupción se seguirá viendo igual. No está deshabilitado
(como se indica con una línea verde y un símbolo de detención gris),
pero si corre su programa ahora ya no pausa en esa línea. Si al correr
el programa la línea cambia de color a verde oscuro, entonces su punto
de interrupción está una línea que no ejecuta código. Elija una de las
líneas con un punto azul a la izquierda y repita el proceso. Está bien,
esperaré.
Si lo hizo bien, su programa correrá sin detenerse en ese línea. En este
momento esto no es muy útil, pero al menos ya sabe cómo establecer un
punto de interrupción sin detención.
Registrando con un punto de interrupción
----------------------------------------
Ahora que tenemos nuestro punto de interrupción sin interrupción, lo que
queremos es que escriba en un registro cuando se ejecuta la línea de
código que está marcando. Vuelva al diálogo "Breakpoint Properties".
Note que va directamente a la vista avanzada pues ha hecho un cambio en
la sección "Actions" (acciones). Ahora vamos a hacer otro cambio. Vamos
a añadir texto al cuadro combinado "Log message" (registrar mensaje).
Al analizar mi código habitualmente tengo un punto de interrupción con
registro en el inicio y otro al final del bloque a analizar, y hago que
esos puntos de interrupción registren "Inicio" y "Fin" respectivamente.
Si corre su programa ahora, después de hacer este cambio, no notará
ninguna diferencia obvia. El mensaje fue registrado en el "Event Log"
(registro de eventos), el que puede ser accedido desde el menú del IDE
(View -> Debug Windows -> Event Log) o presionando [Ctrl]+[Alt]+[V].
Tenía tres puntos de interrupción establecidos en mi programa, con el
primero y el último registrando un mensaje. Así es como se ve mi Event
Log:
Fig 3. Event Log
Las líneas en rojo son las que resultan de un punto de interrupción.
Notará tres líneas "Source Breakpoint" (punto de interrupción en código
fuente) y dos "Breakpoint Message" (mensaje de punto de interrupción).
Todas las otras líneas son interesantes pero distraen un poco, así que
ocultémoslas por ahora. Simplemente haga clic derecho en la ventana de
registro y elija "Properties" (Propiedades). Esto mostrará el diálogo
"Debugger Event Log Properties" (Propiedades del Registro de Eventos del
Depurador).
Fig 4. Debugger Event Log Properties
En el grupo "Messages" (Mensajes) puede desmarcar cualquier casilla para
un mensaje que no desea ver. Simplemente desmarque todas las casillas,
incluyendo la casilla "Breakpoint messages" (mensajes de puntos de
interrupción). La casilla de mensajes de puntos de interrupción es algo
engañosa. En realidad quita las líneas de "Source Breakpoint", dejando
las líneas de mensajes de puntos de interrupción (Breakpoint Message).
También puede cambiar los colores y otra información que le guste. Yo
encuentro que el registro es más fácil de leer para analizar desmarcando
la casilla "Display process info with event" (Mostrar información de
proceso con evento). Si usa su Event Log también para otros propósitos,
recuerde volver a cambiar la configuración a la original cuando haya
terminado.
Ahora, cuando corro el programa, el Event Log se ve como se muestra en
la figura 5. Esperemos que el suyo sea similar.
Fig 5. Event Log conciso
Imagino que estará de acuerdo en que esto es mucho más conciso.
CONSEJO: En vez de usar Inicio y Fin puede encontrar más útiles otros
mensajes. Algunas sugerencias: nombre de la función llamada, número de
línea, objeto siendo accedido, nombre de la consulta ejecutada,
definición del bucle, etc.
Analizando el Rendimiento
-------------------------
Ahora que sabemos como crear entradas en nuestro de eventos, podemos
usar esa característica para analizar el rendimiento de nuestro código.
Mientras que mostrar que se entra y sale de un bloque de código es útil,
eso no es exactamente análisis de rendimiento. Lo que necesitamos es una
medida de tiempo que muestre cuánto tiempo llevó la ejecución de algún
código. Esto puede lograrse usando la característica "Eval Expression"
(evaluar expresión) del punto de interrupción. Vuelva al diálogo "Source
Breakpoint Properties". Esta vez coloque GetTickCount en el cuadro
combinado "Eval Expression".
GetTickCount es una API Win32 que devuelve un cardinal conteniendo el
número de milisegundos desde que la computadora fue iniciada por última
vez. Para la programación en Delphi, esta función se encuentra en la
unidad Windows, así que asegúrese de incluirla en su cláusula Uses.
Mientras que el número devuelto son milisegundos, la resolución en
realidad no está en milisegundos. Si tiene dos llamadas distanciadas
por un par de milisegundos, puede que devuelvan el mismo número. La
resolución puede obtenerse con la API GetSystemTimeAdjustment. Además,
puesto que se usa un cardinal (o DWORD), el valor recomenzará desde
cero cada 49,7 días. No es algo de lo que probablemente se tenga que
preocupar corriendo un sistema operativo MS Windows que haya estado
arriba tanto tiempo, pero es algo a tener en cuenta.
En mi programa añadí GetTickCount a los tres puntos de interrupción,
dejando el Incio y Fin en los dos primeros. Al ejecutar mi programa
nuevamente se genera mucha más información útil en el Event Log.
Fig 6. Event Log con GetTickCount
Las líneas coloreadas con salmón o rosa ahora muestran los resultados
de la evaluación de la expresión. Note que hay dos líneas "Breakpoint
Message", y tres líneas "Breakpoint Expression. Si pusiéramos un
mensaje en el segundo punto de interrupción, algo como "Medio", entonces
tendríamos un número para cada uno. De lo contrario, no tendríamos forma
de asociar el resultado de GetTickCount con un lugar específico del
código. Si en el diálogo "Debugger Event Log Properties" rehabilitamos
los "Breakpoint messages" para que se muestren, tendríamos también el
número de línea. Personalmente prefiero usar mensajes significativos,
incluyendo el número de línea, pero puede usar lo que mejor satisfaga
sus necesidades.
Como podemos ver por estos datos, tomó 1,5 segundos ir del primer
punto de interrupción al segundo., y cerca de 1 segundo para llegar
al tercero. Parece como que tengo algo de optimización que hacer. Si
tiene curiosidad por saber cómo arribé a esos valores, es una simple
cuestión de restar cada número al que le sigue, y dividir por 1000,
redondeando al medio segundo más cercano.
Al usar la característica "Eval Expression" del punto de interrupción,
la expresión evaluada debe estar referenciada globalmente y sólo puede
ser una función que se incluya en su código compilado. Puesto que Delphi
tiene un enlazador optimizante, quita las funciones que no tienen chance
de ser ejecutadas por el programa. GetTickCount es una de esas funciones
que siempre tiene una posibilidad de ser llamada y se incluye ya sea que
la llamemos explícitamente o no, así que siempre está allí. Si usamos
otra función, una que escribamos o una de otra librería o llamada API,
debemos asegurarnos que esté enlazada. Asimismo, cuando llamamos a un
método de un objeto que cambia el valor de un campo, esos cambios puede
que no se hayan llevado a cabo después que termina la evaluación.
Análisis de rendimiento avanzado
--------------------------------
¿Qué hay si no quisiera hacer la resta mentalmente? O tal vez realmente
desea una resolución de 1 milisegundo en su análisis. Esto implica
agregar algo de código a su programa, pero hay un truco para asegurar
que el código no sea incluido en su programa cuando lo construya sin
información de depuración.
En vez de usar GetTickCount podemos usar la rutinas de temporizador de
alto desempeño, también provistas en la API de Windows. Estas rutinas
no son tan directas de usar, así que en vez de colocar complejas Eval
Expressions le sugiero construir algunas funciones para hacer las cosas
más fáciles. Estas funciones también pueden sustraer los valores entre
llamadas.
Las API QueryPerformanceCounter y QueryPerformanceFrequency API acceden
al temporizador de alto desempeño disponible en la mayoría de los
sistemas. Desconozco sobre la situación cuando estos contadores no están
disponibles. Para más información sobre esta funciones API consulte la
MSDN o la documentación del Windows SDK incluida con Delphi. Tenga
presente que usan Int64s en vez de Cardinals, y que son precisas más
allá del milisegundo.
En el archivo ZIP que acompaña este número encontrará mi librería para
usar estas llamadas API. Es muy simple de usar; hay tres funciones:
ElapsedMS, ResetElapsed y UpTimeMS. Añada la unidad JimProfiling.pas a
se cláusula Uses y podrá usar estas funciones en sus Eval Expressions.
ElapsedMS
Muestra cuántos milisegundos transcurrieron desde la última llamada a
ElapsedMS.
ResetElapsed
Resetea el contador de tiempo.
UpTimeMS
Muestra cuántos milisegundos transcurrieron desde que se inició el
programa.
Después de correr su programa tiene algo útil, y bastante preciso, en la
ventana Event Log.
Fig 7. Event Log usando la unidad JimProfiling
Note que la segunda llamada a ElapsedMS tiene un valor menor que la
primera. Esto es porque es el tiempo desde la primer llamada. La
llamada a UpTimeMS es en realidad mayor que la suma de las dos llamadas
a ElapsedMS porque incluye el tiempo anterior a la llamada a
ResetElapsed así como la pequeña cantidad de tiempo posterior a la
segunda llamada a ElapsedMS.
CONSEJO: Si necesita una línea para poner un punto de interrupción para
llamar a ResetElapsed o alguna otra función, sólo agregue una línea
Sleep(0). Aunque esto tenga algún impacto en su programa, debería ser
mínimo. La excepción es si está tratando con múltiples hilos de
ejecución (threads), puesto que cuando llama a Sleep le transfiere la
ejecución a otro hilo.
Todo el código de esta unidad se encierra en directivas {$IFOPT D+}, de
modo que se dejará afuera cuando compile su aplicación sin información
de depuración, así que no necesita acordarse de removerla de su
cláusula Uses. Puesto que el alcance de Eval Expression es global,
puede poner la unidad en cualquier cláusula Uses de su aplicación y aún
así podrá usarla en todas las unidades a lo largo de su proyecto.
Consejos finales
----------------
Si desea conservar su análisis entre sesiones de programación, asegúrese
de usar la opción "Autosave Project Desktop" (Autoguardar Escritorio de
Proyecto). Esto guardará la ubicación de todas sus ventanas así como
cualquier punto de interrupción que tuviera. Puede habilitarla desde la
pantalla "Tools" -> "Environment Options", en la ficha "Preferences"
bajo el encabezado "Autosave Options".
Si no desea que siempre se guarden sus cambios al escritorio, puede
activar esta opción, guardar el proyecto una vez, y luego volverla a
desactivar. Eso tomará una instantánea de las cosas que no cambiarán
cuando se hagan futuros cambios. Estas configuraciones se guardan en el
archivo [proyecto].dsk, que está en formato de texto plano (tipo INI).
Puede editarlo directamente si gusta.
Recuerde que si edita este archivo, y tiene el IDE abierto y
autorguardar habilitado, entonces puede sobrescribir sus cambios.
Además, los puntos de interrupción se rastrean por número de línea, así
que si añade o quita una línea arriba de una línea con un punto de
interrupción, entonces el punto de interrupción puede moverse a una
línea incorrecta.
CONSEJO: Si especifica una condición, entonces el registro sólo se
efectuará si la condición es verdadera.
La pantalla "Breakpoint List" es otro recurso valioso. La mencioné más
arriba como otra forma más de crear puntos de interrupción. Puede ir a
esta pantalla usando el atajo de teclado [CTRL]+[ALT]+[B] o desde el
menú View -> Debug Windows -> Breakpoints.
Fig 8. Breakpoint List
Note que la columna "Action" (Acción) muestra los mensajes y expresiones
que estamos registrando. Puede tener varios grupos de puntos de
interrupción para análisis. Luego, desde el menú contextual puede
habilitar o deshabilitar un grupo entero de puntos de interrupción.
También puede usar la característica Enable / Disable Group de otro
punto de interrupción para activar o desactivar estos grupos como sea
necesario.
CONSEJO: Editar puntos de interrupción (con clic derecho o usando
[CTRL]+[E]) desde esta pantalla le permite moverlos a otras líneas o
archivos. Esto es especialmente útil si tiene acciones complejas
establecidas y no desea recrearlas. También puede establecer múltiples
puntos de interrupción sobre una misma línea usando la opción "Keep
Existing Breakpoint" (Mantener el punto de interrupción existente).
Conclusión
----------
Esta técnica de analizar su código usando el IDE estándar de Delphi y
puntos de interrupción sin interrupción le provee con tiempos de
análisis de ejecución con precisión de 1 ms, altamente confinable a
un fragmento específico del código. Mientras que esto no reemplaza
completamente la necesidad de una herramienta de análisis de código en
su caja de herramientas de programación, le provee con otra poderosa
alternativa para crear programas más rápidos en menos tiempo usando el
poderoso IDE que ya posee.
Referencias
-----------
- "Using Non-Breaking Breakpoints in Delphi" por Cary Jensen
http://bdn.borland.com/article/0,1410,31263,00.html
- "Code Profiling with Non-Breaking Breakpoints" by Jim McKeeth
http://bdn.borland.com/article/0,1410,31905,00.html
- "Non-Breaking Breakpoint Profiling Library 1.0" por Jim McKeeth
http://codecentral.borland.com/codecentral/ccWeb.exe/listing?id=21280
________________________________________________________________________
Ayúdanos a conseguir más suscriptores votando por el Boletín Pascal
(Pascal Newsletter) en estos rankings:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
________________________________________________________________________
3. Presentando YAPI
Por Owen Mooney <owenm at scottech dot net>
http://www.geocities.com/yapisoftware/
Yapi - ahora en la versión 2.
Ahora soy un programador "senior".
Me corté los dientes con Fortran, hice my tesis en Algol-60 (¿alguien
se acuerda de eso? - antes del Pascal) y a principio de los 90 aprendí
a odiar la API de Windows usando Borland C++ y OWL ("'Orrible Windows
Library"). Luego descubrí Delphi y es lo que usé desde entonces.
Lo único que siempre le ha faltado a Delphi, ha sido una herramienta
de impresión decente. Los QReports eran inservibles para impresión
general. Compramos un producto de terceros de Nevrona. Con dedos
temblorosos y entusiastas abrí el manual y comencé a leer. ¡Oh, cielo!
La herramienta nunca se usó. Quedó en el estante por cuatro años hasta
que la tiré a la basura el año pasado. Al final, toda mi impresión la
realicé sobre el lienzo (canvas) de TPrinter. Había escuchado que muchos
programadores Delphi habían hecho lo mismo. No he usado las nuevas
herramientas de D2005 todavía, así que no puedo comentar sobre ellas.
Probablemente no las probaré porque no necesito hacerlo.
Después de unos pocos años de fustración construí mis propias
herramientas de impresión y --si me permiten un momento de
autofelicitación-- ¡son las mejores!
Diseño - La programación
------------------------
Quería que las nuevas herramientas fueran fáciles de usar, que siguieran
el más importante principio Delphi: simplicidad. Después de algunos años
de lidiar con C++ para Windows me crucé con Delphi y dije "¡Ah - Sí! Así
es como debe ser." Quería que mis herramientas de impresión evocaran esa
reacción. No sólo deberían ser más simples que otras herramientas de
impresión, sino MUCHO más simples - ¡deberían ser fenomenales!
Comencé por principios básicos.
En los viejos tiempos programábamos reportes más o menos así:
writeln(printer,' Mi Gran Reporte'); // Centrado
writeln(printer); // Línea vacía
writeln(printer,'La primera línea');
for i := 0 to count - 1 do begin
writeln(printer,'El dato para la línea ',i,' ',Data[i]);
end;
Con cada writeln el cabezal de la impresora matricial cobraba vida y
recorría el ancho de la página, aportando lo suyo a la contaminación
sonora de la oficina.
Mientras la tecnología puede parecer muy cruda para los estándares de
hoy, programar este tipo de cosas era fácil. Esto es por una muy
importante razón: Un reporte muy complejo podía contener cientos de
writes y writelns, pero el flujo de código seguía el flujo general del
reporte. Esta correspondencia hacía la programación fácil tanto de
escribir como de seguir. Puede ver un reporte e imaginarse cómo estaría
codificado, y podía ver el código e imaginar el reporte.
Esta metodología se cae a pedazos con impresoras modernas y el
requerimiento de proveer una vista previa de impresión. Herramientas
como QReports y otras tienden a tener una estructura que ejecute
sentencias SQL o llame a código de evento escrito por el usuario. El
flujo de la ejecucución es controlado por el código de ellos, no por
el suyo. Todo lo que usted obtiene son algunos eventos. Si tiene un
reporte complejo, lo que obtiene es una "explosión de complejidad" a
medida que su código intenta recordar qué cosa sucede cuándo. No sé
usted, pero yo me di por vencido.
Yapi provee el mismo flujo lógico del viejo writeln. En Yapi, el
código equivalente al viejo código de arriba es:
Paper.clear;
Header.writeln('Mi Gran Reporte'); // Centrado, pero sin contar espacios
Header.writeln;
Body.writeln('La primera línea');
for i:=0 to count-1 do begin
Body.write('El dato para la línea ');
Body.writeattab(inttostr(i),1);
Body.writeattab(inttostr(Data[i]),2);
end;
Paper.preview;
Ese es todo el código requerido para imprimir el equivalente a la vieja
impresión matricial, pero por supuesto con márgenes, bellas fuentes,
encabezados y pies de página, paginación automática y una muy buena
pantalla de vista preliminar.
Diseño - El formateo
--------------------
Bien, por supuesto que la gente espera control WYSIWYG sobre la
disposición de la página, fuentes, tabulaciones y otros formatos. No soy
tan tonto como para proveer otra cosa.
Yapi provee varios componentes para esto, como sigue:
El componente Paper:
Provee configuración WYSIWYG para toda la estructura del reporte. Se
configuran los márgenes y las tabulaciones, así como la orientación del
papel. Típicamente las dimensiones están en milímetros, pero también se
pueden proveer pulgadas.
El componente Paper muestra todos estos detalles en tiempo de diseño,
pero es invisible en tiempo de ejecución.
El componente Text:
Los componentes Text se usan para establecer las fuentes para los
reportes (incluyendo su color). Se usan para el grueso de la impresión.
El componente Tab:
Éstos establecen las tabulaciones. Pueden ser arrastrados a la posición,
o puede establecerse su posición (en milímetros o pulgadas). También se
provee tabulación dinámica por código.
Estos tres componentes son el conjunto básico.
Probándolo
----------
Vayamos al corazón del asunto. ¿Cómo hacer que se imprima algo y cuán
fácil es iniciarse? Bien, los pasos absolutos más simples son como
sigue:
1. Arrastre un componente Yapi Paper a su formulario
2. Arrastre un componente Yapi Text al papel
3. Agregue un botón al formulario. En su evento OnClick añada tres
líneas de código:
YapiPaper1.clear;
YapiText1.writeln('Hola Mundo');
YapiPaper1.preview;
Eso es todo. Ejecute el programa, presione el botón y tiene una
pantalla de vista previa, y otro botón en la pantalla de vista previa
realiza la impresión. Los documentos tienen un tutorial de 5 minutos,
que hace más o menos esto. Si no puede hacer esto en 5 minutos, tiene
una promisoria carrera como tejedor de canastas.
Más componentes
---------------
Los tres componentes de arriba (disponibles como conjunto gratuito) le
permiten realizar casi cualquier generación de impresión basada en
texto. Por supuesto, la gente quiere más. Otros componentes son:
* Un componente encabezado y pie (un componente hace ambos)
* Un componente cuadrícula (grid) para hacer reporte como un stringgrid
o un dbgrid
* Un componente imagen para hacer mapas de bits (las imágenes pueden
determinarse en tiempo de diseño o de ejecución)
* Un componente paintbox
* Un componente db report
El componente encabezado y pie hace (por supuesto) números de página.
Producir una cuadrícula fue un problema de diseño realmente interesante.
¿Cómo programa uno una cuadrícula sin contradecir la bella filosofía de
diseño que ya tenía? La respuesta vino después de algunas cervezas (en
realidad ese es un inserto colorido para aliviar el aburrimiento de lo
que de otro modo es una seca disertación técnica). El componente de
cuadrícula de texto es como un componente de texto ordinario, pero
dibuja una caja alrededor de sí mismo. Ponga dos cajas, y sus lados
adyacentes se una para formar una línea. Ponga unos abajo de otros, y
los lados superiores e inferiores se unen en una sola línea de
cuadrícula. Ponga filas y columnas juntas y "hey presto" - ¡una
cuadrícula! Todo esto hace que las cuadrículas sean tan fáciles como
texto tabulado ordinario.
El componente imagen era también una razonablemente obvia inclusión,
pero aún quedaba un último desafío de impresión - ¿cómo trataría Yapi
con texto y gráficos arbitrarios? La respuesta vino como la Yapi
PaintBox, la que opera con TODOS los métodos existentes de TCanvas.
En este punto, algún gnomo como programador comentará: "¡Oye bobo! Si
programas yapiPaintbox como un objeto Canvas, ¿por qué no usar el canvas
de TPrinter?" La respuesta es simple: "¡Porque la yapiPaintbox también
provee vista preliminar!'
Con la V2 se incluye un db report. Esto es realmente sólo para aquellos
programadores que creen que uno debería arrastrar y soltar todo un
programa y protestar agriamente a todas y cada una de las líneas de
código que tengan que escribir. Este componente produce un reporte a
partir de una TQuery o una TTable con una sola sentencia:
yapidbreport.open
He provisto el db report como una unidad objeto separada. Esto impide
que el código de bases de datos de Delphi se enlace en programas que no
son de bases de datos.
Implementación
--------------
Bueno... ¡No fue fácil!
Con cada write o writeln, Yapi crea un "token" para representar el
elemento impreso. Almacena y luego usa esos tokens para renderizar
la página relevante en la vista previa de impresión, o en el canvas de
TPrinter. Suena fácil, ¿no?
Cada token es un objeto. Se usó herencia para generalizar el código lo
más posible.
La jerarquía de clases para los tokens relevantes es:
TyapiObject - Clase abstracta; maneja mucho del procesamiento
TyapiTextObject - Puede ser un texto o una cuadrícula de texto
TyapiGraphicObject - Puede ser una imagen o un paintbox
Cada uso de write o writeln genera un nuevo token para representar un
elemento en el reporte.
En la codificación inicial todos esos componentes se almacenaban en un
arreglo en el componente Paper, pero tenía una explosión de complejidad.
Hora de hacer trizas el código y comenzar de nuevo. Añadí una nueva
clase por cada línea y la complejidad quedó bajo control.
En esta segunda versión cada write o writeln añade un nuevo token en el
objeto de la línea actual. Además, cada writeln completa el objeto de la
línea actual y comienza una nueva. Las líneas se almacenan en un arreglo
dinámico dentro del objeto Paper.
Los componentes en sí han sido creados una forma bastante estándar. El
componente Paper hereda de TCustomPanel y opera como un contenedor de
líneas, así como una herramienta para configurar el reporte. Tab,
paintbox e image heredan del componente TGraphicControl. Tanto text como
grid-text heredan de una clase base abstracta común, que a su vez hereda
de TCustomLabel.
Estuve muy agradecido que Borland proporcionara el código fuente de la
VCL. Me arrastré bastante por él para ver cómo se hacían las cosas.
La vista previa de impresión
----------------------------
La vista preliminar de impresión es un formulario Delphi estándar. La
impresión se renderiza en un TPaintbox.
La vista previa de impresión hace lo que esperaría. Seleccionar número
de página, aumento/disminución de tamaño, selección de impresora,
selección de rango de páginas - todo eso se provee.
Además tiene un par de lindos trucos. El primero es la habilidad de
controlar líneas viudas y huérfanas. Una característica única de la
vista preliminar de Yapi es la capacidad de cambiar tabulaciones y
márgenes en tiempo de ejecución, en la ventana de vista previa. Esa
maldita línea al pie puede ser eliminada simplemente estirando el margen
inferior de la página hacia arriba. La línea desaparece y aparece en la
página siguiente.
Otro truco de la pantalla de vista previa es guardarla en un archivo.
Hay dos opciones: si la guarda en un archivo con extensión .csv, eso es
lo que obtiene. Las tabulaciones del reporte se usan para separar las
columnas del archivo csv. Si la guarda en un archivo .bmp, obtiene la
página actual como un mapa de bits. Elegí el formato de salida bmp
porque es el soportado por la VCL básica. Esto significa que no tendrá
problemas de enlazamiento.
Si necesita salida a un archivo pdf, entonces le sugiero obtener un
driver de impresión pdf.
Conclusión
----------
Sólo porque Yapi es muy fácil de usar no la confunda por una herramienta
cruda. Hay muchos trucos sutiles tras bambalinas para hacer su vida más
fácil (por ejemplo ajuste de línea, ajuste en una cuadrícula de texto y
manejo de memo.text para mencionar unos pocos).
Échele un vistazo a algunos de los reportes de muestra (por ejemplo
FishFacts.pdf) en la página web. Son ejemplos PDFs usando el driver de
impresión PDF.
La Yapi básica está disponible gratis. Tiene lo básico, pero aún así es
una herramienta útil.
Visite http://www.geocities.com/yapisoftware/
A propósito, Yapi es un acrónimo de "Yet Another Printer Interface."
________________________________________________________________________
InstallAWARE 3.0 para Windows Installer por MimarSinan International
Oferta especial: 30% de descuento en la Enterprise Edition, sólo $559.95
InstallAWARE es la siguiente generación en herramientas de autoría de
instaladores con características únicas como distribución web parcial,
avisadores de progreso Flash y HTML, diez temas de instalación
llamativos, diálogos de instalación completamente configurables, y un
lenguaje de instalación que automáticamente se convierte en archivo de
Windows Installer. >>> http://www.installaware.com/landingea.html <<<
________________________________________________________________________
4. Estableciendo el manejador de eventos predeterminado de un componente
Por Peter Johnson, Copyright (c) 2004
<delphidabbler at tiscali dot co dot uk>
http://www.delphidabbler.com/
¿Por qué este artículo?
-----------------------
Cuando hace doble-clic en la mayoría de los componentes Delphi en tiempo
de diseño, el IDE automáticamente crea un manejador de evento vacío para
el evento predeterminado. A veces necesita que un evento diferente sea
el predeterminado. El propósito de este artículo es explicarle cómo
hacer eso (hay más información sobre este tema en el archivo de ayuda de
Delphi 7, pero el ejemplo que allí se provee es incorrecto).
Hagamos esto un poco más concreto considerando estos tres componentes:
type
TCompA = class(TComponent)
private
fOnFoo: TNotifyEvent;
fOnBar: TNotifyEvent;
fOnClick: TNotifyEvent;
fOnChange: TNotifyEvent;
fOnChanged: TNotifyEvent;
fOnCreate: TNotifyEvent;
published
property OnFoo: TNotifyEvent read fOnFoo write fOnFoo;
property OnBar: TNotifyEvent read fOnBar write fOnBar;
property OnChange: TNotifyEvent read fOnChange write fOnChange;
property OnChanged: TNotifyEvent read fOnChanged write fOnChanged;
property OnClick: TNotifyEvent read fOnClick write fOnClick;
property OnCreate: TNotifyEvent read fOnCreate write fOnCreate;
end;
TCompB = class(TComponent)
private
fOnFoo: TNotifyEvent;
fOnBar: TNotifyEvent;
fOnChange: TNotifyEvent;
published
property OnFoo: TNotifyEvent read fOnFoo write fOnFoo;
property OnBar: TNotifyEvent read fOnBar write fOnBar;
property OnChange: TNotifyEvent read fOnChange write fOnChange;
end;
TCompC = class(TComponent)
private
fOnFoo: TNotifyEvent;
fOnBar: TNotifyEvent;
published
property OnFoo: TNotifyEvent read fOnFoo write fOnFoo;
property OnBar: TNotifyEvent read fOnBar write fOnBar;
end;
Haciendo doble-clic en los componentes en el Delphi IDE se crean los
siguientes manejadores de evento:
* TCompA: OnCreate
* TCompB: OnChange
* TCompC: OnBar
Supongamos que quisiéramos que el evento OnFoo sea el creado en todos
los casos. Veremos como hacerlo durante en el curso de este artículo.
Algo de base
------------
Antes que podamos resolver nuestro problema necesitamos examinar cómo
Delphi 7 decide cuál evento usar como predeterminado (las cosas son un
poco diferentes en Delphi 4 - tal como veremos después).
Cuando se hace doble-clic a un componente, Delphi llama al método Edit
del editor de componente registrado. El editor de componente registrado
predeterminado es TDefaultEditor y es éste editor el responsable de
crear el manejador de evento. Ahora examinemos cómo TDefaultEditor.Edit
decide cuál es el evento predeterminado.
Tras pasar por un proceso, en última instancia el método Edit llama al
método TDefaultEditor.EditProperty una vez por cada propiedad del
componente. En vez de pasar a EditProperty una referencia a la propiedad
misma, lo que se le pasa es una referencia al editor de propiedad
asociado. EditProperty chequea el nombre por cada propiedad de evento
y guarda el editor de propiedad del evento preferido. Estos eventos, en
orden de preferencia, son:
* OnCreate
* OnChange
* OnChanged
* OnClick
* el primer evento alfabéticamente
Esto significa que si un evento OnCreate está presente, se usa como el
predeterminado. Si no está presente, se usa el evento OnChange y así.
sucesivamente. Si no está presente ninguno de los eventos de la lista,
se usa el primero por orden alfabético.
Redefiniendo el comportamiento predeterminado
---------------------------------------------
De la discusión anterior queda claro que si hemos de especificar el
evento predeterminado, tendremos que cambiar la formar en que trabaja
TDefaultEditor.EditProperty. Afortunadamente para nosotros, este método
es virtual, así que podemos derivar TDefaultEditor y redefinir
EditProperty. La nueva clase puede ser declarada muy simplemente como
sigue:
type
TMyCompEditor = class(TDefaultEditor)
protected
procedure EditProperty(const PropertyEditor: IProperty;
var Continue: Boolean); override;
end;
La implementación es igualmente directa:
procedure TMyCompEditor.EditProperty(const PropertyEditor: IProperty;
var Continue: Boolean);
begin
// only call inherited method if required event name
if CompareText(PropertyEditor.GetName, 'OnFoo') = 0 then
inherited;
end;
Ahora examinemos cómo trabaja. Recuerde que en la clase base el
método TDefaultEditor.EditProperty es llamado una vez por cada
propiedad del componente. El método elige el evento predeterminado
entre los que le son pasados. Ahora, si TDefaultEditor.EditProperty
es llamado una sola vez, entonces el evento predeterminado será aquel
cuyo editor de propiedad sea pasado en esa única llamada.
Nuestro método redefinido trabaja asegurándose que el método heredado
sea llamado sólo una vez - para el evento que queremos que sea el
predeterminado. En nuestra clase descendiente, es el método
TMyCompEditor.EditProperty el que es llamado por cada propiedad del
componente. El método simplemente comprueba si el editor de propiedad
tiene el nombre requerido ('OnFoo') y pasa ese editor de propiedad
-y sólo ese editor de propiedad- al método heredado. ¡Y voilá - OnFoo
es el evento predeterminado!
Una solución reutilizable
-------------------------
En el código que desarrollamos en la sección previa, el nombre del
evento predeterminado es fijo, o -como se dice en la jerga- está
"cableado", término derivado del inglés "(hard-)wired".
Nuestro siguiente trabajo es generalizar la solución para hacer más
fácil de reutilizar el código. Puesto que las clases sólo se distinguen
por el nombre del evento predeterminado que seleccionan, desarrollaremos
una clase base que tienen un método abstracto que las descendientes
pueden redefinir para devolver el nombre del evento requerido.
Esta es la declaración de la clase base:
type
TCompEditorBase = class(TDefaultEditor)
protected
function DefaultEventName: string; virtual; abstract;
{ override to return name of default event }
procedure EditProperty(const PropertyEditor: IProperty;
var Continue: Boolean); override;
{ records property editor of default event }
end;
La implementación no debería ser sorpresa - simplemente reemplazamos
el nombre que estaba cableado en la clase anterior por una llamada al
método abstracto:
procedure TCompEditorBase.EditProperty(
const PropertyEditor: IProperty;
var Continue: Boolean);
begin
if CompareText(PropertyEditor.GetName, DefaultEventName) = 0 then
inherited;
end;
Ahora podemos implementar un editor de componente para un evento
predeterminado específico -nuesto viejo amigo OnFoo otra vez-
simplemente redefiniendo el método abstracto DefaultEventName como
sigue:
type
TCompEditor = class(TCompEditorBase)
protected
function DefaultEventName: string; override;
end;
...
function TCompEditor.DefaultEventName: string;
begin
Result := 'OnFoo';
end;
Arrelgos finales
----------------
Para que estos ejemplos compilen necesitamos usar las unidades Classes,
SysUtils, DesignIntf y DesignEditors. Note que las dos últimas sólo
pueden usarse al integrar con el IDE - no pueden usarse en aplicaciones
independientes.
También necesitamos registrar el editor de componentes en el
procedimiento Register de nuestra unidad como sigue:
procedure Register;
begin
RegisterComponentEditor(TCompA, TCompEditor);
// etc ...
end;
Diferencias con Delphi 4
------------------------
En Delphi 4, TDefaultEditor.EditProperty tiene un prototipo diferente.
Se lo declara como:
procedure EditProperty(PropertyEditor: TPropertyEditor;
var Continue, FreeEditor: Boolean);
Podemos tratar con esto usando compilación condicional. Asumiendo que
está definido el símbolo DELPHI6ANDUP cuando usamos Delphi 6 o superior,
podemos implementar el procedimiento TCompEditorBase.EditProperty como
sigue:
procedure TCompEditorBase.EditProperty(
{$IFDEF DELPHI6ANDUP}
const PropertyEditor: IProperty; var Continue: Boolean
{$ELSE}
PropertyEditor: TPropertyEditor; var Continue, FreeEditor: Boolean
{$ENDIF}
);
begin
if CompareText(PropertyEditor.GetName, DefaultEventName) = 0 then
inherited;
end;
Adicionalmente necesitamos reemplazar las unidades DesignIntf y
DesignEditors por DsgnIntf:
uses
Classes, SysUtils,
{$IFDEF DELPHI6ANDUP}
DesignIntf, DesignEditors;
{$ELSE}
DsgnIntf;
{$ENDIF}
Resumen
-------
En este artículo hemos visto como cambiar el manejador de evento
predeterminado que se abre en el IDE cuando se hace doble-clic en un
componente.
Primero examinamos la manera en la que Delphi decide cuál evento usar
para este propósito y luego desarrollamos una subclase de TDefaultEditor
que puede especificar explícitamente el evento predeterminado. Luego
procedimos a generalizar la solución desarrollando una clase base
abstracta para editores de componentes que modifica el evento
predeterminado.
La discusión principal cerró con un repaso de las unidades requeridas
para compilar las nuevas clases y dimos una mirada a como registrar el
editor de componentes.
Finalmente discutimos los cambios necesarios para compilar el código
con Delphi 4.
Código demo
-----------
Si quiere experimentar con este código, el archivo ZIP adjunto que
acompaña esta edición contiene código demostrativo que implementa los
componentes de ejemplo y los editores de componentes tratados en este
artículo.
__________________
Peter Johnson es un programador hobbyista que vive en West Wales (Reino
Unido) y que "chapotea" en Delphi. Mantiene el sitio web DelphiDabbler
(http://www.delphidabbler.com/) donde publica sus artículos y sus
aplicaciones y componentes Delphi gratuitos. Una versión completa de
este artículo se encuentra disponible en:
http://www.delphidabbler.com/download.php?file=article-17-demo.zip
________________________________________________________________________
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
________________________________________________________________________
5. Antivirus en Delphi: aRC-Anti WODE.JPG 1.0
Como les había prometido hace un par de números atrás, presentamos un
nuevo aporte que nos envía Furious Login desde Lima, Perú.
En esta oportunidad se trata de un antivirus específico para el gusano
conocido popularmente como WODE.JPG o también conocido como virus de la
china (o de la japonesa). Pueden encontrarse referencias de este virus
bajo los nombres W32/Rayl.A, W32/Rayl.A.worm, Win32/Elomon.worm.48644,
W32.Seone.A, AdClicker-BD, Exploit.HTML.Mht, Worm.MSN.Elon.a o
TrojanDownloader.Win32.Delf.ed según la fuente.
El virus brotó en septiembre del año pasado, y se propagaba mediante
MSN, pero no se transmitía por el MSN, sino que mostraba al contacto de
la persona con la PC infectada un enlace para ver una imagen wode.jpg
en un sitio de Internet. Al hacer clic en el enlace no se bajaba
directamente una imagen, sino una página web que contenía la imagen...
¡y algo más! Aprovechando una vulnerabilidad conocida, la página incluía
un IFRAME desde el que se bajaba otra página, la que contenía código en
Visual Basic Script (VBS) que a su vez bajaba un archivo en formato CHM
que se ejecutaba inmediatamente en la zona de seguridad local, y a
partir de allí el resto naturalmente era historia: el archivo CHM
extraía su carga útil, un archivo ejecutable, y lo ejecutaba; a su vez
este ejecutable extraía otros dos archivos ejecutables y procedía a la
infección.
El programa Delphi que les presento aquí (se incluye en el archivo
adjunto con el código fuente correspondiente a este número) fue escrito
originalmente en C++ Builder 6.0 y fue distribuido antes que la mayoría
de los más importantes antivirus pudieran detectar y eliminar el virus.
El programa hace exactamente lo que realizan los programas de este
tipo:
1) Detectar la presencia del virus.
2) Terminar los procesos relacionados con el virus.
3) Eliminar los archivos del virus.
4) Eliminar las entradas usadas por el virus para
ejecutarse al iniciar Windows.
Para detectar la presencia de la infección se busca entre los procesos
en ejecución para determinar si alguno de ellos corresponde al virus.
En vez de la API EnumProcesses, este programa ilustra el uso de las API
Toolhelp32Snapshot, Process32Next y CloseHandle para idéntico propósito.
Habiendo determinado que un proceso corresponde a un virus, el programa
hace uso de la API OpenProcess para obtener el handle con el cual llamar
a TerminateProcess para terminar el proceso.
ADVERTENCIA: La aplicación MSN Messenger es también terminada de
modo abruto. Perderá las conversaciones y datos que
no hubiera guardado. Se recomienda que usted cierre
manualmente el MSN Messenger antes de ejecutar este
programa.
El programa luego busca y elimina los archivos principales y temporales
del virus, y finalmente elimina la entrada en el registro de Windows que
permite la ejecución del virus cuando Windows se inicia.
ADVERTENCIA: Como toda aplicación que elimina archivos del disco
duro y elimina entradas en el Registro de Windows,
debe tomar sus recaudos antes de utilizarla.
El programa pude ser adaptado para remover otros virus y gusanos que
usan procesos de infección similares.
________________________________________________________________________
Ayúdanos a conseguir más suscriptores votando por el Boletín Pascal
(Pascal Newsletter) en estos rankings:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
________________________________________________________________________
6. Foros / listas de correo
Recordamos a los suscriptores las direcciones de nuestros foros. Para
unirse a algún foro, lo más recomendable es hacerlo desde la web para
así tener acceso a todas las áreas del foro y la configuración de las
opciones de suscripción, pero también es posible suscribirse por email.
Para suscribirse desde la web es necesario poseer un ID de Yahoo! (si
no tienes el tuyo, puedes conseguirlo gratis registrándote como usuario
de Yahoo!).
* Delphi-abierto. Programación en Delphi (todos los niveles). Si estás
en la etapa de aprendizaje o si no te agradan los foros discriminados
por niveles, este foro es para ti.
http://espanol.groups.yahoo.com/group/delphi-abierto
Suscripción:
http://espanol.groups.yahoo.com/group/delphi-abierto/join
delphi-abierto-subscribe@gruposyahoo.com
* Delphi-intermedio. Programación en Delphi (nivel intermedio). Si ya
sabes mucho de Delphi, pero todavía te falta un largo trecho para ser
un gurú (o no tanto), este foro es para ti.
http://espanol.groups.yahoo.com/group/delphi-intermedio
Suscripción:
http://espanol.groups.yahoo.com/group/delphi-intermedio/join
delphi-intermedio-subscribe@gruposyahoo.com
* Delphi-avanzado. Programación en Delphi. Sólo para gurús.
http://espanol.groups.yahoo.com/group/delphi-avanzado
Suscripción:
http://espanol.groups.yahoo.com/group/delphi-avanzado/join
delphi-avanzado-subscribe@yahoogroups.com
* GrupoKylix. Programación en Kylix.
http://espanol.groups.yahoo.com/group/GrupoKylix
Suscripción:
http://espanol.groups.yahoo.com/group/GrupoKylix/join
GrupoKylix-subscribe@yahoogroups.com
* FreePascal-es. Programación en Free Pascal (freepascal.org).
http://espanol.groups.yahoo.com/group/freepascal-es
Suscripción:
http://espanol.groups.yahoo.com/group/freepascal-es/join
freepascal-es-subscribe@yahoogroups.com
* Desarrolladores-Software. Un lugar para tratar todos aquellos temas
relacionados con el desarrollo de software y su comercialización, y
para compartir experiencias en el ámbito laboral, profesional o
comercial con otros.
http://es.groups.yahoo.com/group/desarrolladores-software
Suscripción:
http://es.groups.yahoo.com/group/desarrolladores-software/join
desarrolladores-software-subscribe@yahoogroups.com
* Componentes. Un foro para buscar/recomendar componentes de software
(componentes VCL y CLX, objetos ActiveX, librerías DLL, etc.), así
como utilidades, tutoriales, información, etc.
http://espanol.groups.yahoo.com/group/componentes
Suscripción:
http://espanol.groups.yahoo.com/group/componentes/join
componentes-subscribe@yahoogroups.com
________________________________________________________________________
KnowedgeBASE Vortex 2.9 por Delphinium Software ($49.35 US)
KnowledgeBASE Vortex presenta un árbol de información altamente
buscable y expandible, que puede verse como esquema o auditado
dentro del procesador de textos incorporado en la aplicación.
Incluye una base de datos para referencias almacenadas.
http://www.programurl.com/knowledgebase-vortex.htm
________________________________________________________________________
7. Delphi en la Red
Por Dave Murray <irongut at vodafone dot net>
Componentes, librerías y aplicaciones
=====================================
Freeware
--------
* Clearer v1.7 - by Mauro Venturini (with source)
History is a great new feature of Delphi 2005. There is only a little
drawback: after project completion getting rid of all the history
files is a bit annoying. Clear makes this more easy. It also takes
care of .NET local storage accumulation due to version changes.
http://www.torry.net/tools/developers/other/Clearer1.6Clearer.zip
* Delphi Scintilla Interface Components v0.16 - Jan Pettersen (w source)
Use the Scintilla Project Syntax Highlighting edit control with Delphi
Define your own languages based on the lexers in the SciLexer.dll
(Scintilla Project), with the styles and keywords needed directly from
the Delphi designer. Tested with Delphi 7.
http://delphisci.sourceforge.net/
* Graphics32 v1.7 - by Graphics32 Team (open source, MPL)
Graphics32 is a library designed for fast 32-bit graphics handling on
Delphi and Kylix. Optimized for 32-bit pixel formats, it provides fast
operations with pixels and graphic primitives, and in most cases
Graphics32 outperforms the standard TCanvas classes. It is almost a
hundred times faster in per-pixel access and about 2-5 times faster in
drawing lines.
http://graphics32.org/
* PUses v2.2 - by Mauro Venturini (with source)
PUses implements orderly reformatting of uses clauses, including:
rewriting the unit/namespace names one per line and sorting them;
optionally adding the prefix unit (generated using PrefiIt!) names.
Supports Delphi 2005 only.
http://www.torry.net/tools/other/ide/PUses.zip
* TTrimmingLabel v1.0 - by Mauro Venturini (with source)
TTrimmingLabel is a Windows Forms label that can trim the Text string
to adapt it to the available Width. The trimming is controlled by the
Trimming property (of type System.Windows.Forms.StringTrimming).
Supports Delphi 2005 only.
http://www.torry.net/vcl/labels/enhancedlabels/TrimmingLabel.zip
* Undo/Redo for TeeChart Pro VCL v1.02 - by Ivo Ungermann (with source)
Component for limited or unlimited undo / redo function with TChart
(part of TeeChart Pro VCL package from Steema Software). Automatically
traced TChart events: Zoom, Unzoom, Scroll. Other chart changes traced
with a bit of code. Tested with TeeChart Pro 7 VCL, Delphi 5 - 7.
http://www.torry.net/vcl/charts/charts/TChartUndoRedo.zip
* sTile v2.7 - by harmware
A graphics program to create seamless 'tiles' which can be used as
background images for web pages and applications. It has many filters
and effects and is a fun little program to play with. By nature, it
produces somewhat psychedelic images, but they can be toned down or
muted for actual use. Samples on the web site include a brick wall.
http://www.harmware.com/stile.htm
Actualizaciones de productos Borland
------------------------------------
* Public Beta: Delphi 8 Update 3
This patch is designed to correct issues with .NET versioning for
Delphi 8. This is a dcu breaking change. Version calculation for
dcuils and dcpils has been updated to depend on symbol names rather
than values of metadata tokens imported from .NET assemblies. This
fixes errors that users have been experiencing with updating their
service packs for NET 1.1 and will prevent any further issues.
http://community.borland.com/article/0,1410,32873,00.html
* Delphi 2005 Update 1 Now Available
This update makes Delphi 2005 rock solid!
http://community.borland.com/article/0,1410,32875,00.html
Artículos, trucos y consejos
============================
* BDNradio: Database Features of Delphi 2005 with Ramesh Theivendran and
Joerg Weingarten
Read the chat log and listen to the replay of the live interview with
Ramesh and Joerg on Delphi 2005 database features.
http://community.borland.com/article/0,1410,32925,00.html
* BDNradio: VCL and VCL for .NET in Delphi 2005 with Seppy Bloom and
Danny Thorpe
Listen to the replay and read the chat room log of the live interview
with Danny and Seppy.
http://community.borland.com/article/0,1410,32924,00.html
* BDNradio: Unit Testing in Delphi 2005 with Mark Edington
Listen to the replay and read the chat room log of Mark Edington's
live chat on unit testing support in Delphi 2005.
http://community.borland.com/article/0,1410,32920,00.html
* BDNradio: .NET data remoting in Delphi 2005 with Ramesh Theivendran
Read the chat log and listen to the live chat with Ramesh on the easy,
flexible, and powerful way to develop .NET data remoting applications
in Delphi 2005.
http://community.borland.com/article/0,1410,32917,00.html
* BDNradio: Debugging in Delphi 2005 with Chris Hesik
Listen to the replay and read the chat room log of Chris Hesik's
interview on debugging in Delphi 2005.
http://community.borland.com/article/0,1410,32923,00.html
* BDNradio: Web Development in Delphi 2005 with Jim Tierney and
Steve Trefethen
Read the chat log and listen to the replay of this live chat with Jim
and Steve on Delphi 2005's web development support.
http://community.borland.com/article/0,1410,32881,00.html
* Recursions in Delphi - by Zarko Gajic
Recursion is a very simple, yet useful and powerful programmer's tool.
Subroutines can, and frequently do, call other subroutines, a
subroutine that activates/calls itself is called recursive. Recursion
is a general method of solving problems by reducing them to simpler
problems of a similar type. Many programmers often avoid this type of
subroutine because it can be confusing and complicated. This article
is going to make recursion in Object Pascal simple ... I hope.
http://delphi.about.com/od/objectpascalide/l/aa120799a.htm
* Graphical Combos - by Zarko Gajic
Creating owner drawn Combo Boxes in Delphi. See how to code a
graphical drop-down list; examples include a combo box of colours and
a true-type font picker.
http://delphi.about.com/od/vclusing/l/aa101700a.htm
Tutoriales y capacitación
=========================
* An Introduction to COM Programming with Delphi (6/6) - by Curtis Socha
Type Library: pros and cons, 5 steps to a Type Library, a look into
the TLB Abyss.
http://delphi.about.com/library/weekly/aa122804a.htm
* Resource Files Made Easy - by Zarko Gajic
Part 1 of a series of articles, explains how Delphi uses standard
Windows-format resource files: icons, bitmaps and cursors.
http://delphi.about.com/od/objectpascalide/l/aa113099a.htm
* Inside the EXE - by Zarko Gajic
Part 2 of a series of articles, this article will show you how to
store (and use) sound files, video clips, animations and any kind of
binary files in a Delphi executable.
http://delphi.about.com/od/objectpascalide/l/aa021301a.htm
* Web Site inside a Delphi EXE - by Zarko Gajic
Part 3 of a series of articles, shows how HTML and associated files
(pictures) can easily be included within a Delphi application.
http://delphi.about.com/od/objectpascalide/l/aa113099a.htm
* Creating and Using a Resource Only DLL with Delphi - by Zarko Gajic
Fourth article in the series about storing more than just executable
code inside a Delphi application. This part shows how to create a
dynamic link library containing only resources.
http://delphi.about.com/od/objectpascalide/l/aa113099a.htm
* Localizing Delphi Applications using StringTable Resources - Z. Gajic
Part 5 in a series of articles, while resource files enable storing
more than just program code in an EXE file, by including stringtable
resources to an application a Delphi developer can easily build
multilanguage applications. Learn how.
http://delphi.about.com/library/weekly/aa011805a.htm
Noticias
========
* Borland Going After Services Revenue
Services are destined to play a greater part in Borland's future as
the company assists customers around Application Lifecycle Management.
http://www.cbronline.com/article_news.asp?
guid=B1DA308B-4561-4A9B-83EE-F4D4EFAA07E8
* Borland Purchases Brains to Drive SDO
Borland has made its first corporate purchase in two years, acquiring
software process consulting specialist TeraQuest Metrics Inc. Borland
plans to integrate TeraQuest's expertise, encapsulated in templates
for activities such as change management, project planning and
requirements gathering, into its ALM tools, processes and services.
http://www.cbronline.com/article_news.asp?
guid=C5F6EE17-B508-432B-987B-F274EC223A20
* Borland Schedules Q4 and Year End 2004 Conference Call and Webcast
Borland today announced that its fourth quarter and year end 2004
teleconference and simultaneous Webcast is scheduled to begin at
2:30 p.m. Pacific Time, on Tuesday 1st February 2005.
http://www.tmcnet.com/usubmit/2005/Jan/1106470.htm
* Firebird Database Readies SMP Release
Firebird developers are due to do an alpha release of version 2.0 of
the open source database later this month and have completed work on
SMP support, which is due to be released in late spring.
http://news.zdnet.co.uk/software/0,1000000121,39183292,00.htm
Otros / Sitios misceláneos
==========================
* New BDN Feature: Community Calendar
At the BorCon 2004 closing session, one of the new BDN applications
launched was a community calendar, code named EventCentral. Any BDN
member can use EventCentral to post events of interest to Borland
customers anywhere around the world. Events must be approved by a
sysop to be publicly visible.
http://community.borland.com/article/0,1410,32936,00.html
* CodeFez Blogs
Blogs by Charlie Calvert, Julian Bucknall, Lino Tadros, Nick Hodges
and Steve Teixeira. Topics include software development, Delphi and
other Borland tools.
http://www.codefez.com/Default.aspx?tabid=79&newsType=NewsListing
* PGD DogFight Game Programming Competition
DelphiGamer.com recently relauched and will soon be known as "Pascal
Game Development" or PGD for short. To coincide with the relaunch, a
themed game programming competition has been announced.
http://www.pgd.netstarweb.com/viewtopic.php?t=1747
________________________________________________________________________
Irongut's Delphi Pages
Dedicada a la programación con Borland Delphi y Kylix. Tenemos artículos
sobre programación, noticias Borland y Delphi, código fuente y componen-
tes para usar en sus aplicaciones y más. http://www.paranoia.clara.net/
________________________________________________________________________
¡Tú puedes ayudarnos!
Por favor danos una mano y ayúdanos a llegar a los 20.000 suscriptores
en los próximos meses. Una forma en que puedes ayudarnos es enviando
este enlace a tus amigos:
http://www.latiumsoftware.com/es/pascal/index.php
boletin-pascal-subscribe@gruposyahoo.com
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:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
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=p53
________________________________________________________________________
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 la licencia y la ausencia de garantía
que puedes leer en la página http://www.latiumsoftware.com/es/legal.php
Allí también encontrarás una nota sobre marcas registradas. Te animamos
a que redistribuyas 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
Irongut's Delphi Pages http://www.paranoia.clara.net/
Copyright 2005 by Ernesto De Spirito + Dave Murray. All rights reserved.
________________________________________________________________________
|