マスター教えてください。
長い複数ページにわたる文章を一度にCanvasに書き込んで、
任意の範囲(ページ)をプレビューしたり印刷したりしたいのです。
マスターのplPrevを使用すれば解決なのは分かっているのですが。
マスターのサンプル154,172とか
http://www.geocities.jp/asumaroyuumaro/program/tips/Printer.html
を参考にして考えました。
procedure TForm1.Button1Click(Sender: TObject);
var
DocMeta :TMetafile;
PageMeta :TMetafile;
DocMetaCanvas :TMetafileCanvas;
PageMetaCanvas :TMetafileCanvas;
PrintRect :TRect;
i,j :Integer;
sx_dpm,sy_dpm:real;
PageTate,PageYoko:integer; // A4の有効範囲270mm、180mm
begin
// スクリーンの解像度
sx_dpm := screen.PixelsPerInch / 25.4;
sy_dpm := screen.PixelsPerInch / 25.4; // 1mm当りのピクセル数
// A4有効印刷範囲 210 × 297 1ページのサイズ
PageTate := round(270 * sy_dpm); // ピクセル
PageYoko := round(180 * sx_dpm);
//テスト用メタファイルを作成
DocMeta :=TMetaFile.Create;
PageMeta :=TMetaFile.Create;
try
DocMeta.Width := PageYoko; // Screen解像度
DocMeta.Height := PageTate * 2; // 2ページ分
j := (PageTate * 2) div 20; // 印字する数字の最大値
label1.Caption := inttostr(j); // 102
DocMetaCanvas := TMetafileCanvas.Create(DocMeta, 0);
try
for i := 1 to j do begin
DocMetaCanvas.TextOut(50, i * 20, inttostr(i));
end;
finally
DocMetaCanvas.Free;
end;
// ここまででDocMetaに2ページにわたる文章(数字)が書き込まれた。
PageMetaCanvas := TMetafileCanvas.Create(PageMeta, 0); // Dest
try
SetMapMode(PageMetaCanvas.Handle,MM_ANISOTROPIC);
SetWindowExtEx(PageMetaCanvas.Handle,PageYoko,PageTate,nil);
SetViewPortExtEx(PageMetaCanvas.Handle,PageYoko,PageTate,nil); // 倍率1
// SetWindowOrgEx(PageMetaCanvas.Handle,0,0,nil); ←1ページ目が出力 1,2,…
SetWindowOrgEx(PageMetaCanvas.Handle,0,PageTate,nil); // 2ページ目 51,52,…
PageMetaCanvas.Draw(0,0,DocMeta);
finally
PageMetaCanvas.Free;
end;
// 以上でPageMetaに1ページ分だけ切り出した
// プレビュー画面
Image2.Canvas.Draw(0,0,PageMeta); // 原寸大で
// プリンタへの印刷
PrintRect :=Bounds(GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX),
GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY),
GetDeviceCaps(Printer.Handle, HORZRES),
GetDeviceCaps(Printer.Handle, VERTRES));
Printer.Title := 'MetaTest';
Printer.BeginDoc;
try
Printer.Canvas.StretchDraw(PrintRect,PageMeta);
// Printer.Canvas.Draw(0,0,PageMeta); ←ものすごく小さく印字される
except
Printer.Abort;
raise;
end;
Printer.EndDoc;
finally
DocMeta.Free;
PageMeta.Free;
end;
end;
大まかな処理の説明です。
1.数字1〜102を書き出したDocMetaメタファイルを作成しています。
2.マッピングでDocMetaファイルから1ページ分をPageMetaファイルに切り取ります。
3.PageMetaファイルをプレビュー用のImage1に表示
4.同時にプリンタへ出力しています。
疑問点・問題点
1.メタファイルのサイズをスクリーンの解像度に合わせたのですが問題はないでしょうか。
2.マッピングでSetWindowExtEx,SetViewPortExtEx,SetWindowOrgExが
すべてPageMetaCanvasに対して行われているのが理解できない。
DocMetaCanvasだったらなんとなく理解できますが。
3.プリンタへの印刷がPrinter.Canvas.Draw(0,0,PageMeta);では
ものすごく小さく印字される。
仕方がないのでPrinter.Canvas.StretchDrawを使うが文字が歪んでしまう。
|