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
eds2008 @ 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-2006 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/es/file.php?id=p11
________________________________________________________________________
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: eds2008 @ 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
________________________________________________________________________
|