|
DelphiXE3 [FMX] 印刷 2014/06/06 |
前回は、画像ファイルを開く/又は新規状態で、上から絵を描画し、そして画像ファイルとして保存する、という事、Imageコンポーネントの Bitmap プロパティについて見てみました。今回は、印刷について見ていきます。
印刷する手法については、幾つかのパターンがあります。
・フォームをそのままハードコピーしたい
VCLアプリケーション時は、
Form1.PrintScale := poPrintToFit;
Form1.Print;
等
・リッチエディットの文章をそのまま印刷
VCLアプリケーション時は、
RichEdit1.Print('印刷タイトル');
等
・テキストをそのまま印刷
VCLアプリケーション時は、
uses節に「Printers」を追記しておき、
var
pr : TextFile;
begin
AssignPrn(pr);
Rewrite(pr);
WriteLn(pr,'印刷テスト');
WriteLn(pr,'これは、印刷のテストです。');
・・・
CloseFile(pr);
end;
等
・プリンターオブジェクトのキャンバスに描画して印刷
VCLアプリケーション時は、
uses節に「Printers」を追記しておき、
Printer.BeginDoc ;
with Printer.Canvas do begin
・・・
end;
Printer.EndDoc ;
等
・レポートツールを利用
QuickReport、RAVEコンポーネント、FastReport、
等
さて、それでは、FireMonkey(FMX) での印刷プログラムについてです。
[Dialogs]内のダイアログ画面
については既に記述しました。
【フォームをそのままハードコピーしたい】
FireMonkey(FMX)でのフォームには、Printメソッドというものはありませんので、それを利用する事は出来ません。代用として、フォーム内にパネルを配置して、各コンポーネントは、そのパネルの子にしてしまい、パネルのスクリーンショットを生成し、出来上がったビットマップをプリンタへ送る、という手段が取れると思われます。
uses節には、System.UIConsts、FMX.Printer、を追記しておいて下さい。以降の項目でも同様です。
フォーム内に [Standard]内のパネル(Panel)を配置し、パネルの Align プロパティを「alClient」とします。そのパネルの子となるよう各コンポーネントを配置します。勿論、各コンポーネントを配置した後からパネルを配置して、構造ツリーでドラッグ操作をしてパネルの子になるようにする事でもOKです。
ボタン Button1 をダブルクリックして、Button1 の OnClick イベントハンドラを下記のようにしてみます。
procedure TForm1.Button1Click(Sender: TObject);
var
bm : TBitmap;
src,dst : TRectF;
begin
bm := Panel1.MakeScreenshot;
if (PrintDialog1.Execute) then begin
Printer.ActivePrinter.SelectDPI(600, 600);
Printer.Canvas.Fill.Color := claBlack;
Printer.Canvas.Fill.Kind := TBrushKind.bkSolid;
Printer.BeginDoc;
src := TRectF.Create(0,0,bm.Width,bm.Height);
dst := TRectF.Create(0,0,Printer.PageWidth,Printer.PageHeight);
Printer.Canvas.DrawBitmap(bm, src, dst, 1.0);
Printer.EndDoc;
end;
bm.Free;
end; |
恒例によって例外処理は省いています。保存・ビルド(コンパイル)・実行をしてボタンをクリックします。
↓
例として CubePDF を選択します
↓
↓
という事で、画面のハードコピー印刷が出来ている事が分かります。なお、上記は画面全体にフィット描画するようにしていますが、画像の比率を維持したい場合には、それに応じたプログラミングを行う必要があります。
【リッチエディットの文章をそのまま印刷】
FireMonkey(FMX)には、リッチエディット(TRichEdit)コンポーネントはありませんので、VCLアプリケーションと同様の事は出来ません。文章入力編集関係では、メモ(TMemo)コンポーネントはありますが、メモに Print メソッドはありません。
但し、メモ内容を以下項目の手法を使って文章を印刷させる事は可能です。
【テキストをそのまま印刷】
ボタン Button2 を配置し、その OnClickイベントハンドラを下記のように記述します。
procedure TForm1.Button2Click(Sender: TObject);
var
pr : TextFile;
begin
AssignPrn(pr);
Rewrite(pr);
WriteLn(pr,'印刷テスト');
WriteLn(pr,'これは、印刷のテストです。');
CloseFile(pr);
end; |
保存・ビルド(コンパイル)・実行をしてボタンをクリックします。印刷そのものはちゃんと送信されている様子ですが、思ったように動作していないようです。
まずは、文字が(0,0)位置からちゃんと表示されていない、という事と、3頁になっているという事。プリンタ解像度や文字のフォントを事前に設定しても動作状況は変わりません。
ヘルプを見てみると・・・
FMX.Printer.AssignPrn |
procedure AssignPrn(var F: Text); |
現在選択されているプリンタに Text 変数を割り当てます。
AssignPrn を呼び出すと、Text 変数が現在のプリンタに割り当てられます。Write または Writeln の操作でこのファイル変数に出力すると、キャンバス プロパティのフォントを使ってプリンタに書き出されます。CR(復帰)が見つかるか、ページの最終行に Writeln が書き込みを行うと、新しいページが自動的に始まります。テキスト ファイルを閉じると、暗黙的に EndDoc メソッドが呼び出されます。
メモ: プリンタに対して一度に開くことができるのは、1 つの Text 変数だけです。2 つ目を開くと例外が発生します。 |
という訳で、「CR(復帰)が見つかる」と「新しいページ」になる、という仕様らしいですね。 Writelnルーチンは(DOS/Windowsでは)ご承知のように、最後に行末コード、つまり、復帰(CR=#13)+改行(LF=#10)、が送られる訳ですが、ヘルプでも、
System.Writeln |
procedure Writeln([var F: File]; [ P1; [ ..., PN] ]); |
テキスト ファイルに書き出し、行末マーカーを追加します。
WriteLn は、テキスト ファイル用に定義された Write プロシージャを拡張したものです。
ここで示す WriteLn プロシージャの構文は、WriteLn で指定できる引数の数が可変であることを示します。
Write を実行した後、WriteLn は、行末マーカー(行送りまたは復帰/改行)をファイルに書き出します。
F を省略すると、グローバル変数 Output が使用され、プロセス標準出力ファイルにアクセスします。GUI アプリケーションで Output を使用すると、特殊な問題が発生します。 |
と明記されている通りですが、
「WriteLn(pr,'印刷テスト');」で、
「印刷テスト」を印字して次頁へ、
「WriteLn(pr,'これは、印刷のテストです。');」で、
「これは、印刷のテストです。」を印字して次頁へ、
という事で、合計3頁の出力(最後の頁は何も無し)という状況になっている訳です。勿論これを
「Write(pr,'印刷テスト'+#13+#10);」とやっても同じ事です。
では、
復帰(CR=#13)しなければ次頁には行かないんだ、という事で、
Write(pr,'印刷テスト'+#10);
Write(pr,'これは、印刷のテストです。'+#10);
とやってみると、ダメですね、上記同様、3頁になります。
次に、ヘルプのほうが、復帰(CR=#13) と 改行(LF=#10) を間違えているのかもしれない、と想定して、
Write(pr,'印刷テスト'+#13);
Write(pr,'これは、印刷のテストです。'+#13);
と行なってみます。
すると、想定通り、次頁移動はせず、1頁内に文字が印字されました。
が・・・
次の行には移行せず、同じ行で何度も重なってしまう、という事になります。
以上、この手法は、全く使い物にならない、という事で終了です。
ヘルプ内容とも合ってませんし。
改行出来ない文書印刷なんて、ほぼ何の役にも立たないでしょう。
【プリンターオブジェクトのキャンバスに描画して印刷】
以上により、結局のところ、通常はこの手法に落ち着きそうです。
Printer.ActivePrinter.SelectDPI(〜,〜);
Printer.Canvas.Stroke.・・・
Printer.Canvas.Fill.・・・
Printer.Canvas.Font.・・・
Printer.BeginDoc;
Printer.Canvas.・・・・
Printer.NewPage;
Printer.Canvas.・・・・
Printer.EndDoc; |
のような手順で、Printer.Canvas 内に、これまで図形を描画したのと同じように、各図形描画メソッドを実行していけば良い、という事になります。
procedure TForm1.Button3Click(Sender: TObject);
var
px,py : Integer ;
begin
if (PrintDialog1.Execute) then begin
Printer.ActivePrinter.SelectDPI(600, 600);
Printer.Canvas.Stroke.Kind := TBrushKind.bkSolid;
Printer.Canvas.Stroke.Color := claBlack;
Printer.Canvas.Fill.Kind := TBrushKind.bkSolid;
Printer.Canvas.Fill.Color := claBlack;
Printer.Canvas.Font.Family := 'MS ゴシック';
px := Printer.PageWidth;
py := Printer.PageHeight;
Printer.BeginDoc;
with Printer.Canvas do begin
Stroke.Thickness := 50 ;
DrawRect(RectF(0,0,px,py),50,50,AllCorners,1.0);
Stroke.Color := claBlue ;
Stroke.Thickness := 25 ;
DrawLine(PointF(0,0),PointF(px,py),1.0);
DrawLine(PointF(px,0),PointF(0,py),1.0);
Font.Size := 50 ;
FillText(RectF(0,0,px,500),'印刷テスト',
False,1.0,[],TTextAlign.taCenter);
Font.Size := 25 ;
FillText(RectF(0,500,px,800),'これは印刷テストです。',
False,1.0,[],TTextAlign.taLeading);
end;
Printer.EndDoc;
end;
end; |
保存・ビルド(コンパイル)・実行をしてボタンをクリックし、CubePDFで印刷すると下図のようになります。
なお、フォントの大きさ Font.Size の値は、デバイス非依存ピクセル(DIP。1 論理インチが 96 DIP)の値であり、画面上のドット(ピクセル)値でも、従来のポイント値でもありません。VCLアプリケーションでは、Font に Height プロパティ(ドット(ピクセル)指定)がありましたが、FireMonkey(FMX)にはありませんので、自分で算出する必要があります。TextHeightメソッドを利用するのが簡単かもしれません。
【レポートツールを利用】
DelphiXE3 には、サードパーティー製の FastReport が実装されていますが、この版は、MacOS X に対応していません。この実装されている FastReport ツールは、パーソナル版のような感じで、配布ライセンスもかなり限定されている様子?なので、私的に利用するだけならともかく、インターネットでの配布や販売目的の場合には、このソフトメーカー(http://www.fast-report.com/)から購入する必要があると思われます。その場合には、MacOS X 対応版もあるようなので、購入する価値有りと判断すれば利用するのも良いと思われます。
※当方は未購入・動作未確認です。Macも所持しておりませんので。
という訳で、ここでは記載しません。
|
|
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Dehi入門編
>Delphi2010
>DelphiXE3
▲2014/06/05
2014/06/06
▼2014/06/07
シェアウェア
Script!World
データベース
|