How to use TPrintPreview to Print Multiple Pages for BCB6

Please discuss general Delphi programming topics here.

How to use TPrintPreview to Print Multiple Pages for BCB6

Postby Wisarut » May 7th, 2009, 11:18 am

Hi Everybody,

I'm just a newbie for this forum.
I've use TPrintPreview component on BCB6 to print the result of my application
by using canvas to capture the form as shown in this code:

void __fastcall TForm2::Print1Click(TObject *Sender)
{
// Printign mechanism

int PrintLeft, PrintTop, PrintWidth, PrintHeight;
TRect Srect, Smrect,*DynamicSRect, *DynamicSMRect;
Graphics::TBitmap **PrintingBitmapSet;
int BitmapSetNum = 2;
PrintingBitmapSet = new Graphics::TBitmap* [BitmapSetNum];
DynamicSRect = new TRect [BitmapSetNum];
DynamicSMRect = new TRect [BitmapSetNum];
for(int i =0; i <= BitmapSetNum-1;i++)
{
PrintingBitmapSet[i] = new Graphics::TBitmap;
PrintingBitmapSet[i]->PixelFormat = pf24bit;
}
TCanvas *C = new TCanvas;
C->Handle = GetDC(0);
PrintBMP = new Graphics::TBitmap;
PrintBMP->PixelFormat = pf24bit;
CanvasPager->ActivePage = ZoomCanvasPage;
PrintLeft = Form2->Left;
PrintTop = Form2->Top + 83;
PrintWidth = Form2->Width;
PrintHeight = Form2->Height - 93;
Srect = Rect(PrintLeft,PrintTop,PrintLeft+PrintWidth,PrintTop+PrintHeight);
Smrect = Rect(0, 0, PrintWidth, PrintHeight);
DynamicSRect[0] = Rect(PrintLeft,PrintTop,PrintLeft+PrintWidth,PrintTop+PrintHeight);
DynamicSMRect[0] = Rect(0, 0, PrintWidth, PrintHeight);
PrintBMP->PixelFormat = pf24bit;
PrintBMP->Width = PrintWidth;
PrintBMP->Height = PrintHeight;
PrintBMP->Canvas->CopyRect(Smrect, C, Srect);
PrintBMP->Canvas->TextOutA(PrintBMP->Width - 250, 4, "Written By: Dr.Pooh, NECTEC @2008-2012");
PrintingBitmapSet[0]->Assign(PrintBMP);
delete PrintBMP; PrintBMP = NULL;
delete C; C = NULL;
C = new TCanvas;
C->Handle = GetDC(0);
PrintBMP = new Graphics::TBitmap;
PrintBMP->PixelFormat = pf24bit;
CanvasPager->ActivePage = PhotoCanvasPage;
PrintLeft = Form2->Left;
PrintTop = Form2->Top + 83;
PrintWidth = Form2->Width;
PrintHeight = Form2->Height - 93;
Srect = Rect(PrintLeft,PrintTop,PrintLeft+PrintWidth,PrintTop+PrintHeight);
Smrect = Rect(0, 0, PrintWidth, PrintHeight);
DynamicSRect[1] = Rect(PrintLeft,PrintTop,PrintLeft+PrintWidth,PrintTop+PrintHeight);
DynamicSMRect[1] = Rect(0, 0, PrintWidth, PrintHeight);
PrintBMP->PixelFormat = pf24bit;
PrintBMP->Width = PrintWidth;
PrintBMP->Height = PrintHeight;
PrintBMP->Canvas->CopyRect(Smrect, C, Srect);
PrintBMP->Canvas->TextOutA(PrintBMP->Width - 250, 4, "Written By: Dr.Pooh, NECTEC @2008-2012");
PrintingBitmapSet[1]->Assign(PrintBMP);
delete PrintBMP; PrintBMP = NULL;
delete C; C = NULL;
int PrintingCode = 1;
Form11->ShowForm11(PrintingBitmapSet,BitmapSetNum,PrintingCode);
}
//---------------------------------------------------------------------------

So far, I learnt from your example on how to print Bitmap Data in single page and it works very well. However, I still have a very hard time on how to print Bitmap Data stored in Dynamic Array as multiple page since it gives me Access Violation Problem at PaintGraphicEx function of TPrintPreview component.

The source code for Print Preview can be shown as follows:

