Recent

Author Topic: Print Previews via TPrinterCanvas/TPrinter derived classes  (Read 4209 times)

derek.john.evans

  • Guest
Print Previews via TPrinterCanvas/TPrinter derived classes
« on: September 03, 2016, 09:07:31 am »
Ive seen a few requests for "print preview" solutions. The problem is, Lazarus doesn't have a TPrinterCanvas which renders to TBitmap's. (There is TPostScriptPrinterCanvas & TCairoPsCanvas)

I started some code a few weeks ago, but, put it on hold because it was messy. ie: Overriding each TCanvas method.

Today, I took another look, and it turns out, you can map a TPrinter to a TBitmap in just over 120 lines of code. Cool.

So, I put together a demo which prints a TRichMemo.

Download from:
http://www.wascal.net/bin/PrintPreview.zip

Note: Im using the FreePascal bitmap resamplers, which are slow, so, you may want to use something faster.

I also couldn't find a way to get TRichMemo to print one page. So, my TPrinterBitmap class has the method DoClearPage() which you can use to extract a page before it gets cleared for a new page.

The code should work for any printer enabled controls. Hopefully something similar is added to Lazarus in the future.

Cheers
Derek
« Last Edit: September 03, 2016, 09:14:21 am by Geepster »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Print Previews via TPrinterCanvas/TPrinter derived classes
« Reply #1 on: September 03, 2016, 10:41:46 pm »
The solution is Windows only.
You'd need to call  EM_FORMATRANGE in a loop, passing wParam of the message as 0 (always measure).
Each call to EM_FORMATRANGE is measuring a single page, thus you can track where the page you'd like to print starts and where it ends.
Once you found the characters for the desired page you could call Print() method of RichMemo. But before that you'd need to populate TPrintParams structure and specify SelStart and SelLength fields, so the only page printed would be the desired page.

 

TinyPortal © 2005-2018