This had me stumped for a bit too. To elaborate on the reply from Kambiz, I've written the following function:
- Code: Select all
function GetPrintable: TRect;
begin
with PrintPreview do
begin
result.Left := ConvertUnits(GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX),
GetDeviceCaps(Printer.Handle, LOGPIXELSX),
mmPixel, Units);
result.Top := ConvertUnits(GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY),
GetDeviceCaps(Printer.Handle, LOGPIXELSY),
mmPixel, Units);
result.Right := result.Left + ConvertUnits(Printer.PageWidth,
GetDeviceCaps(Printer.Handle, LOGPIXELSX),
mmPixel, Units);
result.Bottom := result.Top + ConvertUnits(Printer.PageHeight,
GetDeviceCaps(Printer.Handle, LOGPIXELSY),
mmPixel, Units);
end;
end;
This code will handle cases where the printer x and y DPI are not the same. It will also handle cases where the printable area is not centered on the page (such as my printer, an Epson Stylus C60). Once you have the printable rectangle, all of your drawing to the preview should be kept within these boundaries. Incidentally, Printer.PageWidth and Printer.PageHeight represent the width and height of the printable area.
Since this code queries the printer itself, it's important that the printer settings reflect what is going on with the PrintPreview (your PrintPreview may be in Portrait mode when the printer is in landscape mode) so call PrintPreview.SetPrinterOptions before calling this function.