I have TPanel. On this Panel there is an TImage descendant , few other panels with controls, etc. In fact, picture contains some diagram, while additional panels with labels are created during runtime to provide user with additional info.
Recently I was told, that it would be nice, if it was possible to print this panel, and have it on the paper just as it appears in form. Any clues, how to do it?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I found an old usenet post that provides a solution, by copying the contents of the panel to a bitmap, which can be printed:
procedure TFormPrintWindows.ButtonPrintPanelClick(Sender: TObject);
var
Bitmap : TBitmap;
FromLeft : INTEGER;
FromTop : INTEGER;
PrintedWidth : INTEGER;
PrintedHeight: INTEGER;
begin
Printer.BeginDoc;
TRY
Bitmap := TBitmap.Create;
TRY
Bitmap.Width := Panel1.Width;
Bitmap.Height := Panel1.Height;
Bitmap.PixelFormat := pf24bit; // avoid palettes
// Copy the Panel area from the Form into a separate Bitmap
Bitmap.Canvas.CopyRect(Rect(0,0, Bitmap.Width,Bitmap.Height),
FormPrintWindows.Canvas,
Rect(Panel1.Left, Panel1.Top,
Panel1.Left + Panel1.Width-1,
Panel1.Top + Panel1.Height-1) );
// Assumes 10% left, right and top margin
// Assumes bitmap aspect ratio > ~0.75 for portrait mode
PrintedWidth := MulDiv(Printer.PageWidth, 80,100); // 80%
PrintedHeight := MulDiv(PrintedWidth, Bitmap.Height, Bitmap.Width);
FromLeft := MulDiv(Printer.PageWidth, 10,100); // 10%
FromTop := MulDiv(Printer.PageHeight,10,100); // 10%
PrintBitmap(Printer.Canvas,
Rect(FromLeft, FromTop,
FromLeft + PrintedWidth,
FromTop + PrintedHeight),
Bitmap);
FINALLY
Bitmap.Free
END;
FINALLY
Printer.EndDoc
END
end;
and add
//Source of Code:
//http://www.swissdelphicenter.ch/torry/showcode.php?id=744
//Which refers to a posting to borland.public.delphi.winapi by Rodney E Geraghty, 8/8/97.
procedure PrintBitmap(Canvas: TCanvas; DestRect: TRect; Bitmap: TBitmap);
var
BitmapHeader: pBitmapInfo;
BitmapImage: Pointer;
HeaderSize: DWORD;
ImageSize: DWORD;
begin
GetDIBSizes(Bitmap.Handle, HeaderSize, ImageSize);
GetMem(BitmapHeader, HeaderSize);
GetMem(BitmapImage, ImageSize);
try
GetDIB(Bitmap.Handle, Bitmap.Palette, BitmapHeader^, BitmapImage^);
StretchDIBits(Canvas.Handle,
DestRect.Left, DestRect.Top, // Destination Origin
DestRect.Right - DestRect.Left, // Destination Width
DestRect.Bottom - DestRect.Top, // Destination Height
0, 0, // Source Origin
Bitmap.Width, Bitmap.Height, // Source Width & Height
BitmapImage,
TBitmapInfo(BitmapHeader^),
DIB_RGB_COLORS,
SRCCOPY)
finally
FreeMem(BitmapHeader);
FreeMem(BitmapImage)
end
end {PrintBitmap};
回答2:
PrintBitmap in Birger's code example is missing, when you add the missing method it works well.
//Source of Code:
//http://www.swissdelphicenter.ch/torry/showcode.php?id=744
//Which refers to a posting to borland.public.delphi.winapi by Rodney E Geraghty, 8/8/97.
procedure PrintBitmap(Canvas: TCanvas; DestRect: TRect; Bitmap: TBitmap);
var
BitmapHeader: pBitmapInfo;
BitmapImage: Pointer;
HeaderSize: DWORD;
ImageSize: DWORD;
begin
GetDIBSizes(Bitmap.Handle, HeaderSize, ImageSize);
GetMem(BitmapHeader, HeaderSize);
GetMem(BitmapImage, ImageSize);
try
GetDIB(Bitmap.Handle, Bitmap.Palette, BitmapHeader^, BitmapImage^);
StretchDIBits(Canvas.Handle,
DestRect.Left, DestRect.Top, // Destination Origin
DestRect.Right - DestRect.Left, // Destination Width
DestRect.Bottom - DestRect.Top, // Destination Height
0, 0, // Source Origin
Bitmap.Width, Bitmap.Height, // Source Width & Height
BitmapImage,
TBitmapInfo(BitmapHeader^),
DIB_RGB_COLORS,
SRCCOPY)
finally
FreeMem(BitmapHeader);
FreeMem(BitmapImage)
end
end {PrintBitmap};