Boletín Pascal #37
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
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/html/dil.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 eds2004 @ 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-7 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm ________________________________________________________________________ 2. EL FUTURO DE LA BDE Por Ernesto De Spirito <eds2004 @ 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!" http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium ________________________________________________________________________ 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: http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium ________________________________________________________________________ 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.sedlan.com/dbgrid_footer.php * 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/Jedi:TEAM_DARTH_HOME:40040 * 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://builder.com.com/article.jhtml?id=u00220020603dol01.htm * 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://builder.com.com/article.jhtml?id=u00320020628dol01.htm 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.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium http://news.optimax.com/topdelphi/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://www.top219.org/cgi-bin/vote.cgi?delphi&83 http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80 http://www.programacion.net/votar-enlace.php?id=474 http://www.lawebdelprogramador.com/buscar/enlace.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/descarga/p0037.zip ________________________________________________________________________ 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: eds2004 @ 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 ________________________________________________________________________ |
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
¿Errores? ¿Omisiones? ¿Comentarios? Por favor contáctanos!






