delphiprintingvcldelphi-5tpanel

How to print TPanel contents?


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?


Solution

  • 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};