Boletín Pascal #34
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #34 - 04-ABR-2002 INDICE 1. UNAS PALABRAS DEL EDITOR 2. EN LAS NOTICIAS - Borland TeamSource DSP ahora disponible - La Cara Oculta de Delphi 4 disponible para descarga gratuita 3. APLICACIONES SIN VCL (I) 4. ENSAMBLADOR EN DELPHI 5. TTRAYCOMPONENT 6. IMPEDIR QUE WINDOWS MUESTRE MENSAJES DE ERRORES CRÍTICOS 7. MOSTRANDO EL DIÁLOGO "BUSCAR CARPETA" DE WINDOWS (II) 8. FOROS 9. DELPHI EN LA RED - Componentes, librerías y aplicaciones . Shareware/Comercial . Freeware - Artículos, trucos y consejos . Kylix - Tutoriales ________________________________________________________________________ 1. UNAS PALABRAS DEL EDITOR He recibido las opiniones de los suscriptores respecto de la cuestión planteada en el último número y -siguiendo la opinión de la inmensa mayoría- a partir de ahora la edición en español será más autónoma, lo que significa que se perderá la sincronía de tiempos y contenido con la versión en inglés, a favor del contenido mayoritariamente en español. Aprovecho para agradecer la valiosa colaboración de Ernesto Cullen en la traducción de los artículos en inglés para hacer esta edición posible, y aprovecho también para hacer un nuevo llamado por interesados en colaborar en esta tarea. Quisiera agradecer a los autores de los artículos colaborados para esta edición, y me complace entregarle a José Manuel Rodríguez (JMR) la licencia de Greatis Print Suite, un juego de componentes de vista previa e impresión, provisto por Greatis Software: http://www.greatis.com/printsuite.htm En la próxima edición, uno de nuestros colaboradores recibirá 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 Para los muchos suscriptores de Brazil y Portugal que sé que tiene este boletín, les tengo la grata noticia que de la mano de Demian Lessa la edición en portugués de este boletín es ahora una realidad: * Boletim Pascal http://www.latiumsoftware.com/br/pascal/index.php Si deseas recibir el Boletim Pascal, puedes suscribirte desde la web (se requiere un ID de Usuario de Yahoo! - puedes obtener el tuyo gratis registrándote como usuario si no tienes uno), o -más fácilmente- por email: http://br.groups.yahoo.com/group/boletim-pascal/join boletim-pascal-subscribe@yahoogrupos.com.br Ah, para quienes se están adentrando en el mundo de la programación en Delphi, en la sección Delphi en la Red encontrarán dos buenos tutoriales de Pablo Castagnino ("Introducción a las excepciones" e "Introducción al Registro y los archivos INI"). 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. EN LAS NOTICIAS Borland TeamSource DSP ahora disponible ======================================= Borland TeamSource DSP es una plataforma de desarrollo colaborativo para equipos distribuidos. En español, si necesitas coordinar el trabajo de tu staff de desarrollo de software a través de la Internet, entonces TeamSource DSP puede ser la solución que estás buscando. TeamSource DSP no es un software... bueno, involucra un software, pero básicamente es un servicio (una solución de servicios web hospedada en un servidor de Borland, para ser preciso), y se cobra como una suscripción por usuario y por mes. Para conocer más acerca de Borland TeamSource DSP y tomar el tour, visita http://www.borland.com/teamsource/ La Cara Oculta de Delphi 4 disponible para descarga gratuita ============================================================ A mediados de Marzo comenzó a circular por Internet la versión digital (en formato PDF) del conocidísimo libro "La Cara Oculta de Delphi 4" de Ian Marteens, con el rumor de que había sido liberado por su autor para libre distribución. De inmediato me puse en contacto con el mismo para corroborar la noticia y preguntarle sobre las posibilidades de disponer de dicho material y ponerlo para descarga en nuestro sitio web. Resultó que esa distribución era ilegal (el archivo fue tomado del CD-ROM que acompaña su último libro, de reciente aparición, y que era exclusivo para quienes hayan adquirido dicho libro), pero sorprendido por el gran interés que despertó el material en la comunidad, el autor, en un gesto desprendido, decidió autorizar la descarga de dicho material de la siguiente dirección: http://www.latiumsoftware.com/descarga/lcod4.php El archivo (de 3,7MB) no es de distribución libre, pero sí puede bajarse de la dirección de arriba. Debemos hacer la aclaración que si bien el libro es muy bueno y seguramente le será útil a un estudiante, es para Delphi 4, y -como todos sabemos- de Delphi 4 a Delphi 6 se han producido muchas y grandes novedades, por lo que el material resultará obsoleto para un profesional, a quien mejor le recomendamos el libro "La Cara Oculta de Delphi 6": http://www.marteens.com/#CaraOculta ________________________________________________________________________ Greatis Print Suite Pro v1.7 - Un conjunto de componentes VCL que ofrece características avanzadas de vista previa e impresión para sus aplica- ciones en Delphi y C++ Builder. Olvídese de BeginDoc, EndDoc, NewPage y otros procedimientos de bajo nivel. Sólo dibuje su trabajo de impresión y Print Suite hará el resto. >>>>> http://www.greatis.com/printsuite.htm ________________________________________________________________________ 3. APLICACIONES SIN VCL (I) Por José Manuel Rodríguez (JMR) CopyRight: JMR, Madrid 1997/1999/2002 Antecedentes ============ La VCL de Delphi permite hacer en unos minutos cosas extraordinarias que en otros entornos llevarían horas y horas. Basta con con escribir cuatro cosas y dos golpes de ratón. Sin embargo esto conlleva un precio, y es la huella ("footprint") que deja en el tamaño del producto final el uso de la VCL. En efecto, cada vez que usamos un componente nuevo, todas las unidades de la VCL que directa o indirectamente dan soporte a dicho componente, incluyendo componentes relacionados pasan a formar parte de nuestro ejecutable DLL, enlazándose buena parte de su código con el nuestro (el enlace inteligente -SmartLinking- hace que no se enlace todo el código de todas las unidades sino sólo lo referenciado, pero da igual eso es mucho código). Esto sólo ocurre la primera vez que se emplea un componente nuevo, desde luego, los sucesivos componentes de ese tipo o relacionados que se añadan a continuación ya producen incrementos de memoria muy pequeños (buena parte del código de los ancestros comunes ya estaba incluida por el uso de otros componentes), pero eso no quita que haya al inicio, y al añadir ciertos componentes, unos incrementos brutales, así por ejemplo, el uso de un simple TButton produce un incremento súbito en el tamaño del código del orden de 150-200K, aunque a partir de entonces todos los controles estándar que se vayan incor- porando apenas añadirán 1 o 2K cada uno al tamaño total, pero si a continuación añadimos, por ejemplo, un control común, como pueda ser un TListView, el tamaño se vuelve a disparar, aunque de nuevo, a partir de entonces cada nuevo control común ("common control") que añadamos producirá un incremento despreciable en el tamaño del PE final. La aparición de los paquetes ("packages") en Delphi 3 viene a paliar en parte este problema en ciertos aspectos. Un package no es otra cosa que una DLL un tanto especial en el sentido que los recursos que proporciona sólo son en principio accesibles desde programas escritos en Object Pascal (o C++ escrito con Borland C++ Builder) ya que usa tipos y estructuras específicos de Delphi, pero totalmente estándar en todos los demás aspectos. Poniendo todos los componentes, fragmentos de código, etc. más usados por una serie de programas en un package, podemos reducir drásticamente el tamaño de cada uno de los programas de esa serie, que compartirán con todos los demás los recursos almacenados en el package. Si bien esta solución es ideal, por ejemplo, para distribuir ejecutables o DLLs a través de Internet, ya que podemos hacer un package con todos los componentes y rutinas que usemos en todos nuestros programas y distribuirlo una única vez a modo de run-time y a partir de entonces podríamos distribuir unos ejecutables extremadamente pequeños pero que necesitarían de dicho run-time para poder ser utilizados, esto no tiene trascendencia alguna cuando hablamos de programas individuales, ya que el hecho es que la suma de los tamaños del package más nuestro programa es en realidad mayor que el tamaño de un programa enlazado a la manera tradicional. Mientras que renunciar a la comodidad y versatilidad de la VCL para casi cualquier proyecto que merezca el nombre de tal sería poco menos que una locura, para proyectos mínimos, como pequeñas utilidades y cosas de ese tipo o sobre todo para la creación de DLLs o aplicaciones de consola, el uso de la VCL es totalmente superfluo, de hecho muchas veces ni siquiera la usamos aunque hacemos inadvertidamente referencias a la misma, lo que provoca la inclusión de su código en nuestro producto final, encontrán- donos con una DLL de proporciones desorbitadas y las causas de cuyo tamaño no nos explicamos muy bien. Normalmente las referencias inadver- tidas a la VCL las habremos hecho en algún aspecto visual de nuestro programa, normalmente en la interacción con el usuario ("mostrar datos a" o "recabar información del" usuario). Pues bien, las rutinas que aquí se presentan pretenden solucionar este aspecto proporcionando cuadros de diálogo para entrada y salida de datos que no usan la VCL sino recursos estándar de Windows y llamadas al API de Windows. El que esto escribe logró pasar de una DLL de cerca de 900K a una DLL que no llegaba a 150K, obviamente hubo que tomar varias cosas en consideración, esta unidad no es la purga de Benito y su mera inclusión no soluciona automáticamente las cosas, pero el resultado final se debe en un 90% al uso de esta unidad. Por supuesto, por su parte esta unidad no interfiere en absoluto con la VCL, por lo que si se desea se puede emplear sin problemas conjuntamente con esta. En los ejemplos que la acompañan, se ha hecho un programa exactamente igual de dos maneras distintas, una (ConVCL.DPR) usando la VCL ha ocupado 178K, la otra, usando solo APIDlgs (SinVCL.DPR), ha ocupado sólo 42K! (puede comprobarlo). En cualquier caso, como ya se ha reseñado, para aplica- ciones normales no es factible ni deseable prescindir de la VCL, pero encontrará que las funciones aquí incluidas son más versátiles que sus homólogas MessageDlg/InputDlg de la VCL, así que de todas formas, aunque use la VCL, puede querer seguir usando APIDlgs. Descripción =========== La unidad contiene dos grupos de familias bien diferenciadas, el primero (APiMsgShow, APIInput y sus hermanas descafeinadas QuickShow y QuickInput) usan recursos estándar de Windows creados con un editor convencional, mientras que el segundo (APIMsgBox y CriticalMsg) usan una función interna de Windows (la misma que usa la conocida MessageBox), y por tanto recursos contenidos en las propias librerías de Windows para mostrarse. APIShowMsg ---------- function APIShowMsg(hParent: THandle; const cTitle, cText: String; Buttons: TAPIDlgBtns; DefaultBtn: TAPIDlgBtn; hIcon: THandle; HelpCtx: Integer): TAPIDlgBtn; Muestra un mensaje en pantalla y espera que el usuario pulse un botón de entre los que se le muestran en respuesta a dicho mensaje. * Devuelve: Devuelve el botón que ha sido pulsado. * Parámetros: - hParent: Handle de la ventana padre, puede ser nulo (0). - cTitle: Título que aparecerá en el Caption del diálogo. - cText: Texto (hasta 1024 caracteres) del mensaje que se quiere mostrar. - Buttons: Es un conjunto donde cada elemento es uno de los botones que se quieren mostrar. Los botones son del tipo TAPIDlgBtn, que es un tipo totalmente idéntico al tipo TDlgBtn usado por la función estándar de la VCL MessageDlg. - DefaultBtn: Indica el botón por defecto, es decir el botón que aparecerá con un borde más obscuro y que inicialmente tendrá el foco. La pulsación de la tecla mientras el diálogo tenga el foco equivaldrá a la pulsación de este botón. De igual forma, si se ha incluido un botón cancelar, la pulsación de la tecla equivaldrá a la pulsación de dicho botón, siendo ignorada en caso contrario. - hIcon: Handle del icono que queremos que se muestre. Puede ser un handle normal que hayamos conseguido nosotros mismos mediante la llamada a LoadIcon, o bien, uno de estos valores predefinidos: AD_NOICON No se muestra ningún icono. AD_ICONDLG Se muestra el icono asociado a esta unidad AD_ICONHAND, AD_ICONEXCLAMATION, AD_ICONINFORMATION, AD_ICONQUESTION, AD_ICONWIN, AD_ICONAPPLICATION Estos son los iconos de Windows AD_ICONOWN Normalmente cada programa Windows tiene un icono asociado y además en Delphi dicho icono recibe el nombre de MAINICO, de cumplirse estas circunstancias, este será el icono que se mostrará, sino este valor es equivalente a AD_ICONWIN. - HelpCtx: ID del contexto de la ayuda, si es distinto de 0, aparecerá un botón de ayuda en el diálogo, aunque no haya sido incluido explícitamente. Cuando aparece el botón de ayuda, este es manejado internamente, al contrario que el resto de los botones, y manda un mensaje WM_DLGHELP a la ventana padre, con WPARAM igual al HelpCtx indicado. QuickShow --------- function QuickShow(cTitle, cText: String; Buttons: TAPIDlgBtns): TAPIDlgBtn; La función APIMsgShow es bastante potente y versátil, pero resulta un tanto engorroso tener que introducir tantos parámetros al llamarla. QuickShow es una simple función "wrapper" alrededor de APIMsgSHow que sólo recibe los parámetros imprescindibles, supliendo el resto con los valores más comunes, así el Handle de la ventana padre será siempre el de la ventana activa, el botón por defecto será siempre el botón "Aceptar" si existe y si no el primero que aparezca, no habrá contexto de ayuda y el icono será del tipo ADD_ICONOWN. APIInput -------- function APIInput(hParent: THandle; const cTitle, cText: String; hIcon: THandle; HelpCtx: Integer): String; Muestra un breve mensaje (prompt) en un cuadro de diálogo y espera que el usuario la suministre una línea de texto (hasta 1024 caracteres). Esta función es de todas la que más imprescindible es, ya que mal bien, para mostrar mensajes podríamos apañarnos con la función estándar de Windows, para recibir información del usuario no hay absolutamente nada. * Devuelve: Devuelve la cadena de caracteres introducida por el usuario si este ha pulsado aceptar o una cadena vacía en cualquier otro caso. * Parámetros: - hParent: Handle de la ventana padre, puede ser nulo (0). - cTitle: Título que aparecerá en el Caption del diálogo. - cText: Texto (hasta 1024 caracteres) del mensaje que se quiere mostrar, normalmente una pregunta dirigida al usuario. - hIcon: Handle del icono que se quiere mostrar. Tiene el mismo significado que en APIMsgShow (consultar). - HelpCtx: ID del contexto de la ayuda. Tiene el mismo funcionamiento y significado que en APIMSgShow (consultar). QuickInput ---------- function QuickInput(cTitle, cText: String): String; Al igual que en el caso de APIMsgShow, esta función resulta algo engorrosa de manejar por el número de parámetros que hay que pasarle, aunque ciertamente menos que a aquella. QuickInput es simplemente un wrapper alrededor de APIInput, a la que suministra los parámetros más usuales, a saber: el Handle de la ventana padre es siempre el de la ventana que estuviese activa al ser invocado este cuadro de diálogo, no hay contexto de ayuda y el icono es de tipo AD_ICONOWN. APIMsgBox --------- function APIMsgBox(hParent: THandle; const cTitle, cText: String; WinFlags: LongInt; HelpCtx: Integer): LongInt; Las funciones anteriores usan recursos propios y los parámetros empleados son del tipo de los empleados en la VCL. En cambio, en esta función, se emplean parámetros al estilo clásico de Windows (es decir, banderines o flags en una doble palabra en vez de los tipos basados en tipos definidos y conjuntos de la VCL) y usa los propios recursos de las librerías constituyentes de Windows. En realidad, APIMsgBox no es otra cosa que la archiconocida MessageBox (y usa la misma subfunción subyacente que ésta usa), pero con menos limitaciones, sobrepasando los dos mayores inconvenientes que presenta MessageBox, a saber: en primer lugar, los cuadros de mensajes estándar de Windows son eso, demasiado estándar, hay que leerlos detenidamente para enterarse a que aplicación pertenecen, esto lo paliamos un poco mediante la personalización del icono, y por otro lado, no tienen botón de ayuda y aunque lo tuviesen no está integrado en un sistema de ayuda al estilo Delphi, esto también se ha logrado solucionar. * Devuelve: devuelve en un entero largo un identificador del botón pulsado para cancelar el diálogo, al estilo IDOK, IDCANCEL, etc., exactamente igual que MessageBox (consultar ayuda del API de WIN32). * Parámetros: - hParent: Handle de la ventana padre, puede ser nulo (0). - cTitle: Título que aparecerá en el Caption del diálogo. - cText: Texto (hasta 1024 caracteres) del mensaje que se quiere mostrar. - WinFlags: Se corresponde con el parámetro dwStyle de MessageBox. Al contrario que en las funciones anteriores, a las funciones estándar de Windows se les indican los botones, iconos, etc. que tienen que mostrar activando flags en una palabra (o doble palabra). En este caso los flags admitidos son los mismos que admita la función MessageBox (Consultar ayuda del de Win32), con las siguientes novedades: MB_NOICON No se muestra ningún icono. MB_ICONDLG Se muestra el icono asociado a esta unidad. MB_ICONOWN Normalmente cada programa Windows tiene un icono asociado y además en Delphi dicho icono recibe el nombre de MAINICO, de cumplirse estas circunstancias, este será el icono que se mostrará, sino este valor es equivalente a MB_ICONDLG. CriticalMsg ----------- procedure CriticalMsg(const Title, Text: String); Está función en realidad no es más que una llamada muy concreta a MessageBox y está incluida únicamente por motivos de presentar una unidad lo más completa posible y porque parece el sitio más adecuado dada la temática de dicha unidad. Cuando se produce un error crítico en Windows, el sistema puede estar inestable, sin recursos o cualquier otra situación desagradable similar. El intentar en esas circunstancias recabar encima más recursos para mostrar un mensaje de error puede traer consecuencias aún más funestas. Sin embargo, al arrancar, Windows carga y pone aparte a buen recaudo los recursos indispensables para mostrar un mensaje de error si se dan esas circunstancias. Para mostrar dicho mensaje, hay que llamar a MessageBox con los flags MB_SYSTEMMODAL y MB_ICONSTOP, y un Handle de 0, que es simplemente lo que hace esta función. * Devuelve: ---- * Parámetros: - cTitle: Título que aparecerá en el Caption del diálogo. - cText: Texto (hasta 1024 caracteres) del mensaje que se quiere mostrar. (En cualquier caso, bajo estas circunstancias Windows limita el texto mostrado a un máximo de 3 líneas. Comentarios =========== a) Esta unidad compilará sin problemas en 32 bits, tanto en D2 como en D3. No se ha probado en 16 bits, pero no veo por qué, a excepción de APIMsgBox que se basa en una función de Win32, no debería funcionar, si alguien quiere tomarse las molestias de ponerse los defines oportunos y probarlo en 16 bits, adelante, y si logra un resultado positivo, que por favor me lo comunique, estaré encantado de añadirlo a este paquete y por supuesto incluirle en los créditos. Por mi parte, yo no puedo luchar contra Microsoft, y dado el empeño de este último de cargarse a su propia criatura de 16 bits (que no a seguir empleando código de 16 bits, que no es lo mismo) yo he renunciado a programar para Win 3.x. b) Esta unidad ha sido probada, aunque no demasiado exhaustivamente porque en realidad tiene poco misterio la cosa. No se ha encontrado ningún 'bug', pero no se puede garantizar que este libre de ellos c) Todo el código incluido es original del que subscribe, pero ha podido llevarse a buen término gracias a la colaboración, consejos y suge- rencias de algunos compañeros programadores, principalmente Nicolás Aragón (nico@nicoaragon.com), así como las reflexiones sobre este tema mantenidas en la lista de programación Delphi delphi-intermedio (consultar http://www.latiumsoftware.com). Toda la base teórica puede encontrarse en los libros y artículos (PC Magazine USA) sobre Windows de 32 bits de Charles Petzold y sobre Delphi de Neil J. Rubenking. d) Esta unidad puede ser utilizada de forma totalmente gratuita en programas compilados sin ningún tipo de restricción, aunque de ser usada se agradecería una mención al autor en los créditos del programa que haga uso de ella. En caso de ser distribuida en forma de fuentes, ha de ser distribuida la totalidad del paquete, con todos los ficheros íntegros, incluyendo las notificaciones de copyright, y estará prohibido el cobro de cualquier cantidad, excluyendo el soporte, por dicha distribución. Esta unidad se suministra tal cual, sin garantías de ningún tipo, y su uso no implica que el autor sea responsable de ninguna consecuencia nefasta que éste pudiera conllevar. El autor tampoco se compromete a mantenerla, dar soporte técnico, etc., aunque está en su ánimo hacerlo de manera voluntaria. (¡Total! por ese precio). Es esta entrega se incluye la unidad APIDlgs y un par de aplicaciones de ejemplo. En la próxima entrega se incluirá la unidad APIApp que nos permitirá más flexibilidad para crear aplicaciones sin VCL. Cualquier sugerencia, corrección o crítica (constructiva, claro) será bien recibida en: José Manuel Rodríguez (jmr@clubdelphi.com) ________________________________________________________________________ SMImport component suite 1.46 - Components for data loading from Text, CSV, HTML, XML, MS Excel (without OLE), MS Access (without the BDE), Lotus 1-2-3, QuattroPro and Paradox/DBF. Available for Delphi 3-6 and CBuilder 3-6. Price $35. >>> http://www.scalabium.com/smi/index.htm <<< ________________________________________________________________________ 4. ENSAMBLADOR EN DELPHI Por Max Kleiner <max @ kleiner.com> Hemos sabido desde siempre que OP (Object Pascal) produce código rápido y eficiente, y si sumamos a esto el entorno de desarrollo rápido (RAD) de Delphi y Kylix, la necesidad de usar ensamblador se vuelve una incógnita. Este artículo es en cierta manera un extracto del excelente escrito de Ian Hodger "Aprendiendo Ensamblador con Delphi" (Learning Assembler with Delphi), que se puede encontrar en: http://www.delphi3000.com/articles/article_2245.asp Era el deseo de mis estudiantes el resumirlo y decir unas pocas palabras sobre depuración. Adjunto encontrarán un ejemplo impresionante de ensamblador: muestra un gráfico de llamas de fuego en la pantalla. En todo nuestro trabajo con OP, enfrentamos solamente cinco situaciones en las que uno consideraría el uso de código de bajo nivel: 1. Recorrer y procesar grandes cantidades de datos. Por supuesto excluyo de esto cualquier situación donde se emplee un lenguaje de consulta de datos con un optimizador de consultas, lo que no es generalmente el caso en un entorno de automatización o microcontrolador. 2. Por razones científicas, para proveer simulaciones de alta velocidad o sólo para educación en la secuencia Compiladores-Ensamblador- Enlazador-Cargador. Yo llamo a esto CALL (Compiler-Assembler-Linker- Loader). 3. Para programación de controladores, o para desarrollar o probar periféricos tales como dispositivos COM, por ejemplo para detectar puertos serie libres (en cuanto a Windows concierne...) e invocar algunas funciones que Windows no permite, por ejemplo no detecta un puerto serie si hay conectado un ratón. Utilice una llamada DPMI con ensamblador. 4. Rutinas de presentación de alta velocidad; aquí queremos rutinas veloces y simples en OP, no extrañas cabeceras de C++, librerías de funciones externas o confusas demandas de hardware como las de DirectX. 5. Algoritmos de encriptación robustos y veloces como cifradores, "hashes", o sumas de comprobación, con las rutinas principales de codificación y decodificación escritas en código ensamblador altamente optimizado. Decir que escribir código de máquina es cómodo sería una simplificación, y en cuanto a depurar lenguaje ensamblador es solamente una forma fácil de recordar cuáles operaciones de código máquina están disponibles. El trabajo de convertir a código de máquina es realizado por un ensam- blador, por lo que el Turbo Assembler de Borland está incorporado en Delphi. Hagamos un poco de práctica: Si queremos sumar el entero 15 al registro eax, la instrucción apropiada en ensamblador es add eax,15 // a := a + 15 Casi igualmente, para sustraer el valor de ebx de eax sub eax,ebx // a := a - b Para guardar un valor en espera de mejores días, podemos moverlo a otro registro mov eax,ecx // a := c o mejor aún, guardar el valor a una dirección de memoria mov [1733],eax // almacena el valor de eax en la dirección 1733 y por supuesto lo recuperamos con mov eax,[1733] Esto significa que el número más grande que podemos almacenar en un registro, por ejemplo eax, es 2 elevado a la potencia 32 menos 1, o exactamente 4294967295. Tenga en cuenta el tamaño de los valores que está moviendo; la instruc- ción mov [1733],eax afecta no sólo a la dirección 1733 sino también a 1734, 1735 y 1736, ya que como recordará eax tiene 32 bits de largo, o 4 bytes, por lo que la memoria se direcciona siempre en bytes! Para realizar un incremento como el siguiente: step := step + 1; escribiríamos algo como esto: mov eax, step add eax, 1 mov step, eax o simplemente: inc step Ahora estamos listos para nuestro primer recort e de código en ensam- blador, dejando de lado la naturaleza simple del ejemplo. Considere las siguientes líneas de código OP: function BigSum(A, B: integer): integer; begin result := A+B; end; OP provee el bloque asm...end como un método para introducir ensamblador puro en nuestro código, por lo que podemos reescribir la función BigSum como: function BigSum(A, B: integer): integer; begin asm mov eax,A add eax,B mov result,eax end; end; Esto funciona bien, pero hay un punto a considerar: no hay ganancia de velocidad y hemos perdido la legibilidad de nuestro código. También puede escribir procedimientos y funciones completos usando código ensamblador embebido ("inline assembler"), sin incluir una sentencia begin...end, por ejemplo: function LongMul(X, Y: Integer): Longint; asm mov eax, X imul Y end; El compilador realiza varias optimizaciones en estas rutinas así que no se genera código para copiar los valores de los parámetros en variables locales. Esto afecta todos los valores de parámetros tipo string y cualquier otro valor de parámetro cuyo tamaño no sea de 1, 2, o 4 bytes. Dentro de la rutina, estos parámetros deben ser tratados como si fueran parámetros por referencia. Si realmente vamos a producir código útil, en algún momento necesita- remos implementar rutinas más complicadas. Por ejemplo si tenemos que mostrar la salida de alguna función dependiente de dos variables. Puede imaginar esto como un mapa tridimensional, donde las coordenadas [X,Y] corresponden a una altura H. Cuando graficamos el punto [X,Y] en la pantalla necesitamos dar una idea de profundidad. Esto puede hacerse usando colores de diferente intensidad, azul por debajo del nivel del mar y verde por encima. Lo que se necesita es una función que convierta una altura dada en color de la apropiada profundidad para un determinado nivel del mar. Depurando código ---------------- Para finalizar este artículo, digamos unas pocas palabras acerca de la depuración. Es muy fácil establecer "watches", puntos de interrupción ("breackpoints") y ejecutar un programa OP paso a paso. Lo mismo sigue siendo cierto, incluso en programas que usen ensamblador. Todo lo que necesitamos hacer es agregar los cuatro registros generales de 32 bits (eax, ebx, ecx y edx) a nuestra "watch list", y ver el efecto de cada línea en ensamblador. En un shell de DOS, también podemos escribir "debug" y luego "u" para desensamblar. El ensamblador incorporado le permite escribir código ensamblador para Intel dentro de sus programas en OP. Implementa un gran subconjunto de la sintaxis soportada por Turbo Assembler y Microsoft Macro Assembler, incluyendo todos los códigos de operación ("opcodes") de 8086/8087 y 80386/80387, pero soporta unos pocos operadores de expresiones de Turbo Assembler. Las funciones en ensamblador devuelven sus resultados como sigue: - Los valores ordinales se devuelven en AL (valores de 8 bits), AX (valores de 16 bits), o EAX (valores de 32 bits). - Los valores reales se devuelven en ST(0) en la pila de registros del coprocesador. - Punteros, incluyendo cadenas largas, se devuelven en EAX. - Cadenas cortas y valores variantes se devuelven en una ubicación temporaria apuntada por @result. Espero que sientan un poco la velocidad de Delphi y agradezco a Ian por sus fundamentos. ________________________________________________________________________ 5. TTRAYCOMPONENT Stewart Moss <stewartm @ idcorpholdings.com> presenta su modificación de TrayComponent para hacer que el código "Mostrar en Barra de Tareas" funcione en Windows 2000/NT. TrayComponent fue escrito originalmente por Alexander Rodigin, basado en el componente Stealth de Janus N. Tøndering el componente TrayIcon de Pete Ness. El componente modificado es en el archivo TrayComp.pas. ________________________________________________________________________ 6. IMPEDIR QUE WINDOWS MUESTRE MENSAJES DE ERRORES CRÍTICOS Por Zarko Gajic http://delphi.about.com Cuando se realizan ciertas funciones es necesario que nuestro programa tome el control total sobre los mensajes de error. Por ejemplo, si su programa quiere verificar "silenciosamente" si una unidad de discos flexibles tiene un disco dentro, es posible que no quiera que Windows muestre un "Error Crítico" si de hecho la unidad está vacía. Se puede controlar cuáles mensajes de error mostrará Windows usando la función Win API "SetErrorMode()" como sigue: var wOldErrorMode: Word; begin // indicar a Windows que ignore errores críticos // y almacene el modo de error actual wOldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS); try // el código que podría genera un error crítico va aquí... finally // volver al modo de error previo SetErrorMode(wOldErrorMode); end; end; ________________________________________________________________________ 7. MOSTRANDO EL DIALOGO "BUSCAR CARPETA" DE WINDOWS (II) Por Ernesto De Spirito <eds2004 @ latiumsoftware.com> En la última entrega publiqué el código fuente para mostrar el diálogo estándar de Windows "Buscar carpeta", y como recibí varios comentarios sobre el tema, pensé que el artículo merecía una segunda parte abordando algunas cuestiones planteadas por los lectores. SelectDirectory =============== Mucha gente me recordó que la función SelectDirectory que reside en la unidad FileCtrl cumple la misma función. Bueno, en realidad esto no es correcto... Una de las dos versiones (la función esta sobrecargada) permite fijar el nodo raíz pero no el directorio seleccionado: var Directory: string; begin Directory := 'C:\Delphi\'; if SelectDirectory('Seleccionar carpeta', '', Directory) then ShowMessage(Directory); end; La otra versión de SelectDirectory permite fijar el directorio seleccio- nado, pero no el directorio raíz, aunque tiene algunas características interesantes (se puede permitir la creación de directorios, y se puede proveer un ID de contexto de ayuda), pero esta versión de la función no usa el cuadro de diálogo estándar de Windows: var Directory: string; begin Directory := 'C:\Delphi\'; if SelectDirectory(Directory, [], 0) then ShowMessage(Directory); end; Destruyendo PIDLs ================= En el código del artículo anterior usé GlobalFreePtr para liberar la memoria utilizada por el PIDL. Es una forma fácil y rápida de hacerlo, pero no es seguro. Los PIDLs deberían ser liberados llamando a IMalloc.Free. Una manera fácil de reemplazar a GlobalFreePtr podría ser usando la siguiente función: uses shlobj, ActiveX; procedure IMallocFree(Ptr: Pointer); var pMalloc: IMalloc; begin if Succeeded(SHGetMalloc(pMalloc)) then pMalloc.Free(Ptr); end; Directorio Raiz como una cadena =============================== Un par de lectores pidieron que en lugar del CSIDL de una carpeta especial la raíz pudiera ser cualquier directorio dado como una cadena, por lo que hice unos cambios en el código fuente para obtener el valor correspondiente a TBrowseInfo.pidlRoot basado en el parámetro 'root' (ahora llamado RootFolder, un WideString): : function BrowseForFolder(Title: string; RootFolder: WideString = ''; InitialFolder: string = ''): string; var : IDesktopFolder: IShellFolder; Eaten, Attributes: LongWord; begin with BrowseInfo do begin : pidlRoot := nil; if RootFolder <> '' then begin SHGetDesktopFolder(IDesktopFolder); IDesktopFolder.ParseDisplayName(Application.Handle, nil, PWideChar(RootFolder), Eaten, pidlRoot, Attributes); end; : end; : end; ________________________________________________________________________ 8. FOROS Recordamos a los suscriptores las direcciones de nuestros foros. Para unirse a algún foro, lo más recomendable es hacerlo desde la web para así tener acceso a todas las áreas del foro y la configuración de las opciones de suscripción, pero también es posible suscribirse por email. Para suscribirse desde la web es necesario poseer un ID de Usuario de Yahoo! (si no tienes el tuyo, puedes conseguirlo gratis registrándote como usuario de Yahoo!). * Delphi-abierto. Programación en Delphi (todos los niveles). Si estás en la etapa de aprendizaje o si no te agradan los foros discriminados por niveles, este foro es para ti. http://espanol.groups.yahoo.com/group/delphi-abierto Suscripción: http://espanol.groups.yahoo.com/group/delphi-abierto/join delphi-abierto-subscribe@gruposyahoo.com * Delphi-intermedio. Programación en Delphi (nivel intermedio). Si ya sabes mucho de Delphi, pero todavía te falta un largo trecho para ser un gurú (o no tanto), este foro es para ti. http://espanol.groups.yahoo.com/group/delphi-intermedio Suscripción: http://espanol.groups.yahoo.com/group/delphi-intermedio/join delphi-intermedio-subscribe@gruposyahoo.com * Delphi-avanzado. Programación en Delphi. Sólo para gurús. http://espanol.groups.yahoo.com/group/delphi-avanzado Suscripción: http://espanol.groups.yahoo.com/group/delphi-avanzado/join delphi-avanzado-subscribe@yahoogroups.com * GrupoKylix. Programación en Kylix. http://espanol.groups.yahoo.com/group/GrupoKylix Suscripción: http://espanol.groups.yahoo.com/group/GrupoKylix/join GrupoKylix-subscribe@yahoogroups.com * FreePascal-es. Programación en Free Pascal (freepascal.org). http://espanol.groups.yahoo.com/group/freepascal-es Suscripción: http://espanol.groups.yahoo.com/group/freepascal-es/join freepascal-es-subscribe@yahoogroups.com * Desarrolladores-Software. Un lugar para tratar todos aquellos temas relacionados con el desarrollo de software y su comercialización, y para compartir experiencias en el ámbito laboral, profesional o comercial con otros. http://es.groups.yahoo.com/group/desarrolladores-software Suscripción: http://es.groups.yahoo.com/group/desarrolladores-software/join desarrolladores-software-subscribe@yahoogroups.com * Componentes. Un foro para buscar/recomendar componentes de software (componentes VCL y CLX, objetos ActiveX, librerías DLL, etc.), así como utilidades, tutoriales, información, etc. http://espanol.groups.yahoo.com/group/componentes Suscripción: http://espanol.groups.yahoo.com/group/componentes/join componentes-subscribe@yahoogroups.com ________________________________________________________________________ 9. DELPHI EN LA RED Por Dave Murray Componentes, librerías y aplicaciones ===================================== Shareware/Comercial ------------------- * Database Pro v1.14 - by IMG Software Database Pro incluye once componentes que le brinda la forma más simple y rápida de filtrar o buscar valores en una base de datos. Con Database Pro usted obtendrá la forma más simple de asignar condiciones de filtrado / obtención de datos. Database Pro soporta BDE, MIDAS, ADO, InterBase, KADao y cualquier alternativa. Database Pro se encuentra actualmente disponible en 18 idiomas. http://www.imgsoft.com * RichView Package - by TRICHVIEW.COM. Shareware ($139) RichView is a suite of native Delphi/C Builder components for editing formatted documents with images, tables and hypertext links. Customizable attributes of text and paragraphs, Unicode, bi-directed text, HTML export, RTF, printing, data-aware versions and more... http://www.trichview.com/ * SMImport Suite v1.46 - by Scalabium, Mike Shkolnik SMImport suite is a components for data loading from Text, CSV, HTML, XML, MS Excel (without OLE), MS Access, Lotus 1-2-3, QuattroPro and Paradox/DBF. Available for Delphi 3-6 and CBuilder 3-6, price: $35. http://www.scalabium.com (mshkolnik@scalabium.com) Freeware -------- * dbExpress InterBase 6.5 driver for Delphi 6 available - by J Kaster http://community.borland.com/article/0,1410,28508,00.html Artículos, trucos y consejos ============================ * Bring RAD to your Web app development with WebSnap - by GetPublished WebSnap enables Delphi to build the scriptable business objects, database driven web pages, and back-end servers that are integral to a successful, dynamic web site. http://community.borland.com/article/0,1410,28567,00.html * Simple scripting with NetCLX extension components - by John Kaster C++ Builder 6, Delphi 6 and Kylix all have new RTTI functions that make simple scripting much easier to implement. John K shares some producer components that show how. http://community.borland.com/article/0,1410,28551,00.html * From XML to Object: Part II - by Keith Wood Wraps up this series on the XML Data Binding Wizard with sample applications that demonstrate how to read and display XML documents and generate new ones. www.delphimag.com/features/2002/04/di200204kw_f/di200204kw_f.asp * A Smart Combo Box, etc - by Bruno Sonnino How to create a combo box that remembers the user's selection or entry, and offers it as the default the next time around and tips for RadioGroups and What's This? help. www.delphimag.com/features/2002/04/di200204bs_f/di200204bs_f.asp * Taming the Beast from Redmond - by Dave Ball A step-by-step explanation of how to deploy ISAPI DLLs within an MTS or COM+ memory-protected development environment, by configuring IIS settings within the MMC. www.delphimag.com/features/2002/04/di200204db_f/di200204db_f.asp * Take Action - by Bill Todd If you want your menus and toolbars to have the look and feel of Office 2000, the ActionManager and ActionBars in Delphi 6 may be just the ticket. www.delphimag.com/features/2002/04/di200204bt_f/di200204bt_f.asp * How to get an MP3's ID3-Tag? http://www.swissdelphicenter.ch/en/showcode.php?id=121 * How to load Rft Text from a resource file into a TRichEdit? http://www.swissdelphicenter.ch/en/showcode.php?id=1049 * How to refresh the icon cache? http://www.swissdelphicenter.ch/en/showcode.php?id=1054 * How to enable the Return key in a TWebbrowser? http://www.swissdelphicenter.ch/en/showcode.php?id=1055 * How to open local files in a TWebbrowser and start links directly? http://www.swissdelphicenter.ch/en/showcode.php?id=1057 * How to program a peak level meter? - by Steve Schafer http://www.swissdelphicenter.ch/torry/showcode.php?id=1086 * How to show the source code of a webpage in a Memo? - by Screaminator http://www.swissdelphicenter.ch/torry/showcode.php?id=1085 * How to perform a binary seach on a TListview? - by P Below http://www.swissdelphicenter.ch/torry/showcode.php?id=1078 * Add current page of a TWebbrowser to your favorites - by Screaminator http://www.swissdelphicenter.ch/torry/showcode.php?id=1094 * How to connect to an ftp server + download a file? - by Thomas Stutz http://www.swissdelphicenter.ch/torry/showcode.php?id=1095 * How to check if a given folder is empty - by Christian Cristofori http://www.delphi3000.com/articles/article_3095.asp * Component for saving User Settings (using Tools API) - D Wischnewski Writing a Component, a Component Editor and a Property Editors. http://www.delphi3000.com/articles/article_3096.asp * A Simple Notepad with Delphi 6 - by S S B Magesh Puvananthiran http://www.delphi3000.com/articles/article_3098.asp * Implementation of the State Design Pattern - by Jochen Fromm http://www.delphi3000.com/articles/article_3099.asp * Find full path of registered Applications - by Andreas Schmidt http://www.delphi3000.com/articles/article_3101.asp * Exporting Syntax Highlighted text to HTML - by Danilo Vieira http://www.delphi3000.com/articles/article_3103.asp * Converting HTML colour names and codes to TColor - by D Wischnewski http://www.delphi3000.com/articles/article_3104.asp * Writing all controls of given component to TXMLDocument - by N Ozniev http://www.delphi3000.com/articles/article_3106.asp * Sending email in console mode - by Arman Rad http://www.delphi3000.com/articles/article_3107.asp * Creating High Performance Middleware Apps with Indy - by Romeo Lefter Indy Step by Step part 4. http://www.delphi3000.com/articles/article_3108.asp * Move or resize a TControl object graphically - by Bertrand Goetzmann Graphically move or resize a TControl object by using another object that has all the necessary code. http://www.delphi3000.com/articles/article_3109.asp * How to get the long path and file name? - by Maarten de Haan How to get the long path and file name from a DOS name. http://www.delphi3000.com/articles/article_3110.asp * Viewing Targa Bitmap File Format in Delphi (256-colors) - by h4ry p http://www.delphi3000.com/articles/article_3113.asp * Easiest way to draw a transparent image - by h4ry p http://www.delphi3000.com/articles/article_3115.asp * Un-hiding Properties - by Romeo Lefter Unhiding some usefull properties for VCL controls. http://www.delphi3000.com/articles/article_3116.asp * PAS 2 HTML converter - by Eber Irigoyen Sourcecode to HTML converter for web pages with highlighted syntax. http://www.delphi3000.com/articles/article_3117.asp * Grab the PC Serial Number & BIOS info using WMI calls - by Doug Good Windows Management Instrumentation Calls in Delphi. http://www.delphi3000.com/articles/article_3118.asp * Windows detection routines - by Ronald Buster Here is how to find out the Windows versions for all versions. http://www.delphi3000.com/articles/article_3119.asp * Easy logger - by Eber Irigoyen http://www.delphi3000.com/articles/article_3121.asp * Placing icons in DBGrid - by Fahad Aljarbou http://www.delphi3000.com/articles/article_3122.asp * Extract Icons from .exe, .dll, .lnk - by Prashant Gulati http://www.delphi3000.com/articles/article_3126.asp * Syntax Highlighted Source Code Export to HTML or RTF - by Jim McKeeth Export many different source code files into HTML or FTP with Syntax Highlighting and end user customization http://www.delphi3000.com/articles/article_3128.asp * Web Page to Image File - by Jim McKeeth How to get the URL from IE, open it with PBear's THTMLViewer and save it as a image file. http://www.delphi3000.com/articles/article_3129.asp * A simple class to implement compound files - by David Bolton How do I store multiple files within one compound file? http://www.delphi3000.com/articles/article_3130.asp * Improving your Object classes reliability - by David Bolton How to reference count the easy way. http://www.delphi3000.com/articles/article_3132.asp * How to send HTML messages with attachments (using Indy) - by N Cross Using IdMessage to send HTML formatted emails with attachments. http://www.delphi3000.com/articles/article_3133.asp * How to parse a wave file? - by Liran Shahar Parsing a wave file to access each of its chunks. http://www.delphi3000.com/articles/article_3134.asp * SignalDisplay component - by Liran Shahar Ever wanted to display audio from a microphone or see wave file samples like CoolEdit does? http://www.delphi3000.com/articles/article_3135.asp * How to get keys, like up,down,left, right? - by Etienne Nijboer http://www.delphi3000.com/articles/article_3136.asp * Determine If a File has One of Several File Extensions - by John Long http://www.delphi3000.com/articles/article_3137.asp * Changing IE Proxy Settings - by Shannon Wynter How do I set proxy settings in IE without having to restart? http://www.delphi3000.com/articles/article_3138.asp * How do we implement the Choice Pattern - by Max Kleiner Working with Interfaces. http://www.delphi3000.com/articles/article_3141.asp * How to make a Window with RAW API - by Simone Di Cicco http://www.delphi3000.com/articles/article_3142.asp * From XML to Object: Part I - by Keith Wood The Delphi 6 XML Data Binding Wizard. www.delphimag.com/features/2002/03/di200203kw_f/di200203kw_f.asp * Differential Equations - by Alexander Gofen Implement the Taylor center, a powerful numeric and expression- processing application with extensive visual features, in Delphi. www.delphimag.com/features/2002/03/di200203ag_f/di200203ag_f.asp * Hot Spots: Part II - by Victor Hornback Build a custom component, showing how to register a custom property editor, stream non-published data, and more. www.delphimag.com/features/2002/03/di200203vh_f/di200203vh_f.asp * Spreadsheet Data via ADO, ODBC, or Automation - by Bill Todd A detailed explanation and example projects for accessing MS Excel spreadsheet data via ADO, ODBC, or automation. www.delphimag.com/features/2002/03/di200203bt_f/di200203bt_f.asp * Bug in StringReplace (Handling Null characters) - by Stewart Moss Workaround for a bug in StringReplace function when used on a string which contains NULL (#0) characters (not null terminated). http://www.delphi3000.com/articles/article_3090.asp * Making a "recent files" menu - by Dan Strandberg How to make a simple "recent files" menu/list in your application. http://www.delphi3000.com/articles/article_3091.asp * Yet another "recent file" menu - by Magnus Flysjö http://www.delphi3000.com/articles/article_3093.asp * RGB and HSV conversions - by William Egge Explains HSV and RGB colour values and includes source for converting between the two. http://www.delphi3000.com/articles/article_3094.asp * Quiz: Delphi ADO Programming - by Zarko Gajic Who Wants to be a Delphi ADO Database Programming Guru - trivia game. One copy of a great Delphi book will be given away in this "competition". Closing date is 31st May and a winner will be picked randomly on 1st June. http://delphi.about.com/library/weekly/aa030502a.htm * Spell Checking with MS Word - by Zarko Gajic Why buy or write spell checking components when you can use MS Word? Add spell checking + thesaurus capabilities to your Delphi app using the MS Word Object Library. http://delphi.about.com/library/weekly/aa032701a.htm * Creating PDF Documents, the free way - by Romeo Lefter How to create easy and fast PDF Documents. http://www.delphi3000.com/articles/article_3076.asp * Implementation of the Memento Design Pattern - by Jochen Fromm How do you implement the MEMENTO Design Pattern in Delphi? A Memento is an object that stores a snapshot of the internal state of another object - the memento's originator. http://www.delphi3000.com/articles/article_3077.asp * Reducing Source Code Complexity in your application - William Egge Using a MessageCenter to link your application systems together. Implementation of an observer pattern except that it uses Delphi's built in message dispatching and also maintains the relationships. http://www.delphi3000.com/articles/article_3079.asp * Creating a simple HTTP Server How to create a simple HTTP server using TIdHTTPServer from Indy and the TPageProducer for simple scripting capabilities. http://www.delphi3000.com/articles/article_3081.asp * Read/write summary information of an Office document - by B Goetzmann How read/write summary information of an Office document? http://www.delphi3000.com/articles/article_3082.asp * How to create disabled bitmap - by Mike Shkolnik How can I create a disabled bitmap from original? http://www.delphi3000.com/articles/article_3085.asp * Convert Tab to Space - Yilmaz Kaygisiz How Can i Change TAB Char To Space in my string? http://www.delphi3000.com/articles/article_3086.asp * String or Number? Undocumented Effects of Val(...) - by D Wischnewski Interesting phenomenon where obvious string is incorrectly converted into a number by Delphi functions Val, IntToStr + InToStrDef. http://www.delphi3000.com/articles/article_3087.asp * Lost your MainForm? - by Eber Irigoyen Has it ever happened to you that the MainForm that you want is not listed in Delphi's Projects|Options|General? http://www.delphi3000.com/articles/article_3088.asp Kylix ----- * Simple scripting with NetCLX extension components - by John Kaster C++ Builder 6, Delphi 6 and Kylix all have new RTTI functions that make simple scripting much easier to implement. John K shares some producer components that show how. http://community.borland.com/article/0,1410,28551,00.html * How to catch kernel-signals in Kylix? http://www.swissdelphicenter.ch/en/showcode.php?id=1059 * How to use RCDATA resources in Kylix? http://www.swissdelphicenter.ch/en/showcode.php?id=1060 * How to clone a process in Linux? http://www.swissdelphicenter.ch/en/showcode.php?id=1061 Tutoriales ========== * Introducción a las expeciones - por Pablo Castagnino Una introducción al mundo de las excepciones. ¿Qué son? ¿Por qué se ideó este mecanismo? ¿Cómo tratarlas? Provocación de excepciones. Clases de excepciones. Creación de nuevas clases de excepciones. http://webs.sinectis.com.ar/alvadel/articulos/exception.htm * Introducción al Registro y los archivos INI - por Pablo Castagnino El Registro de Windows. Que es. Su estructura. Cómo leerlo y modificarlo con Regedit. Cómo leerlo y modificarlo con Delphi. Archivos INI. Qué son. Su estructura. Cómo leerlos y modificarlos. Comentarios. Ejercicios. http://webs.sinectis.com.ar/alvadel/articulos/regini.htm * Cup of Coffee for Dolphins Part I - by John Kaster Java for Delphi programmers. Describes basic Java instructions in comparison with Delphi. http://community.borland.com/article/0,1410,28481,00.html ________________________________________________________________________ ¡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 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/p0034.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!






