Printing Graphics

The device context of the screen and that of the printer are two very different animals.  Block transferring bits between the two is not guaranteed to work (by Microsoft).  The reason is that the raster operations that a lot of the components use to paint to the screen, will not work on the printer's canvas.  This eliminates most VCL methods as a reliable technique for printing bitmaps.  See this article:

http://support.microsoft.com/support/kb/articles/q195/8/30.asp

According to Joe C. Hecht, who has written many printer drivers, the reliable way to print a bitmap is to use StretchDIBits().  To learn more about printing, visit Earl F. Glynn's printing section, 

http://www.efg2.com/lab/Library/Delphi/Printing/Default.htm

or power search www.deja.com for "printer" and "Joe C. Hecht".  Fortunately, Joe has posted a way of getting a device independant bitmap from the device dependant TBitmap, and using StretchDIBits to send it to the printer.  His code is on the Delphi QandA site:

http://www.borland.com/devsupport/delphi/qanda/FAQ1211D.html
 


What I've done is translated Joe's code to C++, and wrapped it into a simple non-visual component (TPrintDIB).  You can download it by clicking here <TPrintDIB.zip>

Here's it's documentation:
 

TPrintDIB::StretchDrawDIB

Nonvisual component derived from TComponent


StretchDrawDIB draws the bitmap specified by the SourceBitmap parameter in the rectangle implied from the x, y, Width, and Height parameters.

void __fastcall StretchDrawDIB(Graphics::TCanvas* DestCanvas,
                               int x, int y, 
                               int Width, int Height, 
                               Graphics::TBitmap* SourceBitmap);
 

Description

Call StretchDrawDIB to draw the bitmap specifed by SourceBitmap on the canvas specified by DestCanvas so that the image fits in the rectangle implied by x, y, Width, and Height.  StretchDraw calls the StretchDIBits method to render the bitmap. To render the bitmap in its natural size, specify the bitmap's width and height as the Width and Height parameters, repsectively. 
 

Example:

#include <vcl\printers.hpp>

void __fastcall TForm1::PrintButtonClick(TObject *Sender)
{
    int target_width = Printer()->PageWidth;
    int target_height = Printer()->PageHeight;

    Printer()->BeginDoc();
    PrintDIB1->StretchDrawDIB(Printer()->Canvas, 0, 0, target_width, target_height,
                              Image1->Picture->Bitmap);
    Printer()->EndDoc();
}