ウィキのコピーミラー

これは pascal.chat のウィキのミラーです。編集、履歴、ログインはそちらで行います。

Using the printer/ja

Deutsch · English · Español · Polski · 中文(中国) · 日本語

はじめに

Lazarus/FreePascal での印刷は簡単です。しかしながら、いくつかのステップを踏む必要があります。第一ステップは共通です。その次からは、さまざまな進んだ印刷技法を学べるようになります。この文書は、必要不可欠なステップをさまざまなネットのフォーラムや例から集めてきたものです。最初のステップの後で、実際に文書を印刷してみます。最後に、更に高度な印刷技法のヒントを提供します。

基本的なステップ

プリンタを使えるようにするには、次の段階を踏まなければなりません: You must do the following to be able to use printers:

  1. Printer4Lazarus パッケージを、プロジェクトが要求するパッケージに含める。
  2. Printers ユニットを、プログラムの uses 節に加える。
  3. 既に存在する Printer オブジェクトを使用する。

Printer4Lazarus パッケージを、プロジェクトが要求するパッケージに含める

Printer4Lazarus パッケージは基本的なプリンタを定義し、プラットフォームに依存しない印刷環境を提供します。さまざまなプラットフォームで、次の事が行えます。 The Printer4Lazarus package defines a basic printer and provides platform independent printing. The following can thus be used on various platforms.

Lazarus IDE で、次のようにしてください:

  1. プロジェクトメニューで、プロジェクトインスペクタをクリックします。ツリー表示のウインドゥが現れ、その中に、要求されたパッケージという枝があります。初期状態では、その枝にはLCLパッケージがあります。
  2. 追加ボタンを押します(ウインドゥ上部の+印ボタン)。
  3. 新規の要求 ページを開きます。
  4. パッケージ名リストボックスから Printer4Lazarus を選びます。
  5. OKをクリック。
  6. これで Printer4Lazarus が要求されたパッケージに現れます。

Printers ユニットをプログラムのユニットの uses 節に加える

このステップは簡単で、こんなふうになるでしょう:

pascal
unit MainUnit;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, Forms, Printers;

既存の Printer オブジェクトを用いる

ボタンを押したら文章を印刷するようにしたいとします。フォームに PrintBtn という名前でボタンを置き、OnClick イヴェントのところにこう書いてください:

pascal
procedure TForm1.PrintBtnClick(Sender: TObject);
const
  LEFTMARGIN = 100;
  HEADLINE = 'I Printed My Very First Text On ';
var
  YPos, LineHeight, VerticalMargin: Integer;
  SuccessString: String;
begin
  with Printer do
  try
    BeginDoc;
    Canvas.Font.Name := 'Courier New';
    Canvas.Font.Size := 10;
    Canvas.Font.Color := clBlack;
    LineHeight := Round(1.2 * Abs(Canvas.TextHeight('I')));
    VerticalMargin := 4 * LineHeight;
    // There we go
    YPos := VerticalMargin;
    SuccessString := HEADLINE + DateTimeToStr(Now);   
    Canvas.TextOut(LEFTMARGIN, YPos, SuccessString);
  finally
    EndDoc;
  end;
end;

先ほど基本的かつ単純と書きました。上記の例はちょっと複雑です。ボールドで基礎的なテキスト出力を行う方法に引き続き、書式を設定する例も示しています。

begin から end までの間に、こんなことが起きています:

フォーラムによっては、PrintDialog(プリンタ選択ダイアログ)を呼び出さないとうまくいかないように書いてありますが、(もはや)そんなことはありません。

次のステップ

上述の基本的なステップを踏んだら、次の段階に進めます。読者には以下の宿題を出しておきましょう:

Lazarus には、プリンタへの Raw 印刷を用いる例があります。次の場所をみてください。 $(lazarusdir)\components\printers\samples\rawmode\rawmodetest.lpi 他のプリンタを選択する例はこれです: $(lazarusdir)\components\printers\samples\dialogs\selectprinter.lpi

進んだステップ: コントロールの印刷

根本的には、プリンタオブジェクトは Canvas への描画を許し、その Canvas のイメジをプリンタに送るものです。上述の路線で進むなら、プリンタの canvas が持つメソッドを用いてテクストや楕円や菱形やなんかを描画していくことになります。

