Boletín Pascal #5
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #5 INDICE 1. UNAS PALABRAS DEL EDITOR 2. FREE PASCAL 3. DELPHI ZIP a) ¿Dónde obtenerlo? b) Instalación c) Probando la demo d) ¿Cómo funciona? 1) Creando un nuevo archivo 2) Agregando ficheros a un archivo 3) Agregando ficheros a un archivo en múltiples volúmenes 4) Borrando ficheros de un archivo 5) Extrayendo ficheros de un archivo 6) Probando un archivo 7) Interceptando los mensajes 8) Listando los ficheros guardados en un archivo ________________________________________________________________________ 1. UNAS PALABRAS DEL EDITOR Nuestro nuevo sitio web ya está funcionando... o al menos debería! ;) http://www.latiumsoftware.com/es/ Es lo mismo de antes, nada nuevo por ahora, pero este mes probablemente comenzaremos a agregar material más o menos continuamente si podemos. Los mantendremos informados. En el último número escribimos wwww en vez de www en la dirección de nuestro sitio, así que si no pudieron entrar al sitio, ahora saben por qué! ;) Ups! Gracias a Alejandro que nos indicó este error. 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. FREE PASCAL La versión 1.00 de este compilador pascal fue lanzada oficialmente en Julio pasado y se espera que de a poquito comience a ser incluido en muchas distribuciones de Linux. Está disponible como paquetes RPM, .deb y .tar.gz. Pero Free Pascal no es sólo para Linux puesto que también está disponible para DOS (requiere el GO32 extender), Windows de 32 bits, OS/2 (requiere el EMX extender) y Amiga (Versión 0.99.5). Si desea bajarlo, siga este link: http://www.freepascal.org/sdown.html Le sugerimos que elija un mirror porque el sitio principal por lo general está muy lento. ________________________________________________________________________ 3. DELPHI ZIP Es un conjunto de componentes freeware para Delphi y una aplicación de ejemplo (con código fuente completo incluido) que accede a archivos ZIP usando las DLLs ZIPDLL y UNZDLL del proyecto Info-Zip. Funcionan en todas las versiones de Delphi de 32 bits (de la 2 a la 5). a) ¿Dónde obtenerlo? ==================== Está disponible en: BCB and Delphi Freeware Zip Components http://www.geocities.com/SiliconValley/Orchard/8607/ http://members.tripod.lycos.nl/Vleghert/ Yo descargué los siguientes archivos: * Delphi Zip 1.6L beta release (360K) http://www.geocities.com/SiliconValley/Orchard/8607/beta/dz-del160.zip http://members.tripod.lycos.nl/Vleghert/beta/dz-del160.zip * TZipMaster 1.6L Archivo de ayuda (81K) http://www.geocities.com/SiliconValley/Orchard/8607/beta/zipmst16.zip http://members.tripod.lycos.nl/Vleghert/beta/zipmst16.zip El primer archivo tiene todo, excepto la ayuda del componente TZipMaster y el código fuente de las DLLs: * Código fuente de ZipDll y UnZDll para BCB 3 o BCB 4 (241K) http://www.geocities.com/SiliconValley/Orchard/8607/dz-dllsrc15.zip No lo descargué porque son para C++ Builder. Las DLLs están incluidas en el archivo principal (dz-del160.zip) y también hay versiones optimizadas disponibles, como ésta: * Pentium DLLs. Compiladas con BCB 4 optimizadas para Pentium (129K) http://www.geocities.com/SiliconValley/Orchard/8607/pendll15.zip b) Instalación ============== 1) Descomprima dz-del160.zip en un directorio temporal y ejecute el archivo dz-del160.exe para instalar. Le solicitará el directorio de instalación. Yo elegí "C:\Delphi\Zip", pero puede extraerlo donde quiera (simplemente sustituya "C:\Delphi\Zip" por su camino). 2) Copia o mueva estos ficheros a su directorio Windows\System: C:\Delphi\Zip\DLL\*.DLL y C:\Delphi\Zip\SFX\*.BIN 3) Ahora debería copiar o mover los ficheros "C:\Delphi\Zip\VCL\*.*" a un directorio en la ruta de la VCL, o incluir "C:\Delphi\Zip\VCL" en su ruta de la VCL (en Delphi 5 elija Environment Options del menú Tools y agregue este directorio a Library Path y Browsing Path). 4) Instale los componentes de la VCL. ¿Cómo? ¡Es el ABC! ¡Ya debería saberlo! :) Está bien, inicie Delphi 5. Elija Close All del menú File y luego Install Component del menú Component. Haga click en Browse para seleccionar las unidades y seleccione todos los archivos *.pas en el directorio "C:\Delphi\Zip\VCL" (o donde haya puesto esos archivos) y haga clic en Abrir y luego OK para compilar. Finalmente cierre el paquete y guárdelo cuando se le pregunte. Si tiene una versión anterior de Delphi, siga las instrucciones que se proveen en "C:\Delphi\Zip\Install.txt". 5) Instale los archivos de ayuda. ¿Cómo? ¡Es el ABC! ¡Ya debería saberlo! :) Está bien, descomprima el archivo zipmst16.zip y mueva los dos ficheros al directorio de la ayuda de Delphi (por ejemplo "C:\Archivos de programa\Borland\Delphi5\Help"). Edite delphi5.cnt y agregue estas dos líneas con las otras: :Index ZipMaster Component Help=ZipMstr.hlp :Include ZipMstr.cnt Elimine los archivos delphi5.GID, delphi5.FTS y delphi5.FTG. Esto también funciona con Delphi 3 y 4 (sólo sustituya el "5" de arriba por su número de versión). Si tiene Delphi 2 y desea integrar los archivos de ayuda, puede construir un archivo .kwf. Los fuentes están disponibles para descargar: * Fuentes del archivo de ayuda (98K) http://www.geocities.com/SiliconValley/Orchard/8607/dz-hlpsrc15.zip http://members.tripod.lycos.nl/Vleghert/ c) Probando la demo =================== Abra el proyecto "C:\Delphi\Zip\Demo1\ZipDemo1.dpr" e intente compi- larlo. Cuando lo hice, obtuve el siguiente mensaje de error: [Fatal Error] mainunit.pas(632): Internal error: C3517 Este es un error del compilador y lo estoy reportando a Borland. Ya aislé el problema y aparente ocurre cuando está activada la optimización (predeterminado) y uno convierte explícitamente una propiedad de un objeto (no una variable o constante) de tipo Int64 a Int64. Puede no ocurrir en su versión/build de Delphi, pero si lo hace, habría dos soluciones. 1) Apague las optimizaciones alrededor del procedimiento ZipMaster1Progress: {$OPTIMIZATION OFF} procedure TMainform.ZipMaster1Progress(Sender: TObject... ... end; {$OPTIMIZATION ON} 2) O (mejor aún) quite las conversiones innecesarias a Int64: // Step := Integer(Int64(TotalProgress1) * Int64(10000) // div Int64(TotalSize1)); Step := Integer(TotalProgress1 * 10000 div TotalSize1); // Step := Integer(Int64(TotalProgress2) * Int64(10000) // div Int64(TotalSize2)); Step := Integer(TotalProgress2 * 10000 div TotalSize2); Ahora ejecute el programa y haga clic en el botón "Open Zip". Seleccione un archivo ZIP y haga clic en "Open". ¿Ahora qué? Si obtiene una excepción de tipo EConvertError, no se preocupe: no es un error, es una característica! ;) Esta vez es verdad porque TSortGrid usa excepciones para determinar el tipo de datos la columna para realizar el ordena- miento. Así que haga clic en OK y deje que la aplicación siga corriendo (presione F9). Tendrá que hacerlo tres veces. Si no desea ver esos errores en el futuro, vaya a Tools / Debugger Options / Language Exceptions y desmarque la casilla de verificación "Stop on Delphi Exceptions". En versiones anteriores de Delphi creo que se llamaba "Break on Exceptions" o algo parecido, y estaba ubicada en otro lugar... d) ¿Cómo funciona? ================== Todo el trabajo lo realizan las DLLs, y el componente TZipMaster provee una linda interfaz de programación para trabajar con estas DLLs, así que no tenemos que preocuparnos por llamar a las APIs directamente, releván- donos de un montón de detalles. La aplicación demo es bastante completa y muestra toda la funcionalidad básica del componente TZipMaster. Puede hecharle una mirada al código y usar el archivo de ayuda integrado para aprender más acerca del uso de este componente. Para ayudarle a entenderlo mejor, hemos decidido construir una aplicación demo alternativa, que será muy simple, pensando en proveerle un inicio rápido en cómo agregar capacidades mínimas de manejo de Zips a su aplicación (para propósitos de copia de seguridad, por ejemplo), en vez de construir una utilidad de compresión (como WinZip o Power Archiver). Para comenzar, elegimos New Application del menú File. Luego editamos el fichero de programa y agregamos una directiva de recursos ($R) para cargar los mensajes (están disponibles en varios idiomas): program Project1; uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} {$R ZipMsgUS.RES} // Carga los mensajes en inglés begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Note que esto sólo afectará los mensajes generados por el componente, no por las DLLs (que estarán en inglés). Desafortunadamente no hay archivo de mensajes en español... Ahora agregamos un componente TZipMaster al formulario y lo llamamos Zip para darle un nombre más corto. Antes de comenzar el trabajo real cargaremos las DLLs en memoria cuando se crea el formulario, y las descargaremos cuando se cierre. No es necesario hacerlo porque TZipMaster maneja esto automáticamente, cargando y descargando las bibliotecas como sea necesario, pero esto puede significar una penalidad en el rendimiento (consume tiempo), así que decidimos hacerlo por nuestra cuenta: procedure TForm1.FormCreate(Sender: TObject); begin Zip.Load_Zip_Dll; Zip.Load_Unz_Dll; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Zip.Unload_Zip_Dll; Zip.Unload_Unz_Dll; end; Las bibliotecas ocupan memoria cuando están cargadas, así que esta no es necesariamente la mejor táctica tampoco, pero es mejor que cargarlas y descargarlas cada dos por tres. El problema ahora es que la carga del formulario toma más tiempo, así que quizás la mejor solución sea cargar las DLLs la primera vez que se usan y descargarlas cuando deje de usarlas (por ejemplo cuando se cierra el formulario), pero le dejamos esto a usted. :-) 1) Creando un nuevo archivo --------------------------- Para mostrar cómo crear un nuevo archivo Zip colocamos un botón en el formulario (lo hemos llamado CreateZip), y en su evento Click escribimos: procedure TForm1.CreateZipClick(Sender: TObject); const ZipArch: string = 'C:\Temp\Test.zip'; begin if FileExists(ZipArch) then if MessageDlg('"' + ZipArch + '" ya existe. ¿Sobreescribir?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then DeleteFile(ZipArch) else exit; Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('No se pudo crear "' + ZipArch + '"!'); exit; end; Zip.AddOptions := []; Zip.FSpecArgs.Add('Project*.*'); try Zip.Add; ShowMessage('¡Archivo Zip creado exitosamente!'); except ShowMessage('No se pudo crear "' + ZipArch + '"!'); end; end; Primero preguntamos si el archivo ya existe, y si es así solicitamos confirmación para sobreescribirlo. En caso afirmativo borramos el archivo existente para que luego, cuando agreguemos ficheros al archivo, éste se cree automáticamente. El método Add es el que realiza todo el trabajo, pero antes que podamos invocarlos debemos hacer algunos preparativos: a) Establecer el nombre del archivo Zip en la propiedad ZipFilename b) Establecer las opciones para agregar los ficheros (por ejemplo podemos explorar directorios recursivamente, encriptar los ficheros y otras cosas más). c) Establecer los ficheros que serán agregados en la propiedad FSpecArgs (un objeto TStringList). 2) Agregando ficheros a un archivo ---------------------------------- Ya hemos visto cómo agregar ficheros, pero aquí va otro ejemplo. Primero colocamos un nuevo botón en el formulario y lo nombramos AddToZip, y en su evento Click escribimos: procedure TForm1.AddToZipClick(Sender: TObject); const ZipArch: string = 'C:\Temp\Test.zip'; begin Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('¡No se pudo abrir "' + ZipArch + '"!'); exit; end; Zip.AddOptions := [AddUpdate]; Zip.FSpecArgs.Add('*.d*'); Zip.FSpecArgs.Add('Unit1.pas'); try Zip.Add; ShowMessage('Ficheros agregados!'); except ShowMessage('No se pudieron agregar los ficheros!'); end; end; Este ejemplo es similar al anterior, excepto que hemos usado la opción AddUpdate para decirle al método Add que si los ficheros que estamos agregando ya se encuentran en el archivo, no deberían ser reemplazados a menos que sean más recientes, pero los ficheros que no existen en el archivo sí serán agregados. AddFreshen es como AddUpdate, pero no agrega nuevos ficheros al archivo. El Add 'estándar' (si no se establece ninguna opción) agregará o reemplazará ficheros incondicionalmente. AddMove es como el Add standard, pero borra los ficheros del disco después que han sido agregados. 3) Agregando ficheros a un archivo en múltiples volúmenes --------------------------------------------------------- Para separar (span) un archivo en múltiples partes llamadas volúmenes, simplemente incluimos AddDiskSpan en AddOptions. Para probar el siguiente ejemplo, agregue un botón llamado Span en el formulario y genere su evento Click: procedure TForm1.SpanClick(Sender: TObject); const ZipArch: string = 'C:\Temp\SpanTest.zip'; begin Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('¡No se pudo abrir "' + ZipArch + '"!'); exit; end; Zip.AddOptions := [AddDiskSpan]; Zip.KeepFreeOnDisk1 := 10000; Zip.MaxVolumeSize := 100000; Zip.FSpecArgs.Add('*.*'); try Zip.Add; ShowMessage('Ficheros agregados!'); except ShowMessage('No se pudieron agregar los ficheros!'); end; end; Al separar el archivo en múltiples discos, establezca MaxVolumeSize a 0 y el tamaño del diskette será detectado automáticamente. Estableciendo esta propiedad a otro valor forzará que las partes del archivo (volúmenes) no sean más grandes que el valor que especifique (en bytes). Esto es útil al dividir el archivo en el disco duro. Use KeepFreeOnDisk1 para establecer el número de bytes a dejar libres en el primer volumen. En el ejemplo anterior, el tamaño del volumen es 100,000 bytes y hemos requerido 10,000 bytes libres en el primer volumen, así que el tamaño del primer volumen no excederá los 90,000 bytes. 4) Borrando ficheros de un archivo ---------------------------------- Para borrar un fichero o conjunto de ficheros del archivo podemos usar el método Delete. Para ver un ejemplo, agregue un botón llamado DeleteFromZip al formulario y genere su evento Click: procedure TForm1.DeleteFromZipClick(Sender: TObject); const ZipArch: string = 'C:\Temp\Test.zip'; begin Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('¡No se pudo abrir "' + ZipArch + '"!'); exit; end; Zip.FSpecArgs.Add('*.c*'); Zip.FSpecArgsExcl.Add('*.cfg'); try Zip.Delete; ShowMessage('Ficheros agregados!'); except ShowMessage('No se pudieron agregar los ficheros!'); end; end; En este ejemplo hemos introducido la propiedad FSpecArgsExcl, una StringList que contiene los nombres de los ficheros a excluir de la operación (en este caso Delete). En el ejemplo de arriba, todos los ficheros que concuerden con el patrón *.c* pero no *.cfg serán borrados del archivo. 5) Extrayendo ficheros de un archivo ------------------------------------- Esta operación es realizada por el método Extract. Para ver un ejemplo, agregue un botón llamado ExtractFromZip al formulario y genere su evento Click: procedure TForm1.ExtractFromZipClick(Sender: TObject); const ZipArch: string = 'C:\Temp\Test.zip'; var CurrentDir: string; begin Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('¡No se pudo abrir "' + ZipArch + '"!'); exit; end; CurrentDir := GetCurrentDir; ChDir(ExtractFilePath(ZipArch)); Zip.ExtrOptions := [ExtrOverWrite, ExtrUpdate]; try Zip.Extract; ShowMessage('Ficheros extraídos!'); except ShowMessage('No se pudieron extraer ficheros!'); end; ChDir(CurrentDir); end; La carpeta destino es el directorio de trabajo actual, así que debe- ríamos cambiarlo (usando el procedimiento ChDir) si queremos que sea otro distinto. Previamente "guardamos" el directorio actual así podemos restaurarlo más tarde. En el ejemplo usamos la carpeta donde está localizado el archivo Zip ('C:\Temp'). Puesto que no especificamos los ficheros a procesar en FSpecArgs, se extraerán todos los ficheros del archivo. Puede especificar algunas opciones de extracción en la propiedad ExtrOptions. El método de extracción predeterminado sólo extraerá ficheros si no existen en el disco. Si desea sobreescribir ficheros existentes use la opción ExtrOverWrite (equivalente al Add estándar). Puede conbinarlo con ExtrUpdate (equivaldría a AddUpdate) o con ExtrFreshen (equivaldría a AddFreshen). Puede usar la opción ExtrDirNames para recrear los caminos relativos guardados en el archivo (los caminos se guardan usando la opción AddDirNames con el método Add). 6) Probando un archivo ---------------------- Para verificar la integridad de un archivo Zip use el método Extract con la opción ExtrTest y luego compruebe el valor de la propiedad ErrCode. Para verlo funcionando, agregue un botón llamado TestZip a su formulario y genere su evento Click: procedure TForm1.TestZipClick(Sender: TObject); const ZipArch: string = 'C:\Temp\Test.zip'; begin Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('¡No se pudo abrir "' + ZipArch + '"!'); exit; end; Zip.ExtrOptions := [ExtrTest]; try Zip.Extract; if Zip.ErrCode = 0 then ShowMessage('Verificación exitosa!') else ShowMessage('Error(es) encontrado(s) en el archivo Zip'); except ShowMessage('No se pudo verificar el archivo!'); end; end; 7) Interceptando los mensajes ----------------------------- Agregue un control Memo a su formulario y genere el evento Message del componente Zip: procedure TForm1.ZipMessage(Sender: TObject; ErrCode: Integer; Message: String); begin if ErrCode = 0 then Memo1.Lines.Add(Message) else Memo1.Lines.Add('Error Nº ' + IntToStr(ErrCode) + ': ' + Message); end; El Memo ahora mostrará los mensajes enviados por la DLL. Intente las operaciones que presentamos arriba para verlos. 8) Listando los ficheros guardados en un archivo ------------------------------------------------ La propiedad ZipContents es una TList que contiene punteros a registros ZipDirEntry que contienen información detallada acerca de los ficheros almacenados en el archivo. Para ver un ejemplo, agregue un botón llamado ListFiles al formulario y genere el evento Click: procedure TForm1.ListFilesClick(Sender: TObject); const ZipArch: string = 'C:\Temp\Test.zip'; var i: integer; f: ^ZipDirEntry; begin Zip.ZipFilename := ZipArch; if Zip.ZipFilename = '' then begin ShowMessage('¡No se pudo abrir "' + ZipArch + '"!'); exit; end; for i := 0 to Zip.Count - 1 do begin f := Zip.ZipContents[i]; Memo1.Lines.Add(Format('%s %.1fK (%.0f%%)', [f.FileName, f.UncompressedSize / 1024, f.CompressedSize / f.UncompressedSize * 100])); end; end; Bueno, hasta aquí es lo más lejos que llegamos. La aplicación demo que viene con Delphi Zip es más completa y le mostrará muchas caracterís- ticas del componente TZipMaster (como encriptación y ejecutables autoextractables), y puede aprender más del archivo de ayuda. En el próximo número usaremos este componente en nuestra aplicación Buscador de Archivos para extender la búsqueda a archivos comprimidos. Nos vemos. ________________________________________________________________________ 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/p0005.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) 2000 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!






