Boletín Pascal #37 - 15-JUL-2002
INDICE
1. UNAS PALABRAS DEL EDITOR
2. EL FUTURO DE LA BDE
3. NO DOCUMENTADO: DETECTAR SI UNA APLICACIÓN SE HA DETENIDO
4. MENSAJES DE WINDOWS EN DELPHI
5. INLINE ASSEMBLER EN DELPHI (II) - ANSI STRINGS
6. DIÁLOGO DE BÚSQUEDA EN BASES DE DATOS
7. FOROS
8. DELPHI EN LA RED
- Componentes, librerías y aplicaciones
. Shareware/Comercial
. Freeware
- Artículos, trucos y consejos
- Tutoriales
- Otros enlaces
________________________________________________________________________
1. UNAS PALABRAS DEL EDITOR
Antes que nada, me gustaría agradecer a Thomas Stutz por contribuir un
muy interesante artículo para el boletín, y me complace hacerle entrega
de una licencia de SMImport, un juego de componentes para convertir
desde los formatos de datos populares, provisto por Scalabium:
http://www.scalabium.com/smi/index.htm
Tenemos dos premios para la próxima edición:
* AnyShape Transpack v2.0 - por MindBlast Software (DELPHI + KYLIX)
¿Cansado de las aburridas ventanas rectangulares? Bienvenido al
excitante mundo de las ventanas transparentes y de formas extrañas.
Un cambio de rostro instantáneo para su interfaz gráfica. Lo que toma
horas ahora puede hacerse en segundos sin escribir ni una sola línea
de código. Características: edición WYSIWYG, vista previa en tiempo de
diseño, arrastre automático, verdaderos formularios en primer plano,
combinación de regiones, y cargado/guardado de regiones en un
archivo. Multiplataforma. Shareware, $30.00.
http://www.mindblastsoftware.com/?page=transpack&ref=PascalNL
* Developer Information Library (DIL) CD - por UK Borland User Group
Más de 17,000 trucos, consejos, FAQs y artículos técnicos · Parches y
actualizaciones de herramientas Borland · Más de 4000 componentes y
herramientas · Más de 4000 bitmaps listos para usar con otros 20000
comprimidos · Más de 350 JavaScripts listos para usar · Conjunto
completo de HOWTOs de Linux · y mucho mucho más...
http://www.richplum.co.uk/dil/index.asp
En esta edición tengo el placer también de presentar el artículo
"Mensajes de Windows en Delphi" de Oscar Adrián Esqueda Cortés.
Como sé por las direcciones de email que varios suscriptores de esta
edición son de Brasil y algunos de Portugal, me gustaría recordarles que
tenemos una edición del boletín en su idioma:
* Boletim Pascal - Português
http://br.groups.yahoo.com/group/boletim-pascal/
Assinar:
http://groups.yahoo.com/group/boletim-pascal/join
boletim-pascal-subscribe@yahoogrupos.com.br
Muy bien, ahora continuemos con el boletín.
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. EL FUTURO DE LA BDE
Por Ernesto De Spirito <eds2008 @ latiumsoftware.com>
Después del anuncio oficial de Borland respecto del futuro de la BDE,
del que informáramos en la edición pasada, he contactado (y he sido
contactado por) muchos desarrolladores Delphi que actualmente están
usando la BDE, para conocer acerca de sus planes futuros en lo que
respecta al acceso a datos.
Para bases de datos locales, la BDE seguirá siendo usada, aunque una
discreta minoría está considerando seriamente pasarse a una alternativa
a la BDE en el corto plazo (principalmente componentes de acceso a datos
de terceros, y también Interbase accedida a través de IBX o dbExpress).
Para servidores de bases de datos, el escenario cambia radicalmente.
Entre aquellos que todavía están usando versiones anteriores de Delphi,
muchos no planean actualizarse, así que seguirán usando la BDE con los
SQL Links todo lo que puedan, mientras que casi todos los demás están
considerando principalmente dbExpress, y también ADO y ADO.Net, pero
los desarrolladores mostraron su preocupación acerca de estas alterna-
tivas:
- dbExpress no es tan "universal" como SQL Links, significando que no
hay controladores (drivers) para algunos servidores importantes de
bases de datos (como Microsoft SQL Server).
Acerca de que dbExpress es más rápido que la BDE, no resulta cierto
para pequeñas consultas porque no hay mecanismo de cacheo (ya que no
hay una capa de acceso como la BDE), así que los metadatos son bajados
en cada consulta. Me gustaría dar crédito a Vasilis Devletoglou por
compartir sus hallazgos sobre el funcionamiento interno de dbExpress
con nosotros.
Finalmente, cuando uno está habituado a una tecnología por muchos
años, a veces es un poco difícil no ser algo conservador y considerar
las nuevas tecnologías como "beta". Todos sabemos que dbExpress llegó
aquí para quedarse, pero muchos programadores perciben que todavía
está "verde" y que requiere más desarrollo.
- ADO y ADO.Net no cubren las expectativas de los programadores Delphi
en cuanto a rendimiento y/o características, y no puede ignorarse el
hecho que la mayoría de los programadores preferirían usar una
solución Borland.
En conclusión, los únicos contentos parecen ser los que se mudaron a una
alternativa a la BDE hace tiempo... :-)
Me gustaría recibir su feedback acerca de este artículo, porque mientras
más opiniones reciba, más claro tendré el panorama.
________________________________________________________________________
¿Cuándo fue la última vez que votaste por el Boletín Pascal? Por favor
apoya esta iniciativa votándonos en "The Programming Top 100!"
________________________________________________________________________
3. NO DOCUMENTADO: DETECTAR SI UNA APLICACIÓN SE HA DETENIDO
Copyright (c) 2002 por Thomas Stutz
Email: tom@swissdelphicenter.ch
URL: http://www.swissdelphicenter.com/en/showcode.php?id=910
En muchas situaciones puede que desees detectar si una aplicación se ha
bloqueado. Por ejemplo, al automatizar Word, puede que desees saber si
Word ha dejado de responder. Este artículo describes como detectar si
una aplicación ya no responde usando algunas funciones no documentadas.
{
// Traducido de C a Delphi por Thomas Stutz
// Primero publicado en www.SwissDelphiCenter.com
// Código original:
// (c)1999 Ashot Oganesyan K, SmartLine, Inc
// mailto:ashot@aha.ru, http://www.protect-me.com
// http://www.codepile.com
El código usa la función SendMessageTimout de la API Win32 para
determinar si la aplicación objetivo está respondiendo, pero usa
llamadas a funciones no documentadas de la biblioteca User32.dll.
--> Para Windows 95/98/ME llamamos la APLI IsHungThread()
La función IsHungThread obtiene el estado (corriendo o no respondiendo)
del hilo (thread) especificado:
IsHungThread(DWORD dwThreadId): // El identificador del hilo de la
BOOL; // ventana principal de la aplicación
--> Para NT/2000/XP, la API IsHungAppWindow():
La función IsHungAppWindow obtiene el estado (recorriendo o no respon-
diendo) de la aplicación especificada
IsHungAppWindow(Wnd: HWND): // Handle de la ventana principal de la
BOOL; // aplicación
Desafortunadamente, Microsoft no nos provee con símbolos de exporta-
ción en la User32.lib para esas funciones, así que debemos cargarlos
dinámicamente usando las funciones GetModuleHandle y GetProcAddress:
}
// Para Win9x/ME
function IsAppResponding9x(dwThreadId: DWORD): Boolean;
type
TIsHungThread = function(dwThreadId: DWORD): BOOL; stdcall;
var
hUser32: THandle;
IsHungThread: TIsHungThread;
begin
Result := True;
hUser32 := GetModuleHandle('user32.dll');
if (hUser32 > 0) then
begin
@IsHungThread := GetProcAddress(hUser32, 'IsHungThread');
if Assigned(IsHungThread) then
begin
Result := not IsHungThread(dwThreadId);
end;
end;
end;
// Para Win NT/2000/XP
function IsAppRespondingNT(wnd: HWND): Boolean;
type
TIsHungAppWindow = function(wnd:hWnd): BOOL; stdcall;
var
hUser32: THandle;
IsHungAppWindow: TIsHungAppWindow;
begin
Result := True;
hUser32 := GetModuleHandle('user32.dll');
if (hUser32 > 0) then
begin
@IsHungAppWindow := GetProcAddress(hUser32, 'IsHungAppWindow');
if Assigned(IsHungAppWindow) then
begin
Result := not IsHungAppWindow(wnd);
end;
end;
end;
function IsAppResponding(Wnd: HWND): Boolean;
begin
if not IsWindow(Wnd) then
begin
ShowMessage('Handle de ventana incorrecto');
Exit;
end;
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := IsAppRespondingNT(wnd)
else
Result := IsAppResponding9X(GetWindowThreadProcessId(wnd,nil));
end;
// Ejemplo: Comprobar si Word está colgado/respondiendo
procedure TForm1.Button3Click(Sender: TObject);
var
Res: DWORD;
h: HWND;
begin
// Buscar Word por nombre de clase
h := FindWindow(PChar('OpusApp'), nil);
if h <> 0 then
begin
if IsAppResponding(h) then
ShowMessage('Word está respondiendo')
else
ShowMessage('Word no está respondiendo');
end
else
ShowMessage('Word no está abierto');
end;
________________________________________________________________________
Tecno Soft Solutions. Reseller Autorizado de Symbol Technologies, líder
mundial en captura de códigos de barras. >>> http://www.tecno-symbol.com
________________________________________________________________________
4. MENSAJES DE WINDOWS EN DELPHI
Por Oscar Adrián Esqueda Cortés <oesqueda @ att.net.mx>
El sistema operativo Windows, es un sistema conducido por "eventos",
como las pulsaciones de tecla, movimientos y acciones con el Mouse,
arrastre y dibujado de ventanas, entre muchos otros.
Las aplicaciones Windows, pueden comunicarse entre si y pasarse
información básicamente por un sistema de mensajes, mantenido por el
mismo Sistema Operativo (referido SO en este articulo).
Windows es Multitarea
---------------------
El hecho de tener por decirlo así, Delphi, Interbase, el IBConsole (u
otro que manejen) y varias ventanas de archivos abiertos, nos da una
idea de que el sistema operativo es multitarea, es decir, podemos
tener varias aplicaciones o procesos abiertos y trabajando al "mismo
tiempo".
Windows logra esto gracias a que puede darle a cada aplicación cierto
tiempo del procesador, esto es, no todas están corriendo al mismo
tiempo, mas bien, están dormidas mientras nuestro querido SO le de un
tiempo de procesador.
Para quienes vivieron los tiempos de Windows 3.1, cuando una aplicación
tomaba el control de procesador (quizás en un calculo), todo el SO se
detenía y tenia que esperar a que este terminara para continuar con los
demás, ya no quiero decir que pasaba si este se colgaba o producía algún
error, el desastre, Windows simplemente se caía.
Windows 95 cambio ese esquema protegiendo el tiempo del procesador, es
decir, ahora si una aplicación hace un calculo complicado no toma todo
el control del procesador, ya no se cuelgan todos los programas solo el
que tiene la tarea en proceso (en teoría claro esta).
Aunque esta fue una función de permutación de tareas, el hecho de que
cambiemos la configuración de la pantalla porque no nos gustan los
colores o cambiamos el formato de la fecha, el SO debe hacerle saber a
las aplicaciones actuales que cambiaron las configuraciones del Panel de
Control, como se hace esto, por un sistema de mensajes como mencione en
el primer párrafo.
Comunicación entre aplicaciones Windows
---------------------------------------
Pero como se logra esto, en donde, los programas tienen direcciones de
memoria distintos, donde mi aplicación 1 no ve la parte de memoria de
la aplicación 2.
Podemos hacerlo, gracias al sistema de mensajes de Windows, aunque no
compartan la memoria, comparten el mismo sistema operativo, y la misma
piedra filosofal de funcionamiento (nada que ver con Harry Potter).
Para aquellos afortunados que tienen Windows NT 4, 2000 o XP, saben lo
que es un sistema operativo mas estable, donde ven cuanto tiempo de
procesador tiene cada proceso y poder detenerlo sin temor a que se
cuelgue el sistema operativo (Hablo del administrador de tareas de
Windows).
Todos los procesos mediante API's pueden ver la cola de mensajes de
Windows y así tomar los suyos y continuar con su trabajo, de esta manera
podemos comunicar dos o mas programas entre si.
¿Que es el sistema de mensajes Windows?
---------------------------------------
Entrando en materia, Windows mantiene una cola de mensajes para cada
aplicación. Cada aplicación recoge sus mensajes y los procesa (veámoslo
como repartidores que toman sus pedidos.) Esto se basa en tres
componentes principales:
* Cola de mensajes: administrada por Windows, para que cada aplicación
recoja sus mensajes en cuanto le toca su turno de procesador.
* Ciclo de mensajes: es un ciclo que tiene cada programa que se encarga
de recoger estos mensajes.
* Procedimiento de ventana: Cada ventana (Windows, recuerden que todo
control derivado de TWinControl tiene un Handle o manejador, por eso
se refiere a ellos como ventanas) tiene un procedimiento que procesa
los mensajes que son pasados por el ciclo de mensajes.
Si alguna vez han visto en la ayuda o han usado el objeto Application
(derivado de TApplication), han visto un evento llamado OnMessage, este
se dispara cada vez que llega un mensaje a la aplicación (o a la ventana
de la aplicación principal).
Anatomía de un mensaje
----------------------
Los mensajes de Windows son transportados en una estructura de datos
previamente fija, para Delphi esta es la declaración en la unidad
"Messages.pas" (aunque la unidad "Windows.pas" es 100% necesaria
también para estos trabajos):
TMsg = Packet Record
hwnd:HWND;
message:Uint;
wParam:WParam;
LParam:LParam;
time:DWord;
pt:TPoint;
end; {TMsg}
Donde:
hwnd: Handle o manejador de ventana a quien esta destinado el mensaje.
message: entero sin signo que representa el mensaje de Windows.
wParam: Puntero a algún dato pasado al mensaje.
lParam: Puntero a algún dato pasado al mensaje.
Time: hora de cuando se dejo el mensaje en la cola de mensajes.
pt: variable de tipo TPoint que indica la posición del Mouse en el
momento del mensaje.
Como dije, cada ventana o componente derivado de TWinControl tiene un
manejador o Handle, el cual sabe Windows que esta activo, entonces puede
recibir un mensaje.
Todos los mensajes de Windows, tienen un numero que los identifica,
siempre definidos en Constantes (Las unidades Messages y Windows
contienen dichas Constantes), los nombres de constantes de mensajes
Windows, comienzan con WM_ (Windows Message o Mensaje Windows).
wParam: con este parámetro recibimos algún Handle o información
relacionada con el mensaje.
lParam: por lo regular se envían punteros o algún tipo de objeto o
información para poder ser vinculada.
Los parámetros wParam y lParam son enteros que pueden ser punteros, por
lo que podemos hacer promociones de tipo (TypeCasting) Para usarlos.
El proceso que se da para manipular un mensaje es el siguiente:
a) Ocurre un evento en el sistema.
b) Windows coloca la información del evento en una estructura de mensaje
y lo coloca en la cola de mensajes.
c) El ciclo de mensajes de la aplicación recoge el mensaje.
d) La cola de mensajes manda el evento al procedimiento de ventana
adecuado.
e) Se interpreta el mensaje en su aplicación.
Básicamente en una aplicación Windows hecha en Delphi, no nos preocupamos
por el manejo de mensajes Windows, esto lo hace Delphi por nosotros. Pero
si quiere crear componentes o manipular un poco más el sistema operativo
para controlar mas su aplicación, este es uno de los métodos.
Lista de mensajes
-----------------
Poner una lista de mensajes aquí seria un poco difícil, por lo que
adjuntamos un archivo de texto con los mensajes que tiene Windows, el
nombre es "Lista de Mensajes.txt", seria buena idea el darle una pequeña
leída rápida.
Una gran ventaja que nos da el API de Windows es que podemos crear
nuestros propios mensajes para aplicaciones, estos deben de estar arriba
del número $0400, ya que los mensajes Windows, están en ese rango de
números y pueden chocar con algún mensaje ya definido.
Const
WM_Propio = $0400 + 100;
Con esto defino mi propio mensaje, que es conocido según el ámbito de
la constante, para poder definir un mensaje Windows y poder tenerlo
apartado debe hacerse mediante la API RegisterWindowMessage(),
registrando el mensaje con este método ninguna otra aplicación podrá
hacer uso del número asignado para sus propios mensajes:
function RegistrarMensaje;
Var
WM_Propio = Word;
begin
WM_Propio := RegisterWindowMessage('MiMensaje00');
end;
con esto el mensaje marcado como "MiMensaje" ya esta apartado con el
numero que devuelve la función, Windows en este caso nos asigna
automáticamente el numero de mensaje; para cada aplicación que use
este mensaje deberá usar la misma función o por lo menos con el mismo
nombre de mensaje.
Enviar Mensajes Windows
-----------------------
En nuestros programas tenemos la capacidad de poder enviar mensajes
Windows a otras ventanas que contengan un handle, esto se hace
mediante las ordenes SendMessage() y PostMessage().
SendMessage envía el mensaje directamente al procedimiento de ventana
para su procesamiento y PostMessage lo envía a la cola de mensajes
Windows, como ven SendMessage envía directamente el mensaje a la
ventana.
Estos procedimientos son parte de la API de Windows, por lo que tiene
que saber el Handle de la ventana para poder enviarlo.
La llamada a SendMessage seria de la siguiente manera:
function SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM;
lParam: LPARAM): BOOL;
donde:
HWND es el handle de ventana,
MSG el numero de mensaje (Ver listado de mensajes),
wParam es el dato wParam del mensaje y
lParam corresponde al otro parámetro del mensaje.
function PostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM;
lParam: LPARAM): BOOL;
los parámetros son los mismos que en SendMessage(), las funciones
devuelven verdadero si pudo enviar el mensaje y falso si no.
El método Perform() es parte de la clase TControl y es heredado por
todos sus descendientes, aunque su función es la misma, el mensaje es
enviado directamente al procedimiento de ventana del control.
TControl.Perform(Msg:Cardinal; WParam, LParam:Integer):Longint
Como ven tiene los mismos argumentos, a diferencia del Handle, porque
ya es conocido (siendo la misma ventana del control la que recibe el
mensaje).
El elemento practico de esto en un programa, es de la comunicación
entre varios programas (EXE o DLL) si tener que usar funciones
explícitas para eso, es decir, un cuadro de dialogo puede mandar un
mensaje a la ventana de la que fue llamada y simplemente tener una
acción, siendo que el cuadro de dialogo esta en una DLL y fue llamado
desde un ejecutable, otro caso es el uso de componentes y clases
personalizados.
Atrapar Mensajes Windows
------------------------
Ahora que ya sabemos como enviar mensajes a los controles, ventanas y
aplicaciones Windows, veamos como atraparlos, teniendo varias opciones
(unas más complicadas y poderosas que otras).
Usaremos primero el evento OnMessage del objeto Application (derivado de
TAPPlication), todo programa que contenga ventanas (es decir no de
consola, Web o Kylix) tendrá su objeto Application (viene en la unidad
Forms).
Para los que tienen Delphi 6, pueden usar el objeto ApplicationEvents de
la paleta Additional, para versiones anteriores les recomiendo el objeto
AppEvents de los RX.
La declaración del evento OnMessage es el siguiente:
procedure (var Msg: TMsg; var Handled: Boolean);
Donde:
MSG es el mensaje recibido por la aplicación, pasado por referencia y
Handled también pasado por referencia.
El siguiente paso es agregar un Case Of para capturar que tipo de
mensaje fue recibido.
El parámetro Handled se establece a verdadero si nosotros vamos a
procesar dentro del evento OnMessage el mensaje recibido. Pero esta forma
de atrapar el mensaje no la recomiendo mucho, puede hacer el programa
lento por toda la cantidad de mensajes que recibe (les digo que no solo
son un par, son varios a montones).
Otra manera es programar directamente un procedimiento para el evento en
especial, esto se consigue con la palabra reservada message en la
declaración del objeto, en este caso en particular lo veremos con el
TForm y descendientes.
Para crear un procedimiento que atrape un mensaje Windows lo haremos de
la siguiente forma:
TMiForma = Class(TFOrm)
private
protected
procedure WMMOVE(var MSG:TMsg); Message WM_MOVE;
public
end;
implementation
procedure TMiFOrma.WMMOVE(var MSG:TMsg);
begin
.
.
código
.
inherited
.
end;
el hecho de llamar a inherited significa llamar al manejador del evento
del ancestro, de lo contrario el mensaje no será apropiadamente
procesado y podríamos desde colgar nuestra aplicación hasta el S. O.
Si vemos la forma de hacerlo, es en la sección protected del objeto en
cuestión, creamos un procedimiento del nombre que sea, en mi caso, uso
el del mismo mensaje sin el guión, con el único requisito que tenga de
parámetro una variable de tipo TMsg para recibir el mensaje.
La "magia" aquí es el identificador Message <<mensaje>>, que indica a
Delphi que mensaje vamos a manipular.
Y solo quedaría escribir el código para el evento.
Realmente el uso de eventos en Delphi es manipulación de eventos, vea la
siguiente tabla:
Evento en Delphi Mensaje Windows
----------------------------------------
OnActivate WM_Activate
OnClick WM_XButtonDown
OnCreate WM_Create
OnDblClick WM_XButtonDblClick
OnKeyDown WM_KeyDOwn
y esta es una pequeña lista, realmente ahí radica la programación por
eventos, en los avisos o mensajes que el S. O. da a las aplicaciones.
__________________
NOTA: El autor es el titular de Information Technology Consulting, una
empresa de Mexico dedicada a la informática vista de manera integral,
abarcando -entre otras cosas- el desarrollo de aplicaciones y sitios
web, diseño gráfico y animaciones, venta, instalación y mantenimiento de
equipos, redes y software, consultorías y asesorías en informática, y
servicios de capacitación. >>>>> http://www14.brinkster.com/itcmx/ <<<<<
________________________________________________________________________
5. INLINE ASSEMBLER EN DELPHI (II) - ANSI STRINGS
En este capítulo aprenderemos unas pocas instrucciones en ensamblador
más, y lo básico de trabajar con cadenas ANSI, también llamadas cadenas
largas (long strings).
Opcodes nuevos
==============
Los opcodes introducidos en este artículo:
* JL (Jump if Lower = salta si es menor): La descripción correcta sería
larga de explicar, así que simplemente digamos que JL salta (va a) la
etiqueta especificada si en la previa operación CMP (o SUB), el primer
operando es menor que el segundo en una comparación entera (con
signo).
// if signed(op1) < signed(op2) then goto @@label;
cmp op1, op2
jl @@label
JG (Jump if Greater = salta si es mayor), JLE (Jump if Lower or Equal
= salta si es menor o igual), y JGE (Jump if Greater or Equal = salta
si es mayor o igual) completan la familia de saltos condicionales para
comparaciones entera (con signo).
* JA (Jump if Above = salta si superior): salta (va a) la etiqueta
especificada si en la previa operación CMP (o SUB), el primer operando
es mayor que el segundo, tomados ambos operandos como valores
naturales (sin signo):
// if unsigned(op1) > unsigned(op2) then goto @@label;
cmp op1, op2
ja @@label
JB (Jump if Below = salta si inferior), JBE (Jump if Below or Equal =
salta si inferior o igual), y JAE (Jump if Above or Equal = salta si
superior o igual) completan la familia de saltos condicionales para
comparaciones sin signo.
* LOOP: Decrementa EC y si no es cero salta a la etiqueta especificada.
LOOP @@etiqueta es un equivalente más corto y rápido que:
dec ecx // ECX := ECX - 1;
jnz @@etiqueta // if ECX <> 0 then goto @@etiqueta
Ejemplo:
xor eax, eax // EAX := EAX xor EAX; // EAX := 0;
mov ecx, 5 // ECX := 5;
@@etiqueta:
add eax, ecx // EAX := EAX + ECX; // Ejecutado 5 veces
loop @@label // Dec(ECX); if ECX <> 0 then goto @@etiqueta;
// EAX valdría 15 (5+4+3+2+1)
Trabajando con cadenas ANSI
===========================
Una variable string se representa por un puntero de 32 bits. Si la
cadena es la cadena vacía (''), entonces el puntero es Nil (cero), y
en caso contrario, apunta al primer caracter de la cadena. La longitud
de la cadena y el contador de referencias están en desplazamientos
negativos de la posición del primer byte:
+-----------+
| s: string |-------------------+
+-----------+ |
V
--+-----------+-----------+-----------+---+---+---+---+---+---+---+--
| allocSiz | refCnt | length | H | e | l | l | o | ! | #0|
--+-----------+-----------+-----------+---+---+---+---+---+---+---+--
(longint) (longint) (longint)
\-----------------v-----------------/
StrRec record
const skew = sizeof(StrRec); // 12
Cuando pasamos una cadena como parámetro a una función, lo que se pasa
es tan sólo el puntero de 32 bits. Las cadenas como valores de retorno
son más difíciles de explicar. El llamador de una función que devuelve
una cadena debe pasar ---como un invisible último parámetro de tipo
PString-- la dirección de la variable string que alojará el resultado de
la función.
d := Uppercase(s); // Internamente convertido a: Uppercase(s, @d);
Si el resultado de la función será usado en una expresión en vez de ser
asignado directamente a una variable, el llamador debe usar una variable
temporal inicializada en Nil (la cadena vacía). El compilador hace esto
por nosotros en el código Object Pascal, pero tenemos que hacerlo por
nosotros mismos si llamamos a funciones que devuelven cadenas desde
código ensamblador.
Para algunas tareas, no podemos llamar las clásicas funciones de cadenas
directamente. Por ejemplo, la función Length no es el nombre de una
función de verdad, sino algo incorporado dentro del compilador, y el
compilador genera código para llamar la función apropiada, dependiendo
de si el parámetro es una cadena o un arreglo variable. En ensamblador,
en vez de Length, tenemos que llamar la función _LStrLen (declarada en
la unidad System) para obtener la longitud de la cadena.
Hay más cosas que deberíamos saber de las cadenas, pero ya tenemos
suficiente para un primer ejemplo.
Versión ensamblador de Uppercase
================================
Esta es la declaración de la función:
function AsmUpperCase(const s: string): string;
El parámetro "s" será pasado en EAX, y la dirección de "Result" será
pasada como un segundo parámetro, es decir, en EDX.
Básicamente, esta función debería:
1) Obtener la longitud de la cadena a convertir
2) Asignar memoria para la cadena resultado
3) Copiar los caracteres, convirtiéndolos a mayúsculas
1) Obtener la longitud de la cadena a convertir
-----------------------------------------------
Haremos esto llamando a System.@LStrLen. La función espera la cadena en
EAX (ya la tenemos allí), y el resultado será colocado en EAX, así que
tenemos que guardar el valor de EAX (el parámetro "s") en algún lugar
antes de llamar la función para evitar perderlo. Podemos guardarlo en
una variable local "src". Puesto que las funciones son libres de usar
los registros EAX, ECX y EDX, deberías asumir que el valor de EDX
("@Result") podría también ser destruido después de llamar a
System.@LStrLen, así que primero deberíamos guardarlo, por ejemplo en
una variable local "psrc". El resultado de System.@LStrLen, dejado en
EAX, será usado como parámetro de System.@LStrSetLength (para asignar
memoria para el contenido de la cadena resultado), y luego lo nece-
sitamos para contar la cantidad de bytes a ser copiados, así que
debemos guardarlo, por ejemplo en una variable "n":
var
pdst: Pointer; // Dirección de la cadena resultado
src: PChar; // Cadena origen
n: Integer; // Longitud de la cadena
asm
// La dirección de la cadena resultado se pasa en EDX.
// La guardamos en una variable local (pdst):
mov pdst, edx // pdst := EDX;
// Guardamos EAX (s) en una variable local (src)
mov src, eax // src := EAX;
// n := Length(s);
call System.@LStrLen // EAX := _LStrLen(EAX);
mov n, eax // n := EAX;
2) Asignar memoria para la cadena resultado
-------------------------------------------
Esto se logra llamando a System.@LStrSetLength. El procedimiento espera
dos parámetros: la dirección de la cadena (la guardamos en "pdst"), y
la longitud de la cadena (la tenemos en EAX).
// SetLength(pdst^, n); // Asignamos la cadena resultado
mov edx, eax // EDX := n; // Segundo parámetro p/ LStrSetLength
mov eax, pdst // EAX := pdst; // Primer parámetro para LStrSetLength
call System.@LStrSetLength // _LStrSetLength(EAX, EDX);
3) Copiar los caracteres, convirtiéndolos a mayúsculas
------------------------------------------------------
Si la longitud de la cadena era cero, no hay más que hacer:
// if n = 0 then exit;
mov ecx, n // ECX := n;
test ecx, ecx // ECX And ECX para establecer las banderas
jz @@end // Ir a @@end si la bandera Cero está ON (ECX=0)
Caso contrario, debemos copiar los caracteres de una cadena a la otra,
convirtiéndolos a mayúsculas si es necesario. Vamos a usar ESI y EDX
para apuntar a los caracteres de las cadenas origen y resultado
respectivamente, AL para para cargar el caracter de la cadena origen y
realizar el cambio antes de guardarlo en la cadena destino, y ECX con
la instrucción LOOP para contar los caracteres. Como ESI es un registro
que debemos preservar, tenemos que salvar su valor para restaurarlos
después. Decidí salvar ESI "empujándolo" en la pila.
push esi // Salvamos ESI en la pila
// Inicializamos ESI y EDX
mov eax, pdst // EAX := pdst; // @cadena resultado
mov esi, src // ESI := src; // cadena origen
mov edx, [eax] // EDX := pdst^; // cadena resultado
@@cycle:
mov al, [esi] // AL := ESI^;
// if Shortint(AL) < Shortint(Ord('a')) then goto @@nochange
cmp al, 'a'
jl @@nochange
// AL in ['a'..#127]
// if Byte(AL) > Byte(Ord('a')) then goto @@nochange
cmp al, 'z'
ja @@nochange
// AL in ['a'..'z']
sub al, 'a'-'A' // Dec(AL, Ord('a')-Ord('A'));
@@nochange:
mov [edx], al // EDX^ := AL;
inc esi // Inc(ESI);
inc edx // Inc(EDX);
loop @@cycle // Dec(ECX); if ECX <> 0 then goto cycle
pop esi // Restauramos ESI de la pila
@@end:
end;
________________________________________________________________________
6. DIÁLOGO DE BÚSQUEDA EN BASES DE DATOS
Recientemente se me solicitó añadir un cuadro de diálogo de búsqueda en
todos los formularios tipo browse de un proyecto, así que desarrollé
esta simple unidad en Delphi 5, que muestra un diálogo no modal por
encima de otros formularios, permitiendo a los usuario especificar el
texto de búsqueda, el campo que será revisado, y si el texto puede
estar en cualquier parte del campo, al principio, o al final, o si el
valor del campo debe coincidir el valor buscado. El diálogo tiene
botones para buscar la primera, anterior, siguiente y última ocurrencia.
Para usarlo, simplemente agrega un botón de búsqueda a tu formulario,
incluye DbFindDlg en la cláusula Uses, y escribe un código como el
siguiente en el manejador del evento Click del botón:
procedure TMain.btnSearchClick(Sender: TObject);
begin
ShowFindDialog(Self, Table1); // Cualquier descendiente de TDataset
end;
Si tienes una DbGrid, puedes llamar una versión sobrecargada que en el
combo de campos muestra sólo aquellos que se muestran en el DbGrid:
procedure TMain.btnSearchClick(Sender: TObject);
begin
ShowFindDialog(Self, DbGrid1); // Cualquier descendiente de TDbGrid
end;
El diálogo de búsqueda se libera a sí mismo al cerrarse o cuando se
destruye su dueño (pasado como primer parámetro).
El proyecto no está completo, y todavía necesita algunas mejoras (por
ejemplo, en el caso de la versión DbGrid, se asume que todas las
columnas del DbGrid están vinculadas a campos), pero es bastante
"usable" en muchas circunstancias tal como está, así que quería
compartirlo con ustedes. Se adjunta el código fuente completo y un
programa de demostración simple.
_______________________________________________________________________
Colabora votándonos en este ranking para que esta publicación continúe:
________________________________________________________________________
7. FOROS
Supongo que al igual que muchos de ustedes, cada tanto recibo mensajes
de Yahoo! Grupos solicitándome confirmación para darme de baja de algún
foro (grupo), o para suscribirme a otro grupo, o para indicarme que mi
solicitud de suscripción/cancelación no se procesará porque ya soy o
porque no soy miembro de un grupo.
Generalmente es un efecto de virus como el Klez.H, que se propagan
enviando mensajes a granel a distintas direcciones de email que toman
de la máquina infectada, y que como remitente colocan una dirección de
email al azar tomada de la misma fuente, es decir, que si la PC de algún
forista se infecta, puede enviar correos a las direcciones adminis-
trativas del foro a nombre de alguno de los miembros que publicamos
mensajes en el foro (nuestra dirección será visible para el virus en la
PC de la víctima).
Hace tiempo notifiqué a Yahoo! Grupos del problema, sugiriéndoles una
simple comprobación heurística en los mensajes que se reciben en las
cuentas administrativas, para no procesar como solicitudes válidas los
mensajes de virus, pero hasta el momento no he recibido respuesta.
Por favor les ruego que usen un antivirus actualizado, y aquellos que
tengan problemas para acceder a la web para obtener ese software, pueden
saber si tienen el Klez o el Yaha ejecutando el programa REGEDIT.EXE
para ver el Registro de Windows:
* Klez: Bajo la siguiente clave referencia al archivo WINK???.EXE:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
* Yaha: Modifica el valor "(Predeterminado)" de la siguiente clave
(que ese ""%1" %*") y coloca ""C:\Recycled\????" %1 %*" en su lugar:
HKEY_CLASSES_ROOT\exefile\shell\open\command
Ahora sí, les recuerdo las direcciones de los foros y los invito a
participar:
* 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
________________________________________________________________________
8. DELPHI EN LA RED
Por Dave Murray <irongut @ vizzavi.net>
La entrada en la edición pasada para el "DARTH C-to-Pascal header
converter" no tenía dirección. Ha sido corregido abajo. ¡Perdón! - DM
Componentes, librerías y aplicaciones
=====================================
Shareware/Comercial
-------------------
* TSDBGridFooter v2.0 por Jovan Sedlan, Shareware ($74.50)
Este componente es una poderosa herramienta que provee cálculos auto-
máticos para su DBGrid y muestra información en un pie configurable
debajo de la grilla. Ha sido dieñado para trabajar con TSDBGrid
(también incluido), aunque puede usarse con cualquier descendiente de
TCustomDBGrid.
http://www.softpile.com/Development/Libraries/Review_24756_index.html
* The Logo Creator v2.5 - By Laughingbird Software
Do-it-yourself logo creation software. The Logo Creator is a fun and
easy to use software program made up of logo templates that you can
modify and customize. For Macintosh and Windows.
http://www.thelogocreator.com/
Freeware
--------
* Trivial v6.10 BETA - de JMR - 707 Kb
Librería freeware de componentes de uso común para Delphi 3-6.
http://www.latiumsoftware.com/descarga/trivial610beta.zip
* NKLib - de JMR - 55 Kb
Librería freeware de funciones de uso común para Delphi 3-6.
http://www.latiumsoftware.com/descarga/nklib.zip
* DARTH: C-to-Pascal header converter - by JEDI, FREEWARE with source
Source compiles into a tool that parses C headers and generates Delphi
source for Windows API calls.
http://www.delphi-jedi.org/toolslibrary.html
* TColorButton v1.0 - by 940801, FREEWARE with source
This button drops down a colour select window, can be like Word 2000.
http://940801.cndev.net/
* TGHIPEdit - by gh boy, FREEWARE with source
An IP Address Editor Component.
http://www.delphipages.com/uploads/Edits_Combos/IPEdit.zip
* THTMLLiteCLX - By Dave Baldwin, FREEWARE (DELPHI/KYLIX)
An HTML viewer component designed for hobbyists, students, or casual
users. Does not support Frames or the printing HTML documents. Image
capabilities include GIF, animated GIF, JPEG and bitmap.
http://www.pbear.com
* CPU package - release 2 revision 22 - By Thomas Schatzl
It is a small x86 CPU detection library. It should compile on Delphi
2-6 (tested 5 / 6 Personal) Win32 target, Freepascal 0.99.15+ (tested
1.0.6 / 1.1 Win32) for Win32 / OS/2 / GO32V2 / Linux targets (possibly
others) and VP 2.1b (Win32 target, possibly DOS/Linux). Possibly will
work with Kylix.
http://members.yline.com/~tom_at_work/index.html
Artículos, trucos y consejos
============================
* Optimize DBImage fields and free disk space - by Zeriouh Abdelhafid
How to reduce the size of and optimize dbimage or graphic fields.
http://www.delphi3000.com/articles/article_3312.asp
* BorCon 2002 Nugget: Jake's Tuesday report - by John Jacobson
As posted on delphi.non-technical.
http://community.borland.com/article/0,1410,28837,00.html
* BorCon 2002 Nugget: Jake's Wednesday report - by John Jacobson
As posted on delphi.non-technical.
http://community.borland.com/article/0,1410,28839,00.html
* How to use TWebBrowser printing functions - by Merlin
http://www.delphifaq.net/modules.php?op=modload&name=FAQ&file=index
&myfaq=yes&id_cat=12&categories=Internet/LAN
* How to get a list of network drives - by Merlin
http://www.delphifaq.net/modules.php?op=modload&name=FAQ&file=index
&myfaq=yes&id_cat=12&categories=Internet/LAN
* How to duplicate a TTable? - by Merlin
http://www.delphifaq.net/modules.php?op=modload&name=FAQ&file=index
&myfaq=yes&id_cat=13&categories=Databases
* How to convert TDateTime to a UNIX timestamp and vice versa - Merlin
http://www.delphifaq.net/modules.php?op=modload&name=FAQ&file=index
&myfaq=yes&id_cat=13&categories=Databases
* How to access password protected Paradox databases without a password
http://www.delphifaq.net/modules.php?op=modload&name=FAQ&file=index
&myfaq=yes&id_cat=13&categories=Databases
* How to get the empty memory? - by sümer cip
http://www.delphi3000.com/articles/article_3298.asp
* TCollection Performance Issues and Solutions - by Clever Components
http://www.delphi3000.com/articles/article_3301.asp
* Make TextOut with 3d-Effect or hollow Text - by Holger Voigt
http://www.delphi3000.com/articles/article_3303.asp
* How to save file in BLOB and read from BLOB - by Mike Shkolnik
http://www.delphi3000.com/articles/article_3304.asp
* Loading an exe in a memo field - by Teun Spaans
http://www.delphi3000.com/articles/article_3305.asp
* Simple 3D Labels (Lowered and Raised) - by Abdulaziz Jasser
http://www.delphi3000.com/articles/article_3307.asp
* Custom Exception Dialogs + writing to the NT Event Log - D Wischnewski
Knowing what goes wrong; when, where and why?.
http://www.delphi3000.com/articles/article_3308.asp
* SOAP raises the bar for CORBA
The dawn of the Web Services era promises to link disparate businesses
in a manner and on a scale reminiscent of Internet linked machines.
http://community.borland.com/article/0,1410,28737,00.html
* How to view a TDataSet in MS Excel?
http://www.swissdelphicenter.ch/en/showcode.php?id=998
* How to change the default project directory in Delphi?
http://www.swissdelphicenter.ch/en/showcode.php?id=1130
* How to use the AdjustTokenPrivileges function to enable a privilege?
http://www.swissdelphicenter.ch/en/showcode.php?id=1177
* How to insert a Smiley image into a TRxRichEdit?
http://www.swissdelphicenter.ch/en/showcode.php?id=1147
* How to to fade in/out a TImage?
http://www.swissdelphicenter.ch/en/showcode.php?id=1165
* How to format a MessageDlg?
http://www.swissdelphicenter.ch/en/showcode.php?id=1168
* How to create a registry entry in the autorun key?
http://www.swissdelphicenter.ch/en/showcode.php?id=1157
* How to start a program and wait for its termination?
http://www.swissdelphicenter.ch/en/showcode.php?id=93
* How to print a page in a TWebbrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=478
* How to create a GUID at runtime?
http://www.swissdelphicenter.ch/en/showcode.php?id=1172
* How to Copy, Delete, Cut in the TWebbrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1174
* How to Show the Properties Dialog in the TWebbrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1175
* How to Show Balloon Tips for the Tray Icon?
http://www.swissdelphicenter.ch/en/showcode.php?id=1164
* How to change the Borderstyle/ BorderColor of a TWebbrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1171
* How to extract a frame from a AVI file?
http://www.swissdelphicenter.ch/en/showcode.php?id=1180
* How to show the 'run' Dialog?
http://www.swissdelphicenter.ch/en/showcode.php?id=1181
* How to show shaded hints (XP)?
http://www.swissdelphicenter.ch/en/showcode.php?id=1182
* How to check, if a file is on a local drive?
http://www.swissdelphicenter.ch/en/showcode.php?id=1183
* How to regenerate all out-of-date indexes on a given table?
http://www.swissdelphicenter.ch/en/showcode.php?id=1184
* How to hide the scrollbars of TWebBrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1185
* How to scroll TWebBrowser with own buttons?
http://www.swissdelphicenter.ch/en/showcode.php?id=1186
* How to check if the copy command is active in a TWebBrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1187
* How to Replace images in a TWebBrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1188
* How to find and highlight text in TWebBrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1189
* How to get the lighter or darker color of a TColor variable?
http://www.swissdelphicenter.ch/en/showcode.php?id=1194
* How to automatically dial/hangup the default Internet connection?
http://www.swissdelphicenter.ch/en/showcode.php?id=1198
* How to rotate a DIB image?
http://www.swissdelphicenter.ch/en/showcode.php?id=1199
* How to show the 'Choose Domain' dialog?
http://www.swissdelphicenter.ch/en/showcode.php?id=1200
* How to list the user privileges (NT)?
http://www.swissdelphicenter.ch/en/showcode.php?id=1201
* How to remove a Dll from memory?
http://www.swissdelphicenter.ch/en/showcode.php?id=1202
* How to detect whether the CPU supports MMX?
http://www.swissdelphicenter.ch/en/showcode.php?id=1203
* How to set the volume for the microphone/ mute it?
http://www.swissdelphicenter.ch/en/showcode.php?id=1204
* How to switch a console application to full screen?
http://www.swissdelphicenter.ch/en/showcode.php?id=1205
* How to hide the Minimize/Maximize buttons of a form?
http://www.swissdelphicenter.ch/en/showcode.php?id=1207
* How to show password characters in a InputBox?
http://www.swissdelphicenter.ch/en/showcode.php?id=1208
* How to save a Excel file as Text file?
http://www.swissdelphicenter.ch/en/showcode.php?id=1209
* How to determine if a number is prime, quickly (2)?
http://www.swissdelphicenter.ch/en/showcode.php?id=1210
* How to deactivate the (Windows) keys with a systemwide Hook?
http://www.swissdelphicenter.ch/en/showcode.php?id=1212
* How to get the first/last visible line of a TRichEdit?
http://www.swissdelphicenter.ch/en/showcode.php?id=1213
* How to return information about the current system?
http://www.swissdelphicenter.ch/en/showcode.php?id=1215
* How to determine if the window is a Unicode window?
http://www.swissdelphicenter.ch/en/showcode.php?id=1216
* Rotate an ellipse - by Holger Voigt
Ellipse with Beziercurves.
http://www.delphi3000.com/articles/article_3257.asp
* Auto Hide for Form - by Zswang Wangjihu
http://www.delphi3000.com/articles/article_3258.asp
* Retrieving folder size - by Christian Cristofori
This function tells you how many bytes a folder, with all subfolders
and files occupies on a HD, CD, floppy or whatever.
http://www.delphi3000.com/articles/article_3259.asp
* Use own buttons to scroll TWebBrowser - by Smokey Mc. Pot
http://www.delphi3000.com/articles/article_3262.asp
* Change the looks of a MessageDlg... - by Smokey Mc. Pot
http://www.delphi3000.com/articles/article_3263.asp
* WebBrowser load from stream - by Zswang Wangjihu
function ShowHtml(mWebBrowser:TWebBrowser;mStrings:TStrings):Boolean;
http://www.delphi3000.com/articles/article_3267.asp
* DataSet -> Strings -> DataSet - by Zswang Wangjihu
Functions: TexttToDataSet, DataSetToText.
http://www.delphi3000.com/articles/article_3269.asp
* Creating Matlab files - by Flurin Honegger
A library unit with basic building procedures.
http://www.delphi3000.com/articles/article_3271.asp
* An Iterative ASCII-Export - by Max Kleiner
Exports records to a delimited file.
http://www.delphi3000.com/articles/article_3272.asp
* The Fast and Best way to get a local IP Address - by Gerson Tomas
http://www.delphi3000.com/articles/article_3273.asp
* Print data from table in QReport - by Alper Sirvan
http://www.delphi3000.com/articles/article_3275.asp
* Design-Time Component About Box Dialog (Delpih 6) - by Mike Heydon
http://www.delphi3000.com/articles/article_3277.asp
* Pump data from any dB into Interbase/Firebird - by Clever Components
How to pump data from any ADO/BDE/ODBC and native Interbase/Firebird
databases into Interbase/Firebird databases.
http://www.delphi3000.com/articles/article_3278.asp
* When do we use Application (Owner), Self or NIL? - by Max Kleiner
Passing the right Owner to a component-constructor.
http://www.delphi3000.com/articles/article_3281.asp
* Make Application.ExeName work in DLLs - by Christian Cristofori
http://www.delphi3000.com/articles/article_3283.asp
* Create a DBExpress-Connection at Runtime - by Max Kleiner
http://www.delphi3000.com/articles/article_3286.asp
* High speed parser - by Yuriy Pisarev
This component is intended for mathematics and logical calculations.
http://www.delphi3000.com/articles/article_3287.asp
* How to find the senders email address (MS Outlook) - by Marc Georges
http://www.delphi3000.com/articles/article_3288.asp
* Determine the date of Easter for a given year - by Oliver Moenche
http://www.delphi3000.com/articles/article_3289.asp
* Using AdjustTokenPrivileges to enable a privilege (NT) - Thomas Stutz
http://www.delphi3000.com/articles/article_3291.asp
* Getting the associated Icon of any file - by Daniel Wischnewski
This article shows you how to extract the associated icon of any file.
Including files that use shell icon handlers such as Corel Draw files.
http://www.delphi3000.com/articles/article_3293.asp
* Child windows of a window (forms within a form) - by Tommy Andersen
http://www.delphi3000.com/articles/article_3294.asp
* First/Last changed File in Folder - by Holger Voigt
http://www.delphi3000.com/articles/article_3296.asp
Tutoriales
==========
* A Beginner's Guide to Delphi Programming - by Zarko Gajic
FREE online Delphi programing course for beginners, now up to Part 5:
Understanding the Delphi unit source.
http://delphi.about.com/library/weekly/aa061802a.htm
* Demystifying the syntax of regular expressions - by Shelley Doll
Regular expressions are often wrongly perceived as mystical unknowns
that only a true guru can understand. They're ugly to look at and if
you don't know the syntax they can seem like cryptic strings of
garbage you might get from a core dump. This article will help by
walking you though the most commonly used regular expressions.
http://articles.techrepublic.com.com/5100-10878_11-1050915.html
* SQL Basics I: Data Queries - by Shelley Doll
Need a quick overview of SQL? This article will get you started from
creating basic manipulation queries to altering the database to more
advanced query concepts.
http://builder.com.com/article.jhtml?id=u00320020531dol01.htm
* SQL Basics II: SELECT statement options - by Shelley Doll
Need a quick overview of SQL? This article picks up where the previous
one left off with some additional functions and clauses for use with
the basic SELECT data query.
http://articles.techrepublic.com.com/5100-10878_11-1044962.html
Otros enlaces
=============
* C++Builder Developer Survey 2002 - by C++Builder Product Team
Survey to get feedback on current and desired features for future
releases of C++ products from Borland. Your answers will have a direct
impact on future product releases. Five prize winners will receive a
free Borland Professional software product of their choice.
http://infopoll.net/Live/surveys/s17964.htm
* Builder 7 Personal Download Now Available - by Tim Del Chiaro
Now you can download a free copy of new JBuilder 7 Personal including
a free development license for non-commercial use. JBuilder 7 Personal
is currently available in English for the Windows, Linux, Solaris and
Mac OSX platforms. Other language editions are coming soon.
http://community.borland.com/article/0,1410,28844,00.html
* Delphi 6 Updates for the RTL and Informix 9.2.1 - by John Kaster
Registered users can download two new updates for Delphi 6. Included
in the RTL pack is a SysUtils update that remedies a deadlock issue
that could appear when many Web modules were being used under heavy
load causing the Web application to stop responding.
http://community.borland.com/article/0,1410,28783,00.html
* Borland demonstrates .NET technology - by Anders Ohlsson
DevRel shows Delphi for .NET preview at VS Live in New York.
http://community.borland.com/article/0,1410,28788,00.html
* Merlin's Delphi Forge
Delphi news, faq, tips, downloads, classifieds and more.
http://www.delphifaq.net/
* Builder.com Readers' Choice Awards
The time has come! Make your voice heard, and vote for your favorite
development tool in the 2002 Builder.com Readers' Choice Awards. You
can vote for Borland in these categories: Best Java IDE, Best Java
Application Server, Best Windows Development Tool and Best Linux IDE.
http://clickthru.online.com/Click?q=06-fP6uI482uKMaF6Gma-TvR7xyY8ZR
________________________________________________________________________
¡TÚ PUEDES AYUDARNOS!
Por favor danos una mano y ayúdanos a llegar a los 10.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
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=p37
________________________________________________________________________
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) 2002 por Ernesto De Spirito. Todos los derechos reservados
________________________________________________________________________
|