Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
Delphi 2006 Professional
|
Drucken - Skalierung?
6. Jun 2006, 15:57
Hallo,
ich will eine Dateiliste ausdrucken. Abgesehen davon, dass es jetzt auf einmal das komplette System hopsnimmt (totales Einfrieren), hab ich zwei Probleme:
- PDFCreator nimmt alles wunderbar an, HP officejet 5500 druckt spiegelverkehrt und außerdem über die ränder hinaus
- Wenn ich nicht einen ganz bestimmten wert einstelle für die darstellung der dateinamen, wird das ganze arg verzerrt.
Ich hole mir die Dateiicons mit der Prozedur von sakura, die ich ein wenig modifiziert habe:
Delphi-Quellcode:
function GetFileIcon(Folder, FName: string;aWidth,txthght: Integer): TBitmap;
var
FileInfo: TSHFileInfo;
ImageListHandle: THandle;
aIcon: TIcon;
txtrect: TRect;
begin
Result := TBitmap.Create;
// Speicher löschen
FillChar(FileInfo, SizeOf(FileInfo), #0);
// Handle der Image Liste der ausgewählten Datei ermitteln
ImageListHandle := SHGetFileInfo(
PChar(Folder + ' \' + FName),
0,
FileInfo,
SizeOf(FileInfo),
SHGFI_ICON or SHGFI_LARGEICON // großes Icon verlangen
);
try
// TIcon Objekt erstellen
aIcon := TIcon.Create;
try
// Icon Handle zuweisen
aIcon.Handle := FileInfo.hIcon;
// Transparent darstellen
aIcon.Transparent := True;
with Result do
begin
// bitmap auf die entsprechende Größe bringen
Width := aWidth;
Height := aIcon.Height + txthght;
txtrect := rect(0,aIcon.Height, Width, Height);
DrawText(Canvas.Handle,PChar(FName),length(FName),txtrect,DT_WORDBREAK + DT_CENTER + DT_NOPREFIX);
Canvas.Draw((aWidth - aIcon.Width) div 2, 0, aIcon);
end;
// Icon darstellen
finally
// TIcon Objekt freigeben
FreeAndNil(aIcon);
end;
finally
// Icon der Shell wieder freigeben
DestroyIcon(FileInfo.hIcon);
// Icon Liste der Shell wieder freigeben
ImageList_Destroy(ImageListHandle);
end;
end;
Die Funktion schreibt also gleich den Dateinamen unter das Icon.
Meine Druckfunktion sieht so aus, man beachte den ersten Kommentar:
Delphi-Quellcode:
procedure TFMain.Print;
var pw,ph,rowheight: Integer;
scale: single;
row: TBitmap32;
irow,icol: Integer;
temp: TBitmap;
files: TStrings;
availwidth,availheight: Integer;
x,y,offsetx,offsety,i: Integer;
ipage: Integer;
wpi,hpi: Integer;
numcols,numrows: Integer;
folder: string;
temp32,temp32scaled: TBitmap32;
dstrect,srcrect,txtrect: TRect;
textheight,iwidth: Integer;
begin
if PD1.Execute then
begin
textheight := 80; //wenn das auf einem anderen wert ist, wird das Bild verzerrt...
iwidth := 120;
printer.BeginDoc;
SetMapMode(printer.Handle,MM_LOMETRIC);
pw := GetDeviceCaps(Printer.Handle, HORZSIZE)*10;
ph := GetDeviceCaps(Printer.Handle, VERTSIZE)*10;
offsetx := GetDeviceCaps(Printer.Handle,PHYSICALOFFSETX);
offsety := GetDeviceCaps(Printer.Handle,PHYSICALOFFSETY);
availwidth := pw - 2*offsetx; //available width
availheight := ph - 2*offsety; //available height
numcols := SECols.Value; //number of columns
// files
folder := STV.SelectedFolder.PathName;
files := GetFolder(folder,faAnyFile + faDirectory);
// temporary image for dimensions
temp := GetFileIcon(folder,files[0],iwidth,textheight);
// scale = available width / original width
scale := availwidth / (temp.Width * numcols);
wpi := round(temp.Width * scale); //width per icon
hpi := round(temp.Height * scale); //height per icon
numrows := availheight div hpi; //number of rows per page
irow := 0;
icol := 0;
// temporary resources for image stretching
temp32 := TBitmap32.Create;
temp32scaled := TBitmap32.Create;
irow := 2;
txtrect := rect(offsetx+10,-(offsety+10),availwidth+offsetx,irow * hpi+offsety);
DrawText(printer.Canvas.Handle,
PChar('Verzeichnislisting: ' + folder),
length('Verzeichnislisting: ' + folder),
txtrect,
DT_PATH_ELLIPSIS + DT_WORDBREAK + DT_NOPREFIX + DT_NOCLIP);
for i := 0 to files.count -1 do
begin
x := offsetx + icol * wpi;
y := offsety + irow * hpi;
//temp32.SetSizeFrom(GetFileIcon(folder,files[i],iwidth,textheight));
temp32.Assign(GetFileIcon(folder,files[i],iwidth,textheight));
temp32scaled.Width := Round(temp32.Width * scale);
temp32scaled.Height := Round(temp32.Height * scale);
dstrect := rect(0,0,temp32scaled.Width,temp32scaled.Width);
srcrect := rect(0,0,temp32.Width,temp32.Height);
temp32scaled.StretchFilter := sfLanczos;
temp32scaled.Clear(clwhite);
temp32scaled.Draw(dstrect,srcrect,temp32);
//temp32scaled.Draw(0,0,temp32);
temp32scaled.FlipVert();
(*
temp.Width := temp32scaled.Width;
temp.Height := temp32scaled.Height;
*)
temp.Assign(temp32scaled);
printer.Canvas.Draw(x,-y,temp);
Inc(icol);
if icol = numcols then
begin
icol := 0;
Inc(irow);
if irow = numrows then
begin
irow := 0;
Application.Processmessages;
printer.NewPage;
end;
end;
end;
Printer.EndDoc;
FImage.Image1.Picture.Assign(temp);
FImage.Image1.Center := true;
FImage.Show;
end;
end;
Sieht da irgendjemand den grund für meine Probleme? Eventuell habe ich irgendwo Sachen falsch umgerechnet... Ich hoffe, es ist ausreichend dokumentiert, aber bei Unklarheiten einfach fragen!
Lukas Erlacher
|