しかしながらこれは、立派なプログラマには到底興味を持たれるようなものではありません。あなたは今、完璧な CAD ソフトや画像ファイルのソータを書いているところで、あなたのプログラムが生んだ素晴らしい結果をプリンタに送りたいと思っています。完全なピクチャを Canvas メソッド呼出しの集団に翻訳するですって? とんでもない: すでにピクチャは手許にあるのです。

あなたがフォームに置くコントロールは一つ残らず、プリンタと同じように TCanvas オブジェクトにピクチャを描画しているのです。スクリーンからプリンタにピクチャを持ち込むために、これが使えます。

プレビュープログラムを書いているとします。まずフォームを作り、その上に TPanel を置きます。このパネルは、プレビューのすてきな灰色の背景となります。そのパネルの上に、page と呼ばれるもう一つの TPanel を置きます。この page は白色で、紙を表します。ページの大きさもすてきに変更可能です。

このページの上に TShape オブジェクトを一つおきます。例えばすてきな赤の、角が丸い長方形。さてここで、次のコードを PrintBtnClick イヴェントメソッドに置いてみてください:

pascal
MyPrinter.BeginDoc;
  page.PaintTo(myPrinter.Canvas, 0, 0);
MyPrinter.EndDoc;

何が起きるか:

更に進もう: リサイジング

プリンタが紙の上の一インチあたり使うピクセルの数は、モニタがスクリーン上の一インチあたり使うピクセルの数よりもはるかに大きくなっています(訳注: プリンタの DPI の方が、モニタの DPI よりずっと大きいということ)。その結果、スクリーンからプリンタにリダイレクトされた出力は、紙の上ではちっぽけになってしまいます。見栄えのする印刷には、スケーリングとレイアウトの制御が大事です。スクリーンで見る大きさと紙の上での大きさが揃っていればすてきでしょう(訳注: 昔のマックのように)。

今の時点では、我々は理想(ideal)を追っているのではなく、理念(idea)を探っているのです。前にも述べた通り、コントロールは描画に自前の Canvas を持っておらず、コンテナあるいはオーナーの Canvas に依存しています。しかし、自前の Canvas を持つコンポーネントもあります。ここでは TBitMap を選びます。次のように働きます。

pascal
procedure TForm1.PrintBtnClick(Sender: TObject);
var
  MyPrinter : TPrinter;
  myBitMap : TBitMap;
begin
  myBitMap := TBitMap.Create;
  myBitMap.Width := page.Width;
  myBitMap.Height := page.Height;
  page.BorderStyle:=bsNone;
  page.PaintTo(myBitMap.Canvas, 0, 0);
  page.BorderStyle:=bsSingle;
  //
  MyPrinter := Printer;
  MyPrinter.BeginDoc;
    //page.PaintTo(myPrinter.Canvas, 0, 0);
    //myPrinter.Canvas.Draw(0,0, myBitMap);
    myPrinter.Canvas.CopyRect(Classes.Rect(0, 0, myPrinter.PaperSize.Width, myPrinter.PaperSize.Height),
       myBitMap.Canvas, Classes.Rect(0, 0, myBitMap.Width, myBitMap.Height));
  MyPrinter.EndDoc;
  myBitMap.Free;
end;

これを動作させるには、Windows ユニットを使わないでください。Windows ユニットは異なった Rect を定義しています。この例ではこんなことが起こります:

page が拡大される時に一つ注意すべきことがあります。Printer.papersize はビットマップの大きさより相当大きいが、コピーされる過程でうまく当てはまるようになるということです。ただし、これがちゃんと働くようにするには、page の縦横比を用紙の縦横比と一致させなければなりません。やり方はわかるでしょう。

このやりかたの問題点は、スクリーンのピクセルが印刷した紙にも出ることです。言ったように、理想ではなく理念を提示したのです。コントロールは自前の Canvas を持っていない、コントロールを印刷するには、自前の Canvas を持つオブジェクト(TBitMap)にまず描画する。さてこれで、読者はそれがどう働くかを知り、精細な図版や文書を作り出す方法を理解することができるようになったわけです。そのためには、自分自身を描画する際に、TPanel には低解像度で、TBitMap には高解像度で行うようなオブジェクトが必要になるでしょう。しかし、それは別の解説書の題材です。

関連項目


From the Free Pascal wiki, page "Using the printer/ja", as it stood on 2020-03-04 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

第1版、最終更新:WikiArchive 。