The error suggest that probable causes is that source canvas is DirectX accelerated and printer is usually just SW GDI rendered which might prevent direct Assign
due to Rendering Context incompatibility (the objects are too foreign to eachother).
Another possibility is that Assign
also changes the resolution which I expect is not allowed for printer Canvas ...
Why not CopyRect
and/or StretchDraw
instead?
So copy the contents of source Canvas into printer Canvas or temp Canvas instead of Assign it directly...
OK here is VCL C++ example of what I mean (adapted from mine standard printing routine I use in my apps):
void TMain::print(TCanvas *src,int xs,int ys)
{
// just check if any printers available first
TPrinter *prn = Printer();
int pxs,pys,psz,i=0;
if (prn==NULL) i=1;
if (prn->Printers==NULL) i=1;
if (prn->Printers->Count<=0) i=1;
if (i) return;
// used print dialog component
TPrintDialog *dlg_print=PrintDialog1;
dlg_print->Options.Clear();
dlg_print->Options<<poPrintToFile;
if (!dlg_print->Execute()) return;
// printer settings
prn = Printer();
pxs=prn->PageWidth;
pys=prn->PageHeight;
// create printer page backbuffer
Graphics::TBitmap *bmp=new Graphics::TBitmap;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
bmp->SetSize(pxs,pys);
// compute scale
float zoom,xx,yy;
xx=pxs/xs;
yy=pys/ys;
zoom=xx; if (zoom>yy) zoom=yy;
xx=xs; xx*=zoom;
yy=ys; yy*=zoom;
// copy Incompatible canvas into GDI Canvas (bmp)
bmp->Canvas->CopyRect
(
TRect(0,0,xx,yy),
src,
TRect(0,0,xs,ys)
);
// bmp->SaveToFile("print.bmp"); // just for debug so I do not need actually print
prn->BeginDoc();
for (i=0;i<dlg_print->Copies;i++)
{
if (i) prn->NewPage();
// render GDI Canvas (bmp) to printer page
prn->Canvas->Draw(0,0,bmp);
}
prn->EndDoc();
// release stuff
delete bmp;
}
using BDS2006 Turbo C++ (direct successor to BCB6 and Delphi)... just convert the C++ syntax to Pascal the rest should be the same... The Idea is to use temp bitmap (you might also directly render to printer page instead) and CopyRect
instead of Assign ... However you need to pass resolution of the TCanvas
as that is not accessible directly (as its usually a property of parent object).
[Edit1]
As Marco van de Voort pointed out you are using Firemonkey which I have no experience with and missed it while answering so in case the above code is not working you can workaround with different approach ...
Simply copy the Canvas
content using Winapi see:
and look for bullet #2 with name WinAPI approach in order to make it work you need Handle
of the Canvas
which should be a accessible property of the Canvas
or its parent object. If it is not you can still do this see:
On how to obtain the Handle
using Winapi again.