Boletín Pascal #52
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #52 - 05-FEB-2005 Índice 1. Unas palabras del editor 2. Cómo agregar un programa al menú "Enviar a" del Explorador 3. Principios introductorios de búsqueda indexada 4. Llenando un TStringList extrayendo los registros de una columna 5. Devolviendo clases desde una DLL 6. Detección de colisión simplificada en programación de juegos 7. Foros / listas de correo 8. Delphi en la Red - Componentes, librerías y aplicaciones · Shareware / Comercial · Freeware · Actualizaciones de productos Borland - Artículos, trucos y consejos - Tutoriales y capacitación - Noticias - Otros / Sitios misceláneos ________________________________________________________________________ Tecno Soft Solutions. Reseller Autorizado de Symbol Technologies, líder mundial en captura de códigos de barras. >>> http://www.tecno-symbol.com ________________________________________________________________________ 1. Unas palabras del editor Continúo poniéndome al día con las traducciones. Esta fue la última edición publicada en inglés el año pasado y quisiera aprovechar la ocasión para agradecerles su constante apoyo durante este año complicado con sus palabras de elogio hacia esta publicación y su aliento para continuar con este proyecto de divulgación de información sobre Delphi en español. Por supuesto, también quisiera aprovechar para agradecer a los autores que contribuyeron artículos o premios este año, permitiendo con su aporte que el boletín pueda continuar, y no quiero olvidarme de los moderadores de los foros, quienes aportan mucho de su tiempo a esa tarea. En este número especial tenemos cinco artículos que espero sirvan como para compensarlos parcialmente por la discontinuidad en la publicación del boletín. Mi agradecimiento a Peter Johnson, Jim McKeeth, Stewart Moss, Max Kleiner y John Pears por contribuir sus artículos al boletín y permitir su traducción al español. Me complace entregar a Stewart Moss, Max Kleiner y John Pears los premios para esta edición: * Stewart Moss - "Llenando un TStringList extrayendo registros..." InstallAWARE 3.0 Express Edition - por MimarSinan Int. ($69.95) Desarrolle instaladores para Windows Installer sin necesidad de conocimiento previo de MSI. InstallAWARE automáticamente convierte en tiempo de creación un script de flujo condicional en una base de datos MSI que cumple con ICE, certificable con logotipo. El IDE ofrece una interfaz visual que genera su script de instalación por usted automáticamente y cuyo comportamiento puede ser completamente adaptado. Sigue vigente la oferta especial por tiempo limitado para los lectores del Boletín Pascal: 30% de descuento para todas las ediciones. ¡La Edición Empresarial a tan sólo $559.95! http://www.installaware.com/landingea.html * John Pears - "Detección de colisión simplificada..." KnowedgeBASE Vortex 2.9 por Delphinium Software ($49.35) El corazón de KnowledgeBASE es un árbol de información altamente expandible y con gran capacidad de búsqueda, que puede verse como esquema o auditado dentro de un procesador de textos incorporado. Incluye una base de datos para referencias guardadas. http://www.download.com/KnowledgeBase-Vortex/3000-2064-10342084.html * Max Kleiner - "Devolviendo clases desde una DLL" KylixDriver v1.1 - por ET Kimberliteware Ltd ($39 / $69 con fuentes) Conjunto de herramientas para el desarrollo de drivers Linux que accedan al hardware de la PC, permitiendo desarrollar con Kylix controladores de dispositivo ISA/PCI para hardware específico. http://www.geocities.com/etkimberliteware/kylixdriver/index.html Un agradecimiento especial a Delphinium Software por donar KnowledgeBASE Vortex como premio continuo para futuras ediciones. Para la próxima edición ya tenemos asignados tres premios: InstallAWARE 3.0 Enterprise Edition, KnowedgeBASE Vortex y YAPI Professional. * YAPI Professional - por Owen Mooney ($95) Ofrece la más fácil y aún así poderosa capacidad de impresión desde Delphi. Provee configuración WYSIWYG, vista preliminar, campos independientes, campos enlazados a datos, texto, grids, tabs, mapas de bits, operación con TCanvas, posicionamiento preciso o de flujo libre, y todo usando sentencias "writeln" simples. http://free.hostdepartment.com/o/owenmooney/ Disponibilidad de tiempo mediante, el calendario de publicación del boletín en inglés para el 2005 será enero (#53), marzo (#54), julio (#55), septiembre (#56), noviembre (#57) y fin de año (#58). Les debo la traducción del #53 cuyo original en inglés se publicó en enero, y con eso estaríamos al día. Se las prometo para la semana que viene. Saludos, Ernesto De Spirito y Dave Murray boltin-pascal-owner@gruposyahoo.com ________________________________________________________________________ Help & Manual 3.50 por EC Software · Shareware ($ 279) - Una herramienta visual de autoría de ayuda para generar archivos WinHelp (.HLP), Adobe PDF, páginas HTML y los nuevos archivos HTML HELP (.CHM) introducidos en Windows 98, así como otros formatos de archivo y documentación impresa, todo desde una misma fuente. Una herramienta imprescindible para cualquier desarrollador de software. http://www.helpandmanual.com/ ________________________________________________________________________ 2. Cómo agregar un programa al menú "Enviar a" del Explorador Por Peter Johnson, Copyright (c) 2003 <delphidabbler at tiscali dot co dot uk> http://www.delphidabbler.com/ Por qué hacerlo --------------- Si está escribiendo un programa de propósito general relacionado con archivos, puede ser útil agregarlo al menú "Enviar a" del Explorador de Windows. Por ejemplo yo coloqué el Bloc de notas de Windows en el menú "Enviar a" para poder fácilmente ver cualquier archivo en el editor de textos. Cómo se hace ------------ Hay dos etapas para lograr nuestro propósito: 1. Asegurar que nuestro programa puede recibir archivos desde el menú "Enviar a". 2. Crear una entrada para nuestro programa en el menú "Enviar a". Aunque puede crear un manejador especial para el menú "Enviar a", tomaremos la opción simple de almacenar un atajo a nuestro programa en el menú. Recibiendo archivos desde el menú "Send To" ------------------------------------------- Esto es muy fácil. Si el usuario selecciona uno o más archivos y hace clic derecho y en el emergente selecciona Enviar a | Nuestro programa, Windows simplemente iniciará nuestro programa y le pasará los nombres de los archivos seleccionados en la línea de órdenes. Así que para leer los archivos enviados desde el menú "Enviar a", simplemente necesitamos chequear nuestros parámetros de línea de órdenes. Podemos hacer esto en el manejador del evento FormCreate de nuestra aplicación, como sigue: procedure TForm1.FormCreate(Sender: TObject); var I: Integer; begin for I := 1 to ParamCount do ProcessFile(ParamStr(I)); end; Se asume que ProcessFile procesa un archivo en la forma definida por la aplicación (en el demo que acompaña este artículo simplemente mostramos el nombre del archivo en un control memo). Eso es todo en lo que respecta a manejar los archivos. Ahora demos un vistazo a cómo crear una entrada en el menú "Enviar a". Creando el elemento de menú en el menú "Enviar a" ------------------------------------------------- Windows almacena los contenidos del menú "Enviar a" en una carpeta especial. Debemos crear un acceso directo a nuestro a nuestro programa en esa carpeta. Primero debemos encontrar la ubicación de la carpeta "Enviar a". Cada usuario tiene su propia copia de esta carpeta. Encontramos la ubicación llamando a las APIs SHGetSpecialFolderLocation y SHGetPathFromIDList (definidas en la unidad ShlObj) como sigue: function GetSendToFolder: string; var pidl: PItemIDList; PPath: array[0..MAX_PATH] of AnsiChar; begin Result := ''; if SHGetSpecialFolderLocation(0, CSIDL_SENDTO, pidl) = NOERROR then begin try if SHGetPathFromIDList(pidl, PPath) then Result := PPath; finally CoTaskMemFree(pidl); end; end; end; Primero usamos SHGetSpecialFolderLocation para obtener un PIDL representando la carpeta requerida. Pasamos CSIDL_SENDTO a la función para obtener el PIDL para la carpeta "Enviar a" del usuario actual. Si tenemos éxito en obtener el PIDL luego podemos obtener el camino de la carpeta pasando el PIDL a SHGetPathFromIDList, la que almacena el camino solicitado en un buffer apuntado por un PChar que proveemos. Convertimos el PChar a string y eso es lo que devolvemos desde la función. Windows asigna memoria para el PIDL usando su asignador de tareas. Es nuestra responsabilidad liberar el PIDL usando la función CoTaskMemFree (definida en la unidad ActiveX). Habiendo encontrado el camino a la carpeta "Enviar a" del usuario, ahora podemos crear un acceso directo a nuestra aplicación en dicha carpeta. Podemos elegir hacerlo en un programa de instalación o haciendo que sea una opción de nuestra aplicación. Cualquiera sea nuestra elección, la siguiente sección muestra cómo crear el acceso directo. Creando un acceso directo ------------------------- La siguiente función muestra cómo podemos crear un acceso directo -- no sólo para usarlo en la carpeta "Enviar a". function CreateShellLink(const LinkFileName, AssocFileName, Desc, WorkDir, Args, IconFileName: string; const IconIdx: Integer): Boolean; var SL: IShellLink; // objeto shell link PF: IPersistFile; // interfaz persistente de archivo al shell link begin // Se presume fallo Result := False; // Asegurar que COM esté inicializado CoInitialize(nil); try // Crear el objeto shell link if Succeeded( CoCreateInstance( CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL ) ) then begin // Almacenar las propiedades requeridas del shell link SL.SetPath(PChar(AssocFileName)); SL.SetDescription(PChar(Desc)); SL.SetWorkingDirectory(PChar(WorkDir)); SL.SetArguments(PChar(Args)); if (IconFileName <> '') and (IconIdx >= 0) then SL.SetIconLocation(PChar(IconFileName), IconIdx); // Crear la interfaz persistente de archivo al shell link y // almacenar el archivo de enlace PF := SL as IPersistFile; Result := Succeeded( PF.Save(PWideChar(WideString(LinkFileName)), True) ); end; finally // Finalizar COM CoUninitialize; end; end; La función tiene numerosos parámetros. Ellos son: 1. LinkFileName: Camino completo del archivo de acceso directo -- en nuestro ejemplo usamos el camino de la carpeta "Enviar a" devuelto por GetSendToFolder, seguido por el nombre del archivo de acceso directo. Note que el menú "Enviar a" muestra el nombre de este archivo sin su extensión, así que asígnele un nombre descriptivo. 2. AssocFileName: El nombre del archivo referenciado por el acceso directo -- aquí proveemos el camino completo del programa a ser iniciado desde el menú "Enviar a". ParamStr(0) almacena este nombre de archivo. 3. Desc: una descripción del acceso directo -- no se muestra en el menú "Enviar a" así que le pasamos la cadena vacía (''). 4. WorkDir: El directorio de trabajo del programa -- podemos proveer una cadena vacía ('') si no se requiere. 5. Args: cualquier argumento de línea de órdenes que deba ser pasado al programa -- no usamos este parámetro en este ejemplo. Recuerde que el menú "Enviar a" también pasa los nombres de archivo en la línea de órdenes. 6. IconFileName: especifique el archivo conteniendo el icono del acceso directo -- en nuestro ejemplo no especificamos este archivo, así que se asume que el icono está en el archivo de programa. 7. IconIdx: el índice del icono en el archivo indicado por IconFileName, o -1 para que se use el icono predeterminado de ese archivo -- especificamos -1. De lo anterior podemos ver que podemos llamar a CreateShellLink como sigue: ... CreateShellLink( GetSendToFolder + '\' + 'Mi elemento "Enviar a".lnk', ParamStr(0), 'Mi programa de ejemplo "Enviar a"', ExtractFileDir(ParamStr(0)), '', '', -1 ); ... Resumen ------- Hemos cubierto las bases de cómo agregar un elemento al menú "Enviar a" y cómo manejar los archivos "enviados" a nuestro programa desde el menú. El código presentado se puede usar como una para implementar soporte para el menú "Enviar a" en sus programas. Se incluye una aplicación demo en el archivo comprimido con el código fuente que acompaña a edición del boletín. La misma ha sido probada con Delphi 4 y Delphi 7. __________________ Peter Johnson es un programador hobbyista que vive en West Wales (Reino Unido) y que "chapotea" en Delphi. Mantiene el sitio web DelphiDabbler (http://www.delphidabbler.com/) donde publica sus artículos y sus aplicaciones y componentes Delphi gratuitos. Una versión completa de este artículo se encuentra disponible en: http://www.delphidabbler.com/download.php?file=article-12-demo.zip ________________________________________________________________________ JfControls Lib. Multilenguaje. Multiapariencia. Skins. Privilegios. Más de 40 componentes integrados y personalizables. Múltiples problemas de programación resueltos. Administración centralizada de recursos. Para Delphi 3-7 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm ________________________________________________________________________ 3. Principios introductorios de búsqueda indexada Por Jim McKeeth <jim at mckeeth dot org> Introducción ------------ Hay realmente dos grandes formas de buscar en una gran colección de documentos de texto. El método simple sería cargar cada documento y recorrerlo en búsqueda de los términos buscados, al cual nos referimos como "escaneo de texto completo" (full text scan). El segundo y más rápido método es crear un índice y buscar en el índice. Un índice es una lista de términos encontrados en un documento o conjunto de documentos. Cada palabra sólo aparece una vez por documento, de modo que es más corto que el documento original. Creando un índice ----------------- Encontrando las palabras ------------------------ Para crear un índice debe primero analizar sintácticamente el documento. El análisis sintáctico ("parsing") es el proceso de separar los símbolos o elementos individuales ("tokens") en una porción de texto. Un analizador sintáctico ("parser") es un tipo de máquina de estados. Hay muchas rutinas existentes de parser disponibles. El libro "The Tomes of Delphi: Algorithms and Data Structures" escrito por Julian Bucknall contiene muchos buenos parsers. Un ejemplo puede encontrarse en http://www.delphi3000.com/articles/article_1265.asp Un parser simple puede recorrer una cadena de texto, comenzando por el principio, buscando el primer caracter. Si es una letra o número, entonces es para de una palabra, si es un espacio en blanco o un signo de puntuación, entonces es un separador. Cada palabra se agrega a la lista (por ejemplo un TStringList) en el orden en que se encontró en el documento. Típicamente las palabras se convierten todas a mayúsculas o todas a minúsculas. Al realizar el parsing y crear el índice es muy importante considerar qué es lo que se está indexando y cómo se usará el índice. Por ejemplo al "parsear" archivos HTML sería deseable excluir la mayoría de los tags (con la obvia excepción los META tags, los que son manejados de manera especial). Otras veces puede desear sólo indexar información de resumen del documento. Indexando las palabras ---------------------- Ahora que hemos parseado la lista de tokens, necesitamos indexarla. El índice más simple es una lista con cada palabra encontrada en el documento y una referencia al documento. Esta referencia puede ser una URL, un nombre de documento o cualquier otro identificador único (un GUID una clave foránea a otra tabla describiendo el documento). Un índice más complejo puede incluir la cantidad de veces que la palabra se encontró en el documento o un ranking según la posición en la que se encuentra en el documento (en el título, sección de palabras clave, primer párrafo, medio, último, etc.). Esta información adicional almacenada con cada palabra es parte de lo que diferencia el rendimiento (eficacia y eficiencia) de un motor de búsqueda respecto de otro. Muchas veces ciertas palabras se dejan afuera. Estas palabras se denominan "stop words" (palabras de detención). Se trata de palabras comunes, palabras que no serán buscadas, o palabras que no mejorarán el significado de una búsqueda. Ejemplos de estas palabras incluyen "el", "uno", "una", "y", "si", "pero", palabras con números en ellas o cualquier cosa que desee filtrar. Seleccionar las palabras a dejar afuera es otro punto que hace diferencia en el rendimiento. Algunos motores de búsqueda solían dejar fuera palabras como "HTML" o "WEB" porque eran palabras muy comunes, mientras que otros incluían todas las palabras. Otros motores de búsqueda comenzaron con una lista de diccionario y sólo indexaban palabras en esa lista. Esto lleva a problemas al indexar nombres, términos técnicos o cualquier otra cosa que no se encuentre en el diccionario original. En una oportunidad estaba creando un motor de búsqueda para una colección de artículos de un grupo de noticias. Descubrí que en los artículos había binarios codificados como UUEncode (similar a MIME o Base64). Esto resultaba en mi parser encontrando palabras que tenían cientos de caracteres de largo y en un galimatías total. Decidí omitir cualquier palabra de más de 50 caracteres o de menos de 4. Hacer la elección de sobre qué incluir y qué omitir es una decisión importante, y variará en base al contenido que esté indexando. He aquí un ejemplo de estructura de tabla para su índice: Tabla: WordList --------------- Document: Number (clave foránea para la tabla Documents) Word : String[20] (si nuestra palabra más larga es de 20 caracteres) Count : Number (cuántas veces se encuentra la palabra) La clave primaria sería compuesta por Document y Word dado que cada palabra se lista una vez por documento. Tabla: Documents ---------------- Document : Number (clave primaria) Title : string (título del documento) Location : string (URL o camino y nombre completo) Opcionalmente podría incluir el documento entero como un Blob en esta tabla. También podría tener otras tablas que listen términos (de la sección Meta del documento) o incluir autores. Nuevamente, esta elección de diseño depende del tipo de documentos que esté indexando y del propósito de su motor de búsqueda. Buscando en su índice --------------------- Una vez que están todos los índices almacenados en su base de datos, debería poder buscar en el índice por un documento. Una sentencia SQL simple para buscar un documento que contiene una palabra se vería así: SELECT * FROM WordList WHERE Word = :v_search_term ORDER BY Count DESC Esto devuelve todos los documentos conteniendo el término buscado y los ordena por la cantidad de veces que se encuentra la palabra. Si desea usar SQL, entonces buscar por múltiples palabras involucra un JOIN por cada término. En vez de eso, podría obtener una lista por cada término y luego combinarlas manualmente. Aquí es donde soportaría las palabras clave AND, OR o NOT. Si desea permitir búsquedas de frases, entonces puede buscar por cada palabra en la frase y luego buscar la frase en aquellos documentos en los que se encuentren todas las palabras de la frase. La misma técnica sería aplicable a la palabra clave NEAR. Hay otras técnicas avanzadas para hacer esto mucho más rápido, pero van más allá del alcance de este documento. Una vez que se encuentran los documentos y se los rankea, muestre los títulos de cada documento, posiblemente un sumario o el contexto de la palabras encontradas, y provea una forma al usuario de alcanzar ese documento. Variaciones ----------- Una de las cosas que Google hace un poco diferentemente es que se fija en cuántas páginas están enlazadas. Esto funciona muy bien con la naturaleza hiperenlazada de la web. Por ejemplo si busca por Borland, la mayoría de las páginas que mencionan Borland tienen un enlace a www.borland.com. Esto se asume como indicio de que www.borland.com es un sitio muy importante acerca de Borland. Google también limita el número de documentos encontrados que obtiene en cada dominio. Muchos motores de búsqueda también rankean alto las páginas si la palabra buscada aparece en la URL o el título de la página. Para el rankeo también se fijan en las meta tags para descripción y palabras claves. Algunos motores de búsqueda en realidad ignorarán una palabra si aparece demasiado frecuentemente en la página. Esto guadaña los sitios que intenta inflar artificialmente sus rankings. Otra técnica que puede usarse es Phonetics o Soundex. Esto podría hacerse con una tabla adicional similar a la tabla WordList, pero almacenando el valor Soundex para las palabras en vez de las palabras mismas. Herramientas de búsqueda de terceros ------------------------------------ dtSearch http://www.dtsearch.com/ -------- dtSearch provee un rango completo de productos de búsqueda. Estos productos apuntan a todos: desde el usuario final hasta el editor de contenidos y finalmente el desarrollador. Su Motor de Recuperación de Texto dtSearch es el núcleo de todos sus productos y provee una API con ejemplos en Delphi. Este producto es para crear un índice de texto completo ("full text index") y buscar en él. Usan su propio formato de datos. Usando su API un desarrollador puede crear una aplicación Delphi que indexe casi cualquier documento (PDF, Office, ZIP, etc., ¡y texto también!) y luego buscar en ese índice para encontrar documentos concordantes. Recientemente añadieron soporte para Linux y .NET, pero todavía no lo he probado con Linux o Delphi para .NET. Dependiendo del tipo de proyecto en el que trabaje, una de sus líneas de productos puede ser apropiada. Su dtSearch Publish, por ejemplo, le permite crear CDs / DVDs de contenido buscable rápida y fácilmente, mientras que su dtSearch Web es ideal para construir un motor de búsqueda web. Rubicon http://www.fulltextsearch.com/ ------- Tamarack Associates provee su producto de avanzada Rubicon para los desarrolladores Delphi y C++Builder que desean búsqueda indexada sin construir un sistema desde cero. Más allá de las bases que cubriremos aquí, también ofrecen muchas características avanzadas y mejoras en la velocidad. Si visita su sitio web puede bajar una versión demo de sus herramientas de búsqueda o probar su búsqueda en grupos de noticias en los grupos de noticias de Borland y Microsoft. Rubicon no sólo permite la búsqueda en documentos (viene con un parser para manejar texto, HTML y RTF), sino que también le permite buscar datos en su base de datos. Soporta expresiones lógicas (and, or, not, near y like) así como búsqueda por frases completas. Está escrito enteramente en puro Delphi, y realmente ofrece al desarrollador un nivel muy alto de control sobre el proceso. La tecnología FastPhrase de Rubicon construye una tabla más grande que le permite realizar búsquedas de frases sin realizar un escaneo de texto completo al documento destino. Esto se hace almacenando no sólo la palabra, sino también una concatenación de cada palabra y sus dos palabras adyacentes, para un total de hasta tres entradas por palabra. Rubicon ofrece una muy abarcativa compatibilidad con bases de datos. Las bases de datos soportadas incluyen la BDE y dbExpress así como orígenes ADO, Advantage, Apollo, Direct Oracle Access, DBISAM, FlashFiler, Halcyon, Interbase Express, Interbase Objects, ODBC Express y Topaz. Otras bases de datos son soportadas a través de la construcción de sus propios paquetes. Al instalar Rubicon (ya sea la versión demo o la versión completa) asegúrese de seguir las instrucciones para instalarlo correctamente de modo que soporte su base de datos seleccionada. Resumen ------- Basado en mis comparaciones entre dtSearch y Rubicon, ambos se desempeñan casi igual en el departamento de velocidad de búsqueda. La ventaja de dtSearch es sus líneas de productos adicionales y su interfaz más simple, pero no es tan configurable. Rubicon le brinda acceso a cada detalle de su proyecto de búsqueda, proveyéndole con el mismo código fuente completo en Delphi y su elección de base de datos en vez de la base de datos cerrada y la DLL de dtSearch. Características de búsqueda de bases de datos --------------------------------------------- Muchas bases de datos proveen características para permitirle indexar y buscar documentos guardados en su base de datos. Oracle ofrece un add-in adicional para indexar documentos. MySQL de modo predeterminado provee la capacidad de indexar documentos de textos almacenados como lo haría con cualquier otro campo. DBISAM (un reemplazo nativo de la BDE de Delphi sin librerías externas) ahora también provee indexado y búsqueda. Conclusión ---------- Buscar en un índice corto y bien organizado es más rápido que buscar en documentos completos. Crear y buscar en un índice toma más esfuerzo y planificación al principio, pero rápidamente brinda sus frutos si el texto se busca bastante seguido. Típicamente mientras más grande y complejo es el índice, más efectiva es la búsqueda. Si su índice se hace demasiado grande o demasiado complejo, entonces la velocidad de búsqueda se degradará. Hay herramientas de búsqueda listas para usar disponibles tanto para los usuarios finales como para los desarrolladores. dtSearch and Rubicon son extremadamente rápidas y útiles, pero que eso no lo detenga de diseñar su propia herramienta, sobre todo si tiene una necesidad especializada. Véase: http://www.dtsearch.com/dtsoftware.html#Art_of_The_Text_Query ________________________________________________________________________ InstallAWARE 3.0 para Windows Installer por MimarSinan International Oferta especial: 30% de descuento en la Enterprise Edition, sólo $559.95 InstallAWARE es la siguiente generación en herramientas de autoría de instaladores con características únicas como distribución web parcial, avisadores de progreso Flash y HTML, diez temas de instalación llamativos, diálogos de instalación completamente configurables, y un lenguaje de instalación que automáticamente se convierte en archivo de Windows Installer. >>> http://www.installaware.com/landingea.html <<< ________________________________________________________________________ 4. Llenando un TStringList extrayendo los registros de una columna Por Stewart Moss <stewart at new-heights.co.za> http://www.new-heights.co.za/ Introducción ------------ A veces un programador necesita un método rápido y sucio de extraer un conjunto de registros sobre una columna o campo específico de un dataset en una forma conveniente. Ejemplo de esto en mis programas es cuando necesité llenar un TListBox o TComboBox (en un formulario modal) con valores que el usuario pueda seleccionar para reportes u otros propósitos. Esta clase simple es una forma segura y conveniente de hacer esto. Se restaura el registro actual en el dataset, y el estado activo del dataset (es decir, abierto o cerrado). También se incluye una aplicación demo en el ZIP con el código fuente de esta edición. Implementación -------------- El código simplemente obtiene un objeto TField de un nombre de campo especificado (propiedad llamada "FieldName") perteneciente a un dataset (propiedad llamada "Dataset") e itera a través de los registros devolviendo cada valor en el campo, de inicio a fin. La clase TField es conveniente porque nos permite manejar cualquier tipo de campo basado en cualquier dataset :) Sólo se devuelven los tipos de datos que soporten el método .AsString (por ejemplo no los Blobs). Una propiedad booleana de la clase (llamada "emptyNulls") permite devolver líneas en blanco si se encuentran. Esto es útil si necesita devolver el "desplazamiento" en el dataset del registro requerido (es decir el correspondiente DataSet.RecNo) o si las filas en blanco son significativas. La salida es una propiedad de sólo lectura llamada Strings de tipo TStringList. Esta propiedad puede usarse directamente para llenar un TListBox o incluso Strings.SaveToFile(). La salida se basa en las variables de formato del sistema (para fechas, etc.), así que tome sus recaudos. Cuando el método Refresh se dispara, la propiedad Strings se lee y la lista debe ser refrescada. Esto sucede cuando cambia el dataset o el nombre de campo la primera vez, pero también puede hacerlo manualmente. La salida puede ser rellenada con cadenas de inicio y fin. Esto es útil si necesita llenar el texto para formateo. Sin embargo estos rellenos deben ser removidos del resultado del TListBox o TComboBox (por ejemplo en consultas de búsqueda, etc.). Honestamente no uso esta característica de rellenado en mis programas. La clase tienen un método llamado "quickSearch" que le permite realizar una búsqueda tipo lookup con cualquier valor de retorno. Esto es simplemente un envoltorio del TDataset.Locate() del dataset actual. Por ejemplo puede presentar todos los NombreDelCliente en una lista desplegable y quickSearch() le permitirá localizar el IdDelCliente de su NombreDelCliente seleccionado. Ejemplo de uso -------------- Esto llena el TListBox llamado SrcList en el formulario TfrmSelectData con los nombres del stock activo obtenidos de la consulta qryPortfolio. Luego realiza una búsqueda lookup para determinar el StockID del nombre de stock. procedure TFormMain.thingy; var StockID, StockName : string; DatasetExtract : TDatasetExtract; begin DatasetExtract := TDatasetExtract.Create; try // cualquier campo DatasetExtract.FieldName := 'StockName'; // cualquier dataset DatasetExtract.DataSet := qryPortFolio; // crear el formulario with TfrmSelectData.Create(Self) do begin // añadir una copia de de la TStringlist DatabaseExtract al // TListBox. // Obtener las cadenas podría generar una excepción. SrcList.Items.AddStrings(DatasetExtract.Strings); // mostrar el formulario ShowModal; // si el usuario presionó OK if ModalResult = mrOK then begin // Devolver el nombre del elemento seleccionado de la lista StockName := SrcList.Items[SrcList.selectedindex]; // Buscar el StockID en la consulta qryPortfolio usando la clase StockID := DatasetExtract.Search('StockName', StockName, 'StockID',[]); showmessage('El StockID de '+StockName+' es '+StockID); end; free; end; // with finally DatasetExtract.free; end; end; Class Code ---------- {----------------------------------------------------------------------- Unit Name: unitDatasetExtract2 Modification Date: 18 December 2004 Creation Date: 04 June 02 00:39:21 Documentation Date: 04 June 02 00:39:21 Release Date: 15 Jan 2003 Version: 2.0 Author: Stewart Moss Compiler version: Delphi 5 and Delphi 6 tested Purpose: To Extract a specific field from a dataset in a TStringList. Useful for populating TListBoxes that you dont want to be data aware... (Released originally on Delphi3000.com) Description: At the moment it only support TStringLists. It will convert most TField.FieldType into a string Notes: Dependancies: History: 15 Jan 2003: Posted at wwww.delphi3000.com. Article number 3512. 1122 visits by Dec 2004 Copyright 2002, 2003, 2004 by Stewart Moss All rights reserved. You must not modify this Unit Header. -----------------------------------------------------------------------} unit unitDatasetExtract2; interface uses Classes, db{$IFDEF VER140}, Variants{$ENDIF}; type TDatasetExtract = class private fEmptyNulls: boolean; recPos: integer; fFieldname, fappend, fprepend: string; fDataset: TDataset; fStrings: TStringList; refreshed: boolean; function FieldToString(Field: TField): string; function Get_Strings: TStringList; procedure Set_Dataset(const Value: TDataset); procedure Set_Fieldname(const Value: string); public constructor create; destructor destroy; override; procedure Refresh; function Search(searchField, searchValue, ReturnField: string; Locateoptions: TLocateOptions): string; published // You have the option of appending and prepending any information // to the begining of each record. // Useful for creating delimited records easily (ie you can just add // the StringList items together) (maybe not really that useful :P ) property append: string read fappend write fappend; property prepend: string read fprepend write fprepend; // Whether or not nulls must be translated into blank values, // or ignored property EmptyNulls: boolean read fEmptyNulls write fEmptyNulls default true; // The field name to return in the string list property FieldName: string read fFieldname write Set_Fieldname; // The dataset of the field property Dataset: TDataset read fDataset write Set_Dataset; // This is the TStringList output of the class. Reading this string // triggers the action of the class. property Strings: TStringList read Get_Strings; end; implementation uses Sysutils; // allow exception objects { TDatasetExtract } constructor TDatasetExtract.create; begin fDataset := nil; fStrings := TStringList.create; EmptyNulls := true; // allow null rows by default refreshed := false; // we do not have data end; destructor TDatasetExtract.destroy; begin fStrings.free; inherited; end; procedure TDatasetExtract.Refresh; {----------------------------------------------------------------------- Procedure: TDatasetExtract.Refresh Starts at the beginning of the record set and appends the required field in each consecutive record to the string list using the TField. ----------------------------------------------------------------------} var Field : TField; isactive : boolean; begin with fDataset do begin try // turn off any data-aware components related to current dataset disablecontrols; // save Dataset open state isactive := fDataset.Active; if not isactive then fDataset.open; // Save our current place in the dataset recPos := RecNo; // go to the start First; while not eof do begin // Get the TField object for field FieldName at // the current position (we don't care what type) Field := FieldByName(fFieldname); // Ok is it null? if not varisnull(Field.asvariant) then // use our "safer" .AsString fStrings.add(fprepend + FieldToString(Field) + fappend) else if EmptyNulls then // we are allowed to insert nulls fStrings.add(fprepend + fappend); next; end; // while not eof finally // Restore our current place in the dataset RecNo := recPos; // if the dataset was closed then close it if not isactive then fDataset.close; // turn on the data-aware components related to current dataset enablecontrols; end; // finally end; // with fDataset end; function TDatasetExtract.FieldToString(Field: TField): string; {----------------------------------------------------------------------- Procedure: TDatasetExtract.FieldToString Arguments: Field: TField Result: string This actually reads the field from the database and swallows any EDatabaseErrors. ----------------------------------------------------------------------} begin try result := Field.AsString; except on e: EDatabaseError do begin // nothing end else // re-raise the exception if it is something else raise; end; end; function TDatasetExtract.Get_Strings: TStringList; begin result := fStrings; // always return what you have (even if exception) if refreshed then // if we have clean data exit; // then we are done fStrings.clear; if (fDataset = nil) or (fFieldname = '') then // uber cool error message raise exception.create(self.ClassName + ': No se proveyeron dos campos obligatorios'); Refresh; end; function TDatasetExtract.Search(searchField, searchValue, ReturnField: string; Locateoptions: TLocateOptions): string; {----------------------------------------------------------------------- Procedure: TDatasetExtract.quickSearch Arguments: searchField, searchValue, ReturnField : string; Locateoptions: TLocateOptions Result: string Searches for a field value in a specified field name and returns the specified field returns '' is nothing is found. eg Ask for a customer id of 10 and return the customer name ----------------------------------------------------------------------} var isactive : boolean; begin with fDataset do begin // turn off any data-aware components related to the current dataset disablecontrols; // save Dataset open state isactive := fDataset.Active; if not isactive then fDataset.open; try result := ''; First; if not locate(searchField, searchValue, Locateoptions) then exit; // use our "safer" .AsString method result := FieldToString(FieldByName(ReturnField)); finally // our current place obeys TDataset.Locate() // if the dataset was closed then close it if not isactive then fDataset.close; // turn on any data-aware components related to the current dataset enablecontrols; end; end; end; procedure TDatasetExtract.Set_Dataset(const Value: TDataset); begin fDataset := Value; refreshed := false; // we are dirty again end; procedure TDatasetExtract.Set_Fieldname(const Value: string); begin fFieldname := Value; refreshed := false; // we are dirty again end; end. ________________________________________________________________________ Ayúdanos a conseguir más suscriptores votando por el Boletín Pascal (Pascal Newsletter) en estos rankings: http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium ________________________________________________________________________ 5. Devolviendo clases desde una DLL Por Max Kleiner <max@kleiner.com> Kleiner Kommunikation Reference: http://max.kleiner.com/ Descarga del componente: http://max.kleiner.com/download/dllplus.zip Planteo ------- Exportar una referencia a un objeto desde una DLL es una aproximación hacia obtener verdadero acceso OO a una DLL. La DLL debe crear y devolver el objeto, de modo que el cliente obtiene los métodos sin encapsulamiento. Veamos cómo funciona este "framework" llamado DLL+... Solución -------- También hay un ejemplo subido con Diagramas UML (*.tif) de ModelMaker. Siempre trabajamos con ModelMaker desde que tuvimos que rediseñar un gran proyecto. Primero, debemos construir una clase abstracta en una unidad separada (ver abajo la misma con una interfaz real). Puede considerar esta unidad como una interfaz: unit income1; interface type IIncome = class public function GetIncome(const aNetto: Currency): Currency; virtual; abstract; procedure SetRate(const aPercent, aYear: integer); virtual; abstract; function queryDLLInterface(var queryList: TStringList): TStringList; virtual; abstract; end; Después construimos la DLL en una nueva unidad (*.dpr) con la clase correspondiente, la que debe implementar los métodos de la interfaz: type TIncomeReal = class(IIncome) private FRate: Real; public constructor Create; function GetIncome(const aNetto: Currency): Currency; override; procedure SetRate(const aPercent, aYear: integer); override; ... Y ahora viene la exportación. Puesto que los objetos en DLL+ se crean llamando la función global Constructor, puede ver que devolver objetos desde la función que los crea es aceptable por el cliente: {-------------------------------------------------------------} function CreateIncome: TIncomeReal; stdcall; begin result:= TIncomeReal.Create; end; exports CreateIncome resident; begin {fake} end. {-------------------------------------------------------------} Finalmente demos un vistazo al cliente. En el manejo de objetos desde el cliente debemos considerar quién es el propietario del objeto y es responsable de liberarlo: Uses income1; private IncomeRef: IIncome; //member ... function CreateIncome:IIncome; stdcall; external('income.dll'); ... procedure TfrmIncome.FormCreate(Sender: TObject); begin IncomeRef := CreateIncome; end; De este modo el acceso es fácil, estable y mejora la mantenibilidad de la DLL. Debería ser obligatorio implementar una función queryDLLInterface para reproducir la interfaz y todos los parámetros en caso de pérdida (ver ejemplo). procedure TfrmIncome.BitBtnOKClick(Sender: TObject); begin incomeRef.SetRate(strToInt(edtZins.text), strToInt(edtJahre.text)); cIncome:= incomeRef.GetIncome(StrToFloat(edtBetrag.Text)); edtBetrag.text:= Format('%m',[cIncome]); end; Llamando una interfaz --------------------- Ahora el cliente llama a una InterfaceReference: private incomeIntRef: IIncomeInt; procedure TfrmIncome.BitBtnOKClick(Sender: TObject); begin incomeIntRef:=createIncome; try with incomeIntRef do begin if QueryInterface(IIncomeInt, incomeIntRef) = S_OK then begin SetRate(strToInt(edtZins.text), strToInt(edtJahre.text)); cIncome:=strTofloat(edtBetrag.text); La unidad Income1 se agranda con la interfaz: IIncomeInt = interface (IUnknown) ['{DBB42A04-E60F-41EC-870A-314D68B6913C}'] function GetIncome(const aNetto: Currency): Currency; stdcall; function GetRate: Real; function queryDLLInterface(var queryList: TStringList): TStringList; stdcall; procedure SetRate(const aPercent, aYear: integer); stdcall; property Rate: Real read GetRate; end; La DLL ahora exporta un auténtico puntero a interfaz: TIncomeRealIntf = class (TInterfacedObject, IIncomeInt) private FRate: Real; function Power(X: Real; Y: Integer): Real; protected function GetRate: Real; public constructor Create; destructor destroy; override; function GetIncome(const aNetto: Currency): Currency; stdcall; function queryDLLInterface(var queryList: TStringList): TStringList; stdcall; procedure SetRate(const aPercent, aYear: integer); stdcall; property Rate: Real read GetRate; end; function CreateIncome: IIncomeInt; stdcall; begin result:= TIncomeRealIntf.Create; end; Cuando n clases implementan una interfaz pasan un parámetro a la rutina exportada en la DLL: function CreateIncome(intfID: byte): IIncomeInt; stdcall; begin case intfID of 1: result:= TIncomeRealIntf.Create; 2: result:= TIncomeRealSuper.Create; 3: result:= TIncomeRealSuper2.Create; end; end; exports CreateIncome; La llamada del cliente se ve así: incomeIntRef := createIncome(3); ________________________________________________________________________ KnowedgeBASE Vortex 2.9 por Delphinium Software ($49.35 US) KnowledgeBASE Vortex presenta un árbol de información altamente buscable y expandible, que puede verse como esquema o auditado dentro del procesador de textos incorporado en la aplicación. Incluye una base de datos para referencias almacenadas. http://www.download.com/KnowledgeBase-Vortex/3000-2064-10342084.html ________________________________________________________________________ 6. Detección de colisión simplificada en programación de juegos Por John Pears <j.pears@coventry.ac.uk> Los así llamados "algoritmos simples de detección de colisión" sólo detectan colisión entre dos rectángulos, y aún el más simple parece ser bastante complicado. Cada sprite tiene coordenadas x e y (habitualmente el centro del sprite) con un rectándulo usado para colocar la imagen. A veces se usa un "rectángulo de confinamiento" (bounding rectangle) para detección de colisiones. Cada vez que se mueve la posición x,y del sprite, las posiciones de el o los rectángulos deben ser recalculadas. La detección de colisión luego comprueba los lados izquierdo, derecho, superior e inferior de los rectángulos de AMBOS sprites para determinar si hubo colisión. Todo esto se hace por cada sprite en cada paso del juego. ¿Qué tal mover solamente el x,y (centro) del sprite y "arreglar" los desplazamientos izquierdo y superior? Considérese la siguiente estructura de datos: type TSpriteRec = record Centre : tpoint; OffSet : tpoint; // nunca cambia a menos que cambie image.picture Image : TImage; end; var Invader : array[1..A_NUMBER] of tSpriteRec; Rocket : array[1..ANOTHER_NUMBER] of tSpriteRec; Colocar el sprite sería: Image.Left = ( Centre.x - OffSet.x ); Image.Top = ( Centre.y - OffSet.y ); No se necesita más código; todo está allí; trabajo terminado; los desplazamientos (offsets) nunca cambian. Ahora podemos escribir una simple función para detectar colisiones: Function Collided(Spr1, Spr2 : TSpriteRec) : Boolean; begin result := (abs(Spr1.Centre.x-Spr2.Centre.x) < (Spr1.OffSet.x+Spr2.OffSet.x)) and (abs(Spr1.Centre.y-Spr2.Centre.y) < (Spr1.OffSet.y+Spr2.OffSet.y)); end; Y nuestro código principal se convierte en: if Collided (Rocket[10], Invader[77]) then begin // algo de código end; La aplicación demo incluida en al archivo con el código fuente de esta edición del boletín un simple juego del tipo "Space Invaders". Está escrita en Delphi 6 y no usa DirectX o DelphiX. Es sólo puro Delphi moviendo TImages. El código no es idéntico al de los ejemplos de arriba, pero el principio sí lo es. En la demo prueba cambiando las siguientes constantes en U_Sprites.pas: INVADER_COLS = 16; INVADER_ROWS = 6; ________________________________________________________________________ Ayúdanos a conseguir más suscriptores votando por el Boletín Pascal (Pascal Newsletter) en estos rankings: http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium ________________________________________________________________________ 7. Foros / listas de correo Recordamos a los suscriptores las direcciones de nuestros foros. Para unirse a algún foro, lo más recomendable es hacerlo desde la web para así tener acceso a todas las áreas del foro y la configuración de las opciones de suscripción, pero también es posible suscribirse por email. Para suscribirse desde la web es necesario poseer un ID de Yahoo! (si no tienes el tuyo, puedes conseguirlo gratis registrándote como usuario de Yahoo!). * Delphi-abierto. Programación en Delphi (todos los niveles). Si estás en la etapa de aprendizaje o si no te agradan los foros discriminados por niveles, este foro es para ti. http://espanol.groups.yahoo.com/group/delphi-abierto Suscripción: http://espanol.groups.yahoo.com/group/delphi-abierto/join delphi-abierto-subscribe@gruposyahoo.com * Delphi-intermedio. Programación en Delphi (nivel intermedio). Si ya sabes mucho de Delphi, pero todavía te falta un largo trecho para ser un gurú (o no tanto), este foro es para ti. http://espanol.groups.yahoo.com/group/delphi-intermedio Suscripción: http://espanol.groups.yahoo.com/group/delphi-intermedio/join delphi-intermedio-subscribe@gruposyahoo.com * Delphi-avanzado. Programación en Delphi. Sólo para gurús. http://espanol.groups.yahoo.com/group/delphi-avanzado Suscripción: http://espanol.groups.yahoo.com/group/delphi-avanzado/join delphi-avanzado-subscribe@yahoogroups.com * GrupoKylix. Programación en Kylix. http://espanol.groups.yahoo.com/group/GrupoKylix Suscripción: http://espanol.groups.yahoo.com/group/GrupoKylix/join GrupoKylix-subscribe@yahoogroups.com * FreePascal-es. Programación en Free Pascal (freepascal.org). http://espanol.groups.yahoo.com/group/freepascal-es Suscripción: http://espanol.groups.yahoo.com/group/freepascal-es/join freepascal-es-subscribe@yahoogroups.com * Desarrolladores-Software. Un lugar para tratar todos aquellos temas relacionados con el desarrollo de software y su comercialización, y para compartir experiencias en el ámbito laboral, profesional o comercial con otros. http://es.groups.yahoo.com/group/desarrolladores-software Suscripción: http://es.groups.yahoo.com/group/desarrolladores-software/join desarrolladores-software-subscribe@yahoogroups.com * Componentes. Un foro para buscar/recomendar componentes de software (componentes VCL y CLX, objetos ActiveX, librerías DLL, etc.), así como utilidades, tutoriales, información, etc. http://espanol.groups.yahoo.com/group/componentes Suscripción: http://espanol.groups.yahoo.com/group/componentes/join componentes-subscribe@yahoogroups.com ________________________________________________________________________ Ayúdanos a conseguir más suscriptores votando por el Boletín Pascal (Pascal Newsletter) en estos rankings: http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium ________________________________________________________________________ 8. Delphi en la Red Por Dave Murray <irongut at vodafone dot net> Componentes, librerías y aplicaciones ===================================== Shareware / Comercial --------------------- * InstallAWARE 3.0 for Windows Installer - by MimarSinan International Develop setups for Windows Installer without any knowledge of MSI! InstallAWARE automatically converts a conditionally flowing script into a logo certifiable, ICE-compliant MSI database at build time. The IDE features a visual UI which generates your setup script for you automatically and you can fully customize the script behavior. Special limited offer: 30% off all editions, Enterprise only $559.95! http://www.installaware.com/landingea.html * KnowedgeBASE Vortex 2.9 by Delphinium Software ($49.35) KnowledgeBASE Vortex features a highly searchable and expandable information tree viewed in outline or audited within a built-in wordprocessor. Includes a database for stored references. http://www.download.com/KnowledgeBase-Vortex/3000-2064-10342084.html * YAPI Professional - by Owen Mooney ($95) Offers the easiest and yet powerful printing from Delphi. It provides: WYSIWYG setup, print preview, Non database, Database, text, Grids, tabs, bitmaps, TCanvas operation, precise positioning or free flow positioning - all using simple "writeln" statements. http://free.hostdepartment.com/o/owenmooney/ Freeware -------- * CSV Parser v1.0 - by Patrick Beekmans (with source) Parse any CSV-file with this component. You have the ability to choose the desired separator. This component has three events: OnNewColumnHeader, OnNewRow and OnNewValue. http://www.torry.net/vcl/vcltools/text/PBParsers.zip * GExperts v1.21 - by GExperts Inc. (with source) GExperts is a set of open source tools that increase productivity by adding features to the IDE. Includes: Editor Experts to find matching delimiters, insert unit headers, etc; IDE enhancements that add a Windows menu and show hidden menu items; Palette enhancements that add multi-line tabs or add tabs to the context menu; and much more. Now supports Delphi 5/6/7/8/2005 and C++Builder 6. http://www.gexperts.org/ * Indy v10.0.51 - by The Indy Pit Crew (with source) Open source suite of more than 120 protocols and Internet standards. Each protocol is robust with rich support, the need to add additional support to existing protocols is rare. Indy is easy to use because it uses blocking sockets; everything happens in a sequence, just like accessing a file. Now supports .Net. http://www.indyproject.org/Sockets.iwp * PGP Components for Delphi v4.0.1 - Michael in der Wiesche (w. source) Provides a Delphi (2-7) direct interface to PGP 6.5.x, 7.x or 8.x. New in Version 4.0.1: Checking and restarting of the PGPsdkService have been fixed, modified and enhanced; Error handling in TPGPDecode's data analysis has been slightly adjusted for special cases. http://idw-doc.homepage.t-online.de/PGPcomp.htm * ProDelphi v17.3 - by Helmuth J. H. Adolph Source code profiler for Delphi (runtime measurement). Features include: Cyclic storage of measurement results for long period measurement; Open the source in the Delphi editor by clicking a procedure in the viewer; Conditional compilation; Integrated into the Delphi IDE; Measures runtimes in DLL's; Delphi 2005 Win32 supported. http://www.prodelphi.de/ * ProDelphi.Net v3.0 - by Helmuth J. H. Adolph Source code profiler for Delphi 8 and Delphi 2005. It has the same features as ProDelphi except measuring functions written with the inline assembler (not supported for .Net platform). http://www.prodelphi.de/ * TscFontCombobox v1.1 - by Stefan Cruysberghs (with source) An advanced combobox which shows the available Windows fonts. A lot of features for preview, used fonts, show font types (truetype, printer, symbol), etc are provided. This component provides all features of the Microsoft and Corel font combobox. www.torry.net/news.php?id=26&SID=d05e863b8b4107c854fa651e2bbfdeaa * Vector Graphics ActiveX v1.6.0 - by Stas Semenov A graphics component for creating technical drawings, illustrations and presentation, training material and business reports, charts and diagrams and more. Based on Layer-Class-Shape architecture that repeatedly reduces the size of the stored data, to increase speed of loading and displaying documents, and also to provide excellent speed of execution with documents containing around 1,000,000 shapes. http://www.script-debugger.com/ * XP Graph v2.1 - by JLx Soft A Delphi Chart component equal like that one in Windows' task manager with bar and history, plus additional extensions. http://comps.jlxsoft.com/ Actualizaciones de productos Borland ------------------------------------ * Delphi 2005: The Ultimate Delphi The complete development solution for Windows. With all of the Windows languages and SDKs you need in one environment for modern Windows rapid application development (RAD), Delphi 2005 takes the power of Delphi to the next level. With Delphi, C#, Microsoft .NET Framework and Win32 support for GUI, Web, database, modeling, and ALM in one hyperproductive RAD environment, Delphi 2005 makes Windows development tasks faster, better, and easier. http://www.borland.com/delphi/ Artículos, trucos y consejos ============================ * BDNradio: Delphi 2005 Live Chat on Interop with Chris Bensen In this audio replay, Chris discusses his work on ActiveX, COM, .NET interop, VLI and the New Component wizard. http://community.borland.com/article/0,1410,32858,00.html * BDNRadio: Log from Chat with Corbin Dunn on Delphi 2005 IDE Features Read the chat room log for questions answered by Corbin on Delphi 2005 IDE features, and listen to the replay. http://community.borland.com/article/0,1410,32850,00.html * BDNRadio: Delphi 2005 IDE Chat with Allen Bauer This is a log for the live audio chat from November 24th 2004 on Delphi 2005 with Allen Bauer, a Borland Principal Engineer, and Delphi IDE architect. Allen discusses his work on Delphi 2005. http://community.borland.com/article/0,1410,32843,00.html * Delphi 2005 Fixes for QualityCentral Bug Reports There are currently 263 QualityCentral bug reports closed with the release of Delphi 2005. http://community.borland.com/article/0,1410,32837,00.html * Namespaces in Delphi 2005 To make Delphi code friendlier towards other .NET languages Borland has changed the way Delphi 2005 produces namespaces. This article discusses the changes that have been made and how they affect you. http://community.borland.com/article/0,1410,32765,00.html * Advanced Markup Language Generation for IntraWeb Describes how to use an undocumented feature in IntraWeb to create complex controls that require multiple tags. http://community.borland.com/article/0,1410,32758,00.html * BDNradio: Chat Room Log of Live Chat with Danny Thorpe on Delphi 2005 This is the chat log for the live audio chat from November 19th 2004 on Delphi 2005 with Danny Thorpe, a Borland Chief Scientist and architect of the Delphi compilers. Danny discusses changes and enhancements to the Delphi Win32 and Microsoft.NET compilers, the run time framework and .NET support in general. http://community.borland.com/article/0,1410,32789,00.html * Using XMLDoc For API Documentation And HelpInsight With Delphi 2005 How to use Borland's XMLDoc tool to quickly and easily document your software and generate HelpInsight for your components. http://community.borland.com/article/0,1410,32770,00.html * What's New in Delphi 2005 - by Bob Swart A Technical White Paper on all that's new in Delphi 2005. http://community.borland.com/article/0,1410,32778,00.html * Building a custom data provider for .Text A case study on the porting of .Text from SQL Server to InterBase using Delphi for .NET. http://community.borland.com/article/0,1410,32419,00.html * Borland Conference 2004 Blogs An impressive compilation of blog entries that were created during BorCon 2004. It's not as good as being there, but it's close. http://community.borland.com/article/0,1410,32752,00.html * How to Check if a Document in a TWebBrowser is Located on a Local (or Network) Drive - by Zarko Gajic If you need to know the location of a document displayed in a TWebBrowser component, you need to get the Protocol property of the IHTMLLocation. Here's a function that returns true if a document in a WebBrowser is stored locally. http://delphi.about.com/od/adptips2004/a/bltip1204_5.htm * Using the TDBGrid Component - by Zarko Gajic Contrary to most other Delphi data-aware controls the DBGrid component has many nice features and is more powerful than you would have thought. There are many ways to customise the output of a DBGrid... http://delphi.about.com/od/usedbvcl/a/tdbgrid.htm * Retrieving All Image Links from an HTML Document - by mrbaseball34 Here's how to obtain all image links from an HTML document using Indy. http://delphi.about.com/od/adptips2004/a/bltip1204_3.htm * Making Delphi 2005 Independent from .NET - by Alvaro Garcia Pascual Despite what Borland says, Delphi 2005 doesn't require .NET. If you are a Delphi Win32 developer and don't like that Delphi 2005 comes polluted with .NET stuff, read this article to learn how to remove .Net from Delphi 2005. http://delphi.about.com/od/delphifornet/a/delphi2005win32.htm * A First Look at Delphi 2005 - by Zarko Gajic The time has come to take a sneak peak into a new Delphi version: Delphi 2005. Delphi 2005 is the ultimate weapon for developers: Delphi, C#, Win32 and .NET in one RAD environment. http://delphi.about.com/od/productreviews/ss/delphi2005first.htm * How to write a Ping utility using ICMP.dll - by Serge Perevoznyk Raw Sockets are subject to security checks and are accessible only to members of the administrator's group. Icmp.dll provides functionality that allows developers to write Internet ping applications on Windows systems without Winsock 2 support and without security problems. http://www.delphi-central.com/tutorials/icmp-ping.aspx * How To Find an Item in a Tree Control Via its Label - Serge Perevoznyk The "tree view" control does not have a built-in method for searching the entire tree or for selecting an item given its label. This article provides code that returns the location of any item in a tree when given a specific label to search for. http://www.delphi-central.com/tutorials/FindTreeViewNode.aspx Tutoriales y capacitación ========================= * Installable Delphi 2005 Examples Download an installation for dozens of tested Delphi 2005 examples for use directly from the IDE. These examples include the C# and Delphi languages and both the Win32 and .NET platforms with text that introduces and explains them. http://community.borland.com/article/0,1410,32857,00.html * BDNtv: C++Builder in Delphi In this quick preview, Troy Kitch shows integration of C++Builder features in Delphi 2005. Flash http://bdntv.borland.com/cppbuilder/CPPinDelphi8x6.html * BDNtv: Unit testing in Delphi 2005 This BDNtv episode shows the unit testing integration for DUnit for a Delphi/Win32 application in Delphi 2005. Unit testing for C#, Delphi for .NET, and Delphi for Win32 with both NUnit and DUnit are supported in Delphi 2005. Flash http://dotnet.borland.com/bdntv/delphi/d2005unittesting8x6.html * GOF Behavioural Patterns with C#: Part 1 - by Barry Mossman This is the third article in a series upon the GOF Design patterns from a C# and .Net Framework perspective. It is covers some of the Behavioral Patterns: Chain of Responsibility, Command, Interpreter. http://community.borland.com/article/0,1410,32710,00.html * GOF Behavioural Patterns with C#: Part 2 - by Barry Mossman This is the fourth article in a series upon the GOF Design patterns from a C# and .Net Framework perspective. It is a continuation of the Behavioral Patterns this time looking at Iterator, Mediator, Observer and Memento (Momento) patterns. http://community.borland.com/article/0,1410,32795,00.html * Deriving a Model From an Existing Database with ECO II in Delphi 2005 Henrik Jondell demonstrates how easy it is to create model-powered applications for your existing databases with ECO II. Flash http://dotnet.borland.com/bdntv/delphi/eco2modelderivation.html * An Introduction to COM Programming with Delphi (1/6) - by Curtis Socha A brief historical rundown on COM's glorious past. Abstract methods vs. Interfaces. Classes and Interfaces: An interesting paradox. http://delphi.about.com/library/weekly/aa112304a.htm * An Introduction to COM Programming with Delphi (2/6) - by Curtis Socha What is an Interface? How to implement an Interface? Describing the TInterfacedObject. http://delphi.about.com/library/weekly/aa113004a.htm * An Introduction to COM Programming with Delphi (3/6) - by Curtis Socha What is the implements directive? What is the Method Resolution Clauses? Pseudo-Multiple Interface Inheritance. Interface properties and other fine tales of horror. http://delphi.about.com/library/weekly/aa120704a.htm * An Introduction to COM Programming with Delphi (4/6) - by Curtis Socha A Com Object walk-a-bout. A Class Factory tour. Our first true COM Object program. Homework Assignment. http://delphi.about.com/library/weekly/aa121404a.htm * An Introduction to COM Programming with Delphi (5/6) - by Curtis Socha Marshaling Data. Oh, the glory of leadership! Variant Reference Page. Using Variants and Variant Arrays. http://delphi.about.com/library/weekly/aa122104a.htm * Programming a Memory Game in Delphi: Part 1 - by Delphi Central In this tutorial, we will see how the TDrawGrid component can be used to help us develop a "Memory" game. Firstly we will describe what is involved with the Memory game. http://www.delphi-central.com/tutorials/memory_game.aspx * Programming a Memory Game in Delphi: Part 2 - by Delphi Central In part 1 we explained how to create the form and drawgrid at design time. Now we will move onto writing the actual code. http://www.delphi-central.com/tutorials/memory_game_2.aspx * Programming a Memory Game in Delphi: Part 3 - by Delphi Central In part 1 we explained how to create the form and drawgrid at design time, in part 2 we started writing the actual code. In the third part of the tutorial we will draw the grid that the game is played on. http://www.delphi-central.com/tutorials/memory_game_3.aspx Noticias ======== * Delphi 2005 Architect Review Delphi has grown up since it launched nearly ten years ago. The latest version provides support for developing Win32 and .NET applications as well as supporting the C# language. There are many enhancements to almost all areas with the main goal of increasing developer productivity. http://www.builderau.com.au/program/0,39024614,39170720,00.htm * Global 2000 Companies Select Borland to Elevate Software Quality An unprecedented number of high-profile customers spanning a wide spectrum of industries and regions selected CaliberRM and StarTeam in 2004 as their preferred requirements management and software configuration and change management solutions. Companies that selected CaliberRM or StarTeam this year include: British Telecom, Comcast, EDS, Gap, HP, Jaguar Cars, Siemens AG, Symantec and Verizon Wireless. http://home.businesswire.com/portal/site/google/index.jsp? ndmViewId=news_view&newsId=20041206005289 * BDNradio Interviews with Borland's R&D staff for Delphi 2005 Don't miss these live interviews with Borland R&D engineers. http://community.borland.com/article/0,1410,32786,00.html * Software Delivery Optimisation Enables Disciplined Approach At the Borland Conference 2004, Dale Fuller, President and CEO, presented their vision and product strategy for transforming software development from an unpredictable art form into a more manageable and repeatable business process. http://www.itweb.co.za/sections/business/2004/0411150801.asp * Borland's ALM Products Receive Numerous Accolades in 2004 Borland today announced 2004 as a banner year for its products, with receiving numerous industry accolades and awards from around the globe. Industry recognition of their innovative solutions provides the company with significant momentum leading into 2005 and underscores their ongoing focus on technical excellence and customer value. http://home.businesswire.com/portal/site/google/index.jsp? ndmViewId=news_view&newsId=20041110005673&newsLang=en * Borland to Provide UML Support to MS Visual Studio 2005 Team System Borland joined Microsoft and other industry leaders in announcing support and future plans for Software Factories, a new industry approach to improve software development. As part of Borland's support for Software Factories, the company plans to deliver a domain-specific modeling solution providing UML capabilities within the Microsoft Visual Studio 2005 Team System. http://www.tmcnet.com/usubmit/2004/Oct/1087428.htm * Borland Focuses on UML Modeling Borland is breaking up Together ControlCenter for UML modeling into separate products for developing, designing, and architecting applications. The move is intended to align Together with the SDO strategy of providing a disciplined approach to development. http://www.infoworld.com/article/04/10/25/HNborcontrolcenter_1.html * IBM and Borland Upgrade Developer Tools IBM unveiled new Rational developer tools and Borland rolled out the new version of its Delphi Windows development tool. Both are maneuvering to infuse their platforms with business process automation commonly used in other areas of enterprise operations. http://www.computerweekly.com/articles/article.asp?liArticleID=134236 * Native Win32 and .Net Framework Support for New Delphi Delphi, the grand-daddy of visual programming environments, has been updated. Delphi 2005 works with both Win32 and .Net frameworks, and also supports Microsoft's C# as well as the Delphi language itself. http://www.pcpro.co.uk/news/64469/ native-win32-and-net-framework-support-for-new-delphi.html Otros / Sitios misceláneos ========================== * The Daily WTF: Curious Perversions In Information Technology The Daily WTF presents scary code examples. If you are looking for a good laugh visit the site, I just hope your code is not there! :) http://thedailywtf.com/ ________________________________________________________________________ Irongut's Delphi Pages Dedicada a la programación con Borland Delphi y Kylix. Tenemos artículos sobre programación, noticias Borland y Delphi, código fuente y componen- tes para usar en sus aplicaciones y más. http://www.paranoia.clara.net/ ________________________________________________________________________ ¡Tú puedes ayudarnos! Por favor danos una mano y ayúdanos a llegar a los 20.000 suscriptores en los próximos meses. Una forma en que puedes ayudarnos es enviando este enlace a tus amigos: http://www.latiumsoftware.com/es/pascal/index.php boletin-pascal-subscribe@gruposyahoo.com Otra forma es votándonos en alguno de estos rankings para darle más visibilidad a nuestro sitio web y aumentar así el número de suscrip- ciones al boletín: http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium 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/p0052.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 la licencia y la ausencia de garantía que puedes leer en la página http://www.latiumsoftware.com/es/legal.php Allí también encontrarás una nota sobre marcas registradas. Te animamos a que redistribuyas este boletín, siempre y cuando lo hagas en forma completa (incluyendo la información de copyright), sin modificaciones y de manera gratuita. Los artículos son copyright de sus respectivos autores y se reproducen aquí con el permiso de los mismos. ________________________________________________________________________ Latium Software http://www.latiumsoftware.com/es/index.php Irongut's Delphi Pages http://www.paranoia.clara.net/ Copyright 2004 by Ernesto De Spirito + Dave Murray. All rights reserved. ________________________________________________________________________ |
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
¿Errores? ¿Omisiones? ¿Comentarios? Por favor contáctanos!






