Boletín Pascal #11
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #11 - 27-NOV-2000 INDICE 1. UNAS PALABRAS DEL EDITOR 2. ALMACENANDO Y RECUPERANDO IMAGENES JPEG EN UN CAMPO DE UNA TABLA 3. OBTENIENDO EL NUMERO DE SERIE DE UN VOLUMEN 4. ENLACES ________________________________________________________________________ 1. UNAS PALABRAS DEL EDITOR Quisiera volver a agradecer a Alirio Gavidia por contribuir el artículo "Post-it. Ventanas ajustables sin borde ni título" que publicáramos en el último boletín y que ha recibido buena crítica de parte de nuestros suscriptores, y aprovecho la oportunidad para animar una vez más a los gurús y programadores avanzados que están suscriptos a este boletín para que contribuyan artículos y trucos. Espero oír pronto de ustedes. 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. ALMACENANDO Y RECUPERANDO IMAGENES JPEG EN UN CAMPO DE UNA TABLA Para comenzar, los campos Graphic están diseñados para trabajar sólo con mapas de bits, iconos y metaarchivos, y el control DBImage está diseñado para ser enlazado con un campo Graphic, así que no podemos usar ninguno de los dos. Para guardar imágenes JPEG tenemos que usar un campo Blob en lugar de un campo Graphic, y podemos usar un código como el siguiente: uses jpeg; procedure TForm1.Button1Click(Sender: TObject); var Jpg: TJpegImage; Stream: TMemoryStream; begin Jpg := nil; Stream := nil; try // Crear una imagen JPEG y cargarla desde un archivo Jpg := TJpegImage.Create; Jpg.LoadFromFile('test.jpg'); // Crear una corriente y guardar la imagen en ella Stream := TMemoryStream.Create; Jpg.SaveToStream(Stream); Stream.Position := 0; Table1.Append; // Cargar el campo Blob desde la corriente TBlobField(Table1.FieldByName('Graph')).LoadFromStream(Stream); Table1.Post; except jpg.Free; Stream.Free; raise; end; jpg.Free; Stream.Free; end; Para mostrar una imagen JPEG almacenada en un campo Blob en un control TImage, podemos usar un código como el siguiente por ejemplo en un evento AfterScroll: procedure TForm1.Table1AfterScroll(DataSet: TDataSet); var Stream: TMemoryStream; Jpg: TJpegImage; begin Jpg := nil; Stream := nil; try // Crear una corriente y cargarle el contenido de un campo Blob Stream := TMemoryStream.Create; TBlobField(Table1.FieldByName('Graph')).SaveToStream(Stream); if Stream.Size > 0 then begin // Crear una imagen JPEG y cargarla desde la corriente Jpg := TJpegImage.Create; Stream.Position := 0; Jpg.LoadFromStream(Stream); // Asignar la imagen JPEG a la propiedad Picture de una imagen Image1.Picture.Assign(Jpg); end else Image1.Picture.Assign(nil); except Image1.Picture.Assign(nil); end; jpg.Free; Stream.Free; end; Si desea poder guardar imágenes de diferentes tipos (mapas de bits, iconos, metaarchivos y jpegs) en un campo, puede agregar un byte al comienzo de la corriente para indicar la clase de imagen, y luego debe leer primero este byte para saber cómo cargar y mostrar esta imagen apropiadamente. Hemos diseñado un ejemplo completo para mostrarlo cómo hacerlo. 1) Coloque los siguientes componentes en un formulario y establezca las siguientes propiedades: Table1: TTable TableName = 'GraphTest.DB' FieldDefs = Field1 Name = 'Graph' DataType = ftBlob Size = 1 StoreDefs = True DataSource1: TDataSource DataSet = Table1 DBNavigator1: TDBNavigator DataSource = DataSource1 Align = alBottom PopupMenu1: TPopupMenu Items = mnuLoad: TMenuItem Caption = '&Load...' mnuClear: TMenuItem Caption = '&Clear' Image1: TImage PopupMenu = PopupMenu1 dlgOpenPicture: TOpenPictureDialog Options = [ofReadOnly, ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofNoTestFileCreate, ofEnableSizing] 2) Agregue "jpeg" a la cláusula uses: uses ..., jpeg; 3) Agregar la siguiente declaración de tipo a la unidad: type TGraphType = (gtBitmap, gtIcon, gtMetafile, gtJpeg); 4) Genere los siguientes eventos: procedure TForm1.FormCreate(Sender: TObject); begin if Not FileExists('GraphTest.DB') then Table1.CreateTable; Table1.Open; end; procedure TForm1.mnuLoadClick(Sender: TObject); var Jpg: TJpegImage; Stream: TMemoryStream; FileExt: string; GraphType: TGraphType; begin if dlgOpenPicture.Execute then begin Jpg := nil; Stream := nil; try Stream := TMemoryStream.Create; FileExt := LowerCase(ExtractFileExt(dlgOpenPicture.FileName)); if (FileExt = '.bmp') or (FileExt = '.dib') then begin GraphType := gtBitmap; Stream.Write(GraphType, 1); with Image1.Picture.Bitmap do begin LoadFromFile(dlgOpenPicture.FileName); Image1.Picture.Bitmap.SaveToStream(Stream); end; end else if (FileExt = '.ico') then begin GraphType := gtIcon; Stream.Write(GraphType, 1); with Image1.Picture.Icon do begin LoadFromFile(dlgOpenPicture.FileName); Image1.Picture.Bitmap.SaveToStream(Stream); end; end else if (FileExt = '.emf') or (FileExt = '.wmf') then begin GraphType := gtMetafile; Stream.Write(GraphType, 1); with Image1.Picture.Metafile do begin LoadFromFile(dlgOpenPicture.FileName); Image1.Picture.Bitmap.SaveToStream(Stream); end; end else if (FileExt = '.jpg') or (FileExt = '.jpeg') or (FileExt = '.jpe') then begin Jpg := TJpegImage.Create; Jpg.LoadFromFile(dlgOpenPicture.FileName); Image1.Picture.Assign(Jpg); GraphType := gtJpeg; Stream.Write(GraphType, 1); Jpg.SaveToStream(Stream); end; if (Table1.State <> dsEdit) and (Table1.State <> dsInsert) then Table1.Edit; Stream.Position := 0; TBlobField(Table1.FieldByName('Graph')).LoadFromStream(Stream); except jpg.Free; Stream.Free; raise; end; jpg.Free; Stream.Free; end; end; procedure TForm1.mnuClearClick(Sender: TObject); begin Image1.Picture.Assign(nil); if (Table1.State <> dsEdit) and (Table1.State <> dsInsert) then Table1.Edit; Table1.FieldByName('Graph').Assign(nil); // Limpiar el campo end; procedure TForm1.Table1AfterScroll(DataSet: TDataSet); var Stream: TMemoryStream; Jpg: TJpegImage; GraphType: TGraphType; begin Jpg := nil; Stream := nil; try Stream := TMemoryStream.Create; TBlobField(Table1.FieldByName('Graph')).SaveToStream(Stream); if Stream.Size > 0 then begin Stream.Position := 0; Stream.Read(GraphType, 1); case GraphType of gtBitmap: Image1.Picture.Bitmap.LoadFromStream(Stream); gtIcon: Image1.Picture.Icon.LoadFromStream(Stream); gtMetafile: Image1.Picture.Metafile.LoadFromStream(Stream); gtJpeg: begin Jpg := TJpegImage.Create; Jpg.LoadFromStream(Stream); Image1.Picture.Assign(Jpg); end else Image1.Picture.Assign(nil); // Limpiar la imagen end; end else Image1.Picture.Assign(nil); except Image1.Picture.Assign(nil); end; jpg.Free; Stream.Free; end; ________________________________________________________________________ 3. OBTENIENDO EL NUMERO DE SERIE DE UN VOLUMEN Cuando se formatea un disco/diskette, Windows guarda un número de serie en el sector de arranque. Este número se calcula usando la hora del sistema y no se garantiza que sea único, pero es sumamente improbable que dos discos tomados al azar tengan el mismo número de serie. Puede usar este número para un mecanismo de protección de copias, para asegurar que una aplicación sólo pueda ser ejecutada desde el disco duro en el que usted la instaló originalmente. Por ejemplo puede guardar el número de serie en el Registro de Windows y compararlo con el número de serie del disco cada vez que la aplicación se inicia. Le dejamos esa parte a usted. Para obtener el número de serie puede llamar a la función API GetVolumeInformation declarada en la unidad Windows. Note que también puede llamar esta función para obtener la etiqueta de volumen, la longitud máxima de los nombres de archivo, el tipo de sistema de archivos (por ejemplo 'FAT32') y sus opciones (como compresión de disco/ archivos y sensibilidad de mayúsculas/minúsculas y juego de caracteres de los nombres de archivos). La siguiente función es un envoltorio para la API GetVolumeInformation y devuelve el número de serie de la unidad pasada como parámetro: function GetVolumeSerialNumber(const drive: TFilename): longword; var VolumeName, FileSystemName: array[0..MAX_PATH-1] of char; VolumeSerialNumber, MaxFilenameLength, FileSystemFlags: longword; begin GetVolumeInformation(PChar(IncludeTrailingBackslash(drive)), VolumeName, MAX_PATH, @VolumeSerialNumber, MaxFilenameLength, FileSystemFlags, FileSystemName, MAX_PATH); Result := VolumeSerialNumber; end; Llamada de ejemplo: procedure TForm1.Button1Click(Sender: TObject); var serial: longword; begin serial := GetVolumeSerialNumber('C:\'); ShowMessage(IntToHex(HiWord(serial), 4) + '-' + IntToHex(LoWord(serial), 4)); end; ________________________________________________________________________ 4. ENLACES * The Delphi Programming Source CodeWeb Site http://www.sandbrooksoftware.com/DPSC/index.shtml * Just Delphi Jobs http://www.JustDelphiJobs.com ________________________________________________________________________ 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/p0011.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!






