TPrinter は、Windows のプリンタインターフェースをカプセル化したオブジェクトです。TPrinter を使用すると、フォームやビットマップのキャンバスに描画するのと同じように印刷面に描画できます。
TPrinter オブジェクトを使用するには、Printers ユニットを uses 節に加えなければなりません。TPrinter オブジェクトは、必要なときにそのインスタンスにアクセスできる Printer 関数によって利用します。Printer 関数は、最初に呼び出されたときに TPrinter オブジェクトのインスタンスを作成し、これを返します。2回目以降に呼び出されたときは、既に作成されたインスタンスを返します。Printer 関数を使う限り、プログラマは、TPrinter オブジェクトの生成や破棄を考慮する必要はありません。
TPrinter を用いた印刷は、「印刷ジョブ」という単位で行ないます。印刷ジョブは、1つ以上のページによって構成されたドキュメントデータで、プリンタスプーラによって管理されます。印刷ジョブを作成するには、はじめに BeginDoc メソッドを呼び出します。印刷ページへのアクセスは、Canvas プロパティを用いて行ないます。作成された印刷ジョブを終了するには、EndDoc メソッドを呼び出します。BeginDoc で開始した印刷ジョブは、1ページのデータを作成しますが、次のページを作成し、ここにデータを出力するには NewPage メソッドを呼び出します。NewPage または EndDoc を呼び出すまでは、作成中のページはプリンタに出力されません。BeginDoc によって開始した印刷ジョブを中断し、印刷されていない全てのデータを破棄するには、Abort メソッドを呼び出します。
単純な例ですが、次のコードは2ページのドキュメントをプリンタに出力します。
procedure
TForm1.Button1Click(Sender: TObject);
begin
with
Printer do
begin
BeginDoc;
Canvas.TextOut(10, 10, 'Print Test Page 1'
);
NewPage;
Canvas.TextOut(10, 10, 'Print Test Page 2'
);
EndDoc
end
;
end
;
印刷ジョブの情報を設定するプロパティとして、Title プロパティがあります。Title プロパティは、プリントマネージャやネットワークヘッダページに表示される印刷ジョブの情報を表わすテキストを設定できます。また、Orientation プロパティは、ページを垂直(poPortrait)と水平(poLandscape)のどちら向きに印刷するかを決定します。
現在印刷中の印刷ジョブに関する情報を取得する読み出し専用プロパティも、いくつか用意されています。PageHeight と PageWidth は、印刷ページの高さと幅をピクセル単位で表わします。また、PageNumber プロパティには、現在のページ番号が入っています。ただし、このプロパティを設定して、現在のページを変更することはできません。ページを変更できるのは、NewPage メソッドだけです。つまり、一旦変更したページを、前に戻るような操作はできません。
Printer の Canvas プロパティは、他の画面表示用の TCanvas オブジェクトと同じように、全てのプロパティやメソッドを用いることができます。Printer の Canvas は、現在のページの描画領域を表わします。
Printer の Canvas は、画面用の Canvas と解像度が異なり、1 ピクセルの大きさが変わります。画面表示イメージと印刷イメージの大きさを対応させる場合は、これらの差を考慮する必要があります。また、テキストの位置合わせなどの計算では、これらの点に注意したコーディングを行なわなければなりません。
PixelsPerInch は、相対的なサイズ比較の指標として役立ちます。PixelsPerInch プロパティは、システムフォントの大きさを基準に決定されるので、絶対的な 1 ピクセルの価値を計れるものではありません。Font の Size プロパティと Height プロパティは、PixelsPerInch によって関連付けられます。
Font.Height
= Trunc (-Font.Size * Font.PixelsPerInch / 72)
Size プロパティはポイント数で設定され、Height プロパティはピクセル数で設定されます。これらを用いて、相対的なサイズを計ることができます。 文字列の位置合わせでは、TextWidth や TextHeight メソッドを用いてピクセル単位での大きさを判断した方が確実です。これらのメソッドは、出力する文字列の大きさを求めることができるので、右寄せやセンタリングなどで、出力文字列ごとに呼び出して使用します。 プリンタに出力される実際の大きさを求めるために、これらのプロパティを用いることは薦められません。厳密なサイズを求めるには、Windows API を用いてデバイス情報を取得しなければなりません。
Windows API を用いるときには、Printer の Handle プロパティを用います。Printer の Handle プロパティは、Printer.Canvas の Handle プロパティと同じコンテキストハンドルです。ただし、Printer.Canvas.Handle が常にプリンタデバイスコンテキストを表わすのに対して、Printer.Handle は状況によって異なります。Printer.Canvas へのアクセスは、BeginDoc ~ EndDoc 間でしか有効ではありません。Printer.Handle は、BeginDoc ~ EndDoc 間で参照されると Canvas のそれと同じ働きをします。しかし、その他の所で使用すると、その値は情報コンテキストのハンドルを返します。
GetDeviceCaps は、デバイス固有の情報を取得する Windows API です。GetDeviceCaps を用いると、ミリメートル単位の描画領域の高さや幅を取得できます。
{ ボタンを押すと描画領域の大きさを表示します }
procedure TForm1.Button1Click(Sender: TObject);
var
mm_width, mm_height: Integer;
begin
with Printer do begin
mm_width := GetDeviceCaps(Handle, HORZSIZE);
mm_height := GetDeviceCaps(Handle, VERTSIZE);
end;
ShowMessage(IntToStr(mm_width) + 'x' + IntToStr(mm_height));
end;
プリンタへのグラフィック描画は、ドライバの能力によって決定されます。使用するプリンタやドライバの種類によって、サポートされる描画命令は異なります。特定の命令をサポートしないドライバがあるので、コーディングには注意が必要です。ドライバが特定の命令をサポートするかどうかは、GetDeviceCaps によって調べることができます。例えば、ラスタオペレーションの特定の機能をサポートするかどうかを調べるには、RASTERCAPS を引数に指定して GetDeviceCaps をコールします。関数はサポートするラスタオペレーションを表わすビットを返すので、RC_BITBLT のようなビットを表わす値との論理積を求めます。
if
(GetDeviceCaps(Printer.Handle, RASTERCAPS)
and
RC_BITBLT) = 0 then
...
TPrinter は、Printers プロパティによって、システムで使用可能なプリンタを調べることができます。これらのプリンタのうち、どのプリンタを用いるかは、PrinterIndex プロパティによって指定できます。PrinterIndex のデフォルトは -1 ですが、これはデフォルトのプリンターを使用するという意味です。
プリンタの用紙サイズや使用トレイの設定などを行なうには、SetPrinter 関数を用いる必要があります。
var
DrvName, PrtName, PortName
: array[0..127] of Char;
DeviceMode : THandle;
PDevMode : ^TDevMode;
begin
with Printer do begin
PrinterIndex := -1;
GetPrinter(DrvName,PrtName,PortName,DeviceMode);
{ ハンドルはロックして使用します }
PDevMode := GlobalLock( DeviceMode );
{ 用紙をB4に変更します }
PDevMode^.dmPaperSize := DMPAPER_B4;
GlobalUnlock( DeviceMode );
SetPrinter(DrvName, PrtName, PortName, DeviceMode);
end;
end;