void __fastcall TForm11::ShowForm11(Graphics::TBitmap **Resultbitmap,int NumPage,int PrintingCodeX)
{
// Need to be change to allow Multiple page
NumPage1 = NumPage;
PrintingCode = PrintingCodeX;
DynamicBitmap = new Graphics::TBitmap* [NumPage1];
for(i= 0; i <= NumPage1-1; i++)
{
if(Resultbitmap != NULL)
{
DynamicBitmap[i] = new Graphics::TBitmap;
DynamicBitmap[i]->PixelFormat = pf24bit;
DynamicBitmap[i]->Assign(Resultbitmap[i]);
}
}
CreatePages(DynamicBitmap,R,PortraitOrientation,ProportionalScaling,PrintingCode,NumPage1);
InvalidateRect(PrintPreview1->Handle,&R,true);
Show();
}
//------------------------------------------------------------------------------------------------------------------------
void __fastcall TForm11::CreatePages(Graphics::TBitmap **BitmapX,TRect Rect1,
bool PortraitOrientation1, bool ProportionalScaling1,int PrintingCodeX, int NumPageX)
{
// This is hte mechanic thich has to be changed to allow Multiple page

// create single page by CreateImageOnlyPage function
if(NumPageX == 1 && BitmapX != NULL)
{
bitmap = new Graphics::TBitmap;
bitmap->PixelFormat = pf24bit;
bitmap->Assign(BitmapX[0]);
PrintPreview1->BeginDoc();
CreateImageOnlyPage(bitmap,Rect1,ProportionalScaling1);
// This section work very well
Application->ProcessMessages();
PrintPreview1->EndDoc();
} else if(NumPageX >=2 && BitmapX != NULL)
{

PrintPreview1->BeginDoc();
for(i = 0; i <=NumPageX-1;i++);
{

PrintPreview1->NewPage(); // Next Page
if(BitmapX[i] != NULL)
{
CreateImageOnlyPage(BitmapX[i],Rect1,ProportionalScaling1);
}
Application->ProcessMessages();
}
PrintPreview1->EndDoc();

}
// CreateImageOnlyPage(BitmapX,Rect1,ProportionalScaling1);

}
//---------------------------------------------------------------------------------------------------------------------------------
void __fastcall TForm11::CreateImageOnlyPage(Graphics::TBitmap *BitmapX1,TRect Rect2, bool ProportionalScaling2)
{
if(ProportionalScaling2 == true)
{
Proportional = true;
}
else if(ProportionalScaling2 == false)
{
Proportional = false;
}
if(BitmapX1 != NULL)
{
PrintPreview1->PaintGraphicEx(Rect2,BitmapX1,Proportional,false,true); // -> Access violation Problem arise here!
}
}
//---------------------------------------------------------------------------------
The program stop at the following line in Preview.pas
function TPrintPreview.PaintGraphicEx(const Rect: TRect; Graphic: TGraphic;
Proportinal, ShrinkOnly, Center: Boolean): TRect;
var
gW, gH: Integer;
rW, rH: Integer;
W, H: Integer;
begin
gW := ConvertUnits(Graphic.Width, Screen.PixelsPerInch, mmPixel, FUnits);
% Program stop here!

//--------------------------------------------------------------------

If you know how to print the bitmap data in multiple pages, please help me out of this trouble now!
It would be a lot better if you can show the source code (Delphi is okay but BCB is preferred)
Wisarut
Member
Member
 
Posts: 3
Joined: May 7th, 2009, 9:52 am

Re: How to use TPrintPreview to Print Multiple Pages for BCB6

Postby Kambiz » May 10th, 2009, 1:34 pm

I couldn't see something wrong in your code. However because you code is a bit complex, chance of having a mistake is high.

You have created several copies of initial bitmaps in your code. It doesn't seem to be necessary. Removing those parts make the code much smaller and easier to trace.

For printing several bitmaps each on a single page, do this:

Code: Select all
void __fastcall TForm11::CreatePages(Graphics::TBitmap **BitmapX,TRect Rect1,
  bool PortraitOrientation1, bool ProportionalScaling1,int PrintingCodeX, int NumPageX)
{
  if (NumPageX > 0 && BitmapX != NULL)
  {
    PrintPreview1->BeginDoc();
    for(i = 0; i < NumPageX; i++);
    {
      if (i != 0)
      {
        PrintPreview1->NewPage(); // Next Page
      }
      PrintPreview1->PaintGraphicEx(Rect1, BitmapX[i], ProportionalScaling1, false, true);
    }
    PrintPreview1->EndDoc();
  }
}
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2430
Joined: March 7th, 2003, 7:10 pm

Re: How to use TPrintPreview to Print Multiple Pages for BCB6

Postby Wisarut » May 11th, 2009, 7:34 pm

Well, I've followed your advice but I found that it still not showing the multiple pag print preview as I wish.
It give me the Access Violation Screen2PrinterUnit function within Preview.pas

void __fastcall TForm11::CreatePages(Graphics::TBitmap **BitmapX,TRect *DynamicRect1,
bool PortraitOrientation1, bool ProportionalScaling1,int PrintingCodeX, int NumPageX)
{
if(NumPageX >=1 && BitmapX != NULL)
{
PrintPreview1->BeginDoc();
for(i = 0; i <=NumPageX-1;i++);
{
if (i >=1)
{
PrintPreview1->NewPage(); // Next Page
}
if(BitmapX[i] != NULL)
{
PrintPreview1->PaintGraphicEx(R, BitmapX[i], ProportionalScaling1, false, true);
}
}
PrintPreview1->EndDoc();


}

}


function TPrintPreview.PaintGraphicEx(const Rect: TRect; Graphic: TGraphic;
Proportinal, ShrinkOnly, Center: Boolean): TRect;
var
Bitmap: TBitmap;
gW, gH: Integer;
rW, rH: Integer;
W, H: Integer;
begin
gW := Screen2PrinterUnit(Graphic.Width); % Program stop here
gH := Screen2PrinterUnit(Graphic.Height);
rW := Rect.Right - Rect.Left;
rH := Rect.Bottom - Rect.Top;

BTW, the Dynamci Array of Bitmap variable consists of Bitmap Data at various sizes as shown here:

BitmapX[0]->Width = 1280; BitmapX[0]->Height = 1024; // The Result Form
BitmapX[1]->Width = 379; BitmapX[1]->Width = 561; // Table 1
BitmapX[2]->Width = 356; BitmapX[2]->Width = 193; // Table 2
...................
BitmapX[14]->Width = 364; BitmapX[14]->Width = 801; // Table 14
BitmapX[15]->Width = 766; BitmapX[15]->Width = 605; // Image with Trace Line\


How can I reconfiguare the PrintPreview Components to handle Bitmap Data with various sizes?

Hope that there will bwe a solution for this problem.

Wisarut
Wisarut
Member
Member
 
Posts: 3
Joined: May 7th, 2009, 9:52 am

Re: How to use TPrintPreview to Print Multiple Pages for BCB6

Postby Kambiz » May 11th, 2009, 9:13 pm

I guess it's because dimensions of your bitmaps are too large. Windows has a limit for bitmap size.

You may want to consider using metafile instead of bitmap.
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2430
Joined: March 7th, 2003, 7:10 pm

Re: How to use TPrintPreview to Print Multiple Pages for BCB6

Postby Wisarut » May 12th, 2009, 3:45 am

In such a case, I may have display the result as a single page but need to apply ComboBox component to show different Bitmap Data which I have already done right now.

Furthermore, I need to add the mechanics to readjust the Paper Orientation for optimal display for each Bitmap Data.

BTW, How can I conver Bitmap Data into Metafile? Any suggestion ?
Wisarut
Member
Member
 
Posts: 3
Joined: May 7th, 2009, 9:52 am

Re: How to use TPrintPreview to Print Multiple Pages for BCB6

Postby Kambiz » May 15th, 2009, 3:17 pm

In your code, you create a bitmap, and then draw on the bitmap's canvas.
To use a metafile instead of the bitmap, you have to create a metafile canvas and draw on it.

Code: Select all
var
  Metafile: TMetafile;
  Canvas: TMetafileCanvas;
begin
  Metafile := TMetafile.Create;
  Metafile.Width := ImageWidth + 1;
  Metafile.Height := ImageHeight + 1;
  Canvas := TMetafileCanvas.Create(Metafile, 0);
  try
    // Use canvas to draw on the metafile
  finally
    Canvas.Free;
  end;
  // here, your metafile is ready to use
end;
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2430
Joined: March 7th, 2003, 7:10 pm


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 4 guests

cron