ディスプレイの解像度以上の大きさを持つフォームを印刷するには?

解決


ino668  2009-05-10 00:38:44  No: 34328

Delphi初心者です。教えてください。

Delphi5を使っています。

ディスプレイの解像度(1280×800ピクセル)以上のサイズをもつFormをつくりました。
これを印刷してみました。

A4横置きの状態で、大きな楕円が印刷できるつもりでしたが、
Formの右や下の部分が印刷できませんでした。
どのようにすれば、Form全体を印刷することができるでしょうか。
なお、下がそのソースファイルです。(ImageとPrinterSetupDialogを配置しています。)

よろしくお願いします。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    PrinterSetupDialog1: TPrinterSetupDialog;
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Top:=0;
  Left:=0;
  Self.Width:=2900;
  Self.Height:=2100;
  Image1.Align:= alClient;
  Image1.Canvas.Ellipse(0,0, 2900,2100);
  PrinterSetupDialog1.execute;
  PrintScale:=poPrintToFit;
  Print;
end;

end.


Mr.XRAY  2009-05-10 02:11:30  No: 34329

Mr.XRAYです.

次のようなことだと思います.

1. Formは画面のサイズより大きいのは表示できない.
    画面サイズに縮小される
    
2. TImageはFormより大きいサイズを作成することができる
    そうしないと,大きい画像の処理ができない.    
    Formからはみ出る部分はスクロールすれば見える
    
3. 提示されたコードのPrintメソッドはFormを印刷している
    このとき,PrintScale:=poPrintToFit; となっているので,
    Form部分(画面サイズ)部分が印刷される
    
4. Imageはその画面サイズよりも大きい.

5. したがって,楕円全体は印刷できない.

画面に表示された時点で,楕円が全部見えてないと思いますが...
それにしても,何故OnCreateで処理しているのでしょうか.
そのほうが気になります.


Mr.XRAY  2009-05-10 02:26:46  No: 34330

Mr.XRAYです.

スミマセンね.質問の答えになっていませんでした.

>どのようにすれば、Form全体を印刷することができるでしょうか。

Form全体,この場合は横幅ですが,印刷できているはずです.


ino668  2009-05-10 05:14:02  No: 34331

Mr.XRAY さん

ご回答ありがとうございます。

さて、「それにしても,何故OnCreateで処理しているのでしょうか.そのほうが気になります.」とのこと。
OnCreateでなければならないことはなく、一連の流れ、描画、プリンタセットアップ、印刷がわかりやすいと思ったからです。他に特別な意味はありません。

「1. Formは画面のサイズより大きいのは表示できない.」とのこと。私の考え方が根本的に間違っているようですね。
現在、200×200ピクセルほどの楕円が入ったコンポーネントを水平方向に4つ、これを垂直方向に3列配置して、コンポーネントが合計12でひとつのFormをつくり、印刷してA4版一枚のプリント問題(子ども向け、時計の読み方)を作りたいと思っています。
今のままでも、一応プリント問題としての体裁は整っているのですが、画面をそのままダンプしたようで、楕円が滑らかではないので、解決策を考えました。
Form上のコンポーネントのサイズを拡大しておいて、
PrintScale:=poPrintToFit;
を使い、縮小印刷(?)をかければ、がたがたの楕円が滑らかになるのではないだろうか、と。
そのために、事前準備として、2900×2100の楕円をひとつ描き、これが滑らかに印刷できれば、前述も可能だろうと考えました。
ところが、印刷してみると満足できませんでした。
2週間ほどいろいろ試してみたけれで、どうにも分からなかったので、このページに質問させてもらいました。
スクロールすれば、隠れた部分を表示させることはできますが、見えない部分までは印刷できないようですね。残念です。

「Form全体,この場合は横幅ですが,印刷できているはずです.」とのこと。
今回試している環境を書いていませんでした。すみません。
何度も印刷しては紙がもったいないので、いま設定しているPrinterは、「Microsoft Office Document Image Writer」です。
「*.TIF」ファイルとして保存されたものをダブルクリックして開いてみています。しかし下半分も右半分も見えません。
OSはWindowsXP(SP3)です。
もしかすると、Mr.XRAYさんの環境は、PrinterにしてもDisplayにしても、私の環境の数倍上のものなのかもしれません。

早速の、ご回答感謝しております。


Mr.XRAY  2009-05-10 06:00:50  No: 34332

Mr.XRAYです.

どうもよく分からないのですが,Imageに描いたものを印刷したいということですか?
でしたら,TImageの内容を印刷するようにしたらどうでしょう.

>Mr.XRAYさんの環境は、PrinterにしてもDisplayにしても、
>私の環境の数倍上のものなのかもしれません。

多少は,です.
先程のコードをButton1クリックで実行してみてください.
ただし,Printメソッドを実行しないで.
Formがどう見えるかわかるハズです.
上下左右をよく見てください.Formが画面からはみ出ていないことがわかると思います.
それを見て,FormとImageの表示のされ方を理解するといいと思いますよ.

その見える部分,つまりForm全体が印刷されるわけです.


くらら  2009-05-10 07:43:13  No: 34333

直接質問の答えにはならないですが、
ino668さんはTPrinterの使い方について調べるときっと幸せになれますよ。


Mr.XRAY  2009-05-10 08:16:19  No: 34334

Mr.XRAYです.

以下は,1024×768で,前のコードを実行した時のスクリーンのキャプチャです.
デスクトップにForm全体が表示されています.
これが印刷されるわけですから,Formの枠を除いた楕円の一部が印刷されることになります.
つまり,Form全体は印刷されているんです.
なぜ楕円の一部かというと,前にレスしたように,
楕円は,TImageに描かれています.
TImageのサイズは,Formの表示サイズより大きいからです.

>私の環境の数倍上のものなのかもしれません。

という問題ではないことが理解していただけるでしょうか.
今回の場合,表示FormのサイズとImageのサイズは違うのです.
楕円の一部しか,印刷されていないから,Form全体が印刷されていない
というこではないのです.

http://mrxray.on.coocan.jp/Others/Images/013.gif


KHE00221  2009-05-10 09:25:27  No: 34335

TImage に Printメソッドはないけど

procedure TCustomForm.Print;

FormImage := GetFormImage;

FormImage := Image1.Picture.Bitmap;
にすれば出来そうだけど


ino668  2009-05-11 06:15:07  No: 34336

Mr.XRAYさん  重ねてのご回答ありがとうございます。

初心者のため、私が思い違いをしていたようです。

当方、初心者の癖に、コンポーネントを設計してみようとしているところです。
当初、TImageをもとにコンポーネントを設計しておりました。600×600ドットのコンポーネントです。
ところが、そのTImageClockをForm上にたくさん配置したところ、Formに現れないコンポーネントがでてきてしまいました。
しかし、それでも何とかFormを丸ごと印刷する方法があるのではないかと考えました。
ただ、自力ではできなかったので、このページに載せて、皆さんにお教え願ったのです。

Formとして現れていない部分は印刷できないのですね。
Formのサイズは、Imageのサイズによるものではなく、見えているのがFormなのですね。
キャプチャまで載せていただき、感謝しています。
なんとなくではありますが、分かりかけてきました。
理解が悪くてご迷惑をおかけします。
ご回答ありがとうございました。

くららさん、KHE00221さん、ご回答ありがとうございます。
TPrinterやPrintメソッドについて、すこしずつ勉強してみます。
ありがとうございました。


Mr.XRAY  2009-05-11 14:23:58  No: 34337

Mr.XRAYです.

あの〜,タイトルと文章からよく理解できないのですが,もしかして,

「図形をプリンタで印刷するにはどうしたらいいでしょうか」

という内容の質問に置き換えてもいいのでしょうか?
(沢山文章を書いたのに,たった1行にしてしまって申し訳ありません)
Imageコンポーネントの役割がいまいち理解できないでいるのですが...

もし,そうだとしたら,

新規プロジェクトにボタンを配置して,
以下のリストを試してみてください.
これは四角形を印刷するものですが,楕円でも命令を変更すれば可能です.
また,プロジェクトのunit.pasのusesのところに,Printersを追加する必要があります.
Delphi5でしたら,問題なく実行できるハズです.

procedure TForm1.Button1Click(Sender: TObject);
begin
    Printer.BeginDoc;
    try
      Printer.Canvas.Rectangle(360,360,2000,3000);
    finally
      Printer.EndDoc;
    end;
end;

このコードは,TImageは使用していません.
PrinterにもImageと同じく,Canvasがあります.
このプリンタのCanvasに直接出力するものです.

もし,意味が間違っていたらゴメンナサイ.


KHE00221  2009-05-12 04:12:11  No: 34338

ヤリタイコトハ・コンナコト?

 TSampleComponent = class(TGraphicControl)
  public
    procedure Print(Canvas: TCanvas; Scale: Integer = 100);
  end;

procedure TSampleComponent.Print(Canvas: TCanvas; Scale: Integer = 100);
var
    L,T,R,B: Integer;
begin
    L := Left * Scale div 100;
    T := Top * Scale div 100;
    R := (Left + 200) * Scale div 100;
    B := (Top + 200) * Scale div 100;
    Canvas.Ellipse(L,T,R,B);
    Exit;
end;

procedure TForm5.Button1Click(Sender: TObject);
var
    I: Integer;
    Printer: TPrinter;
begin
    //Printer := TPrinter.Create;
    //Printer.BeginDoc;
    for I:=0 to ComponentCount -1 do
    begin
      if Components[I] is TSampleComponent then
      begin
        //TSampleComponent(Components[I]).Print(Printer.Canvas);
        TSampleComponent(Components[I]).Print(Image1.Canvas,200);
      end;
    end;
    //Printer.EndDoc;
    //Printer.Free;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin

    Image1.Width := 1024;
    Image1.Height := 1024;

    SC1 := TSampleComponent.Create(Self);
    SC1.Width := 200;
    SC1.Height := 200;
    SC1.Left := 10;
    SC1.Top := 10;
    
    SC2 := TSampleComponent.Create(Self);
    SC2.Width := 200;
    SC2.Height := 200;
    SC2.Left := 220;
    SC2.Top := 10;
end;

procedure TForm5.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    SC2.Free;
    SC1.Free;
end;


ino668  2009-05-12 08:10:45  No: 34339

Mr.XRAYさん、KHE00221さん、何度もご回答感謝しています。
私の説明が悪いのと、Delphiについての勉強不足とで、大変なお世話をおかけしています。

さて、これ以上、要領を得ない説明を重ねては大変失礼ですので、
お恥ずかしいしだいではありますが、
私の自作のコンポーネント(作成途中です。フォントの表示サイズが不安定です)とそれを載せたProjectのソースをご覧ください。
(Delphi上級者からご覧になれば、まことにつたないものですが、その点、初心者ゆえのことと、どうぞご勘弁を願います。)

A4版横置きの一枚のプリントに、縦横600ドットの時計が4×3=12個表示される算数のプリント問題を作りたかったのです。
しかし、このprojectでできたのは、2つの時計しか表示されず、スクロールしたら他の時計は見えるけれど、やはり12個全部が見えるわけではない、予想とはずいぶん違ったものでした。

ごらんいただき、どうぞ、ご教授ください。

----------------------
unit ImageClock01;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls,math;

type
  TImageClock = class(TCustomControl)
  private
    { Private 宣言 }
    ri,ro: real;//目盛の内外径
    rl,rs: real;//長針、短針の長さの割合(width/2との比)
    FPenWidthBorderLine: byte;    //境界線の幅
    FPenWidthScaleNoon: byte;     //正午の線の幅
    FPenWidthScale1Minutes: byte; //1分毎の線の幅
    FPenWidthScale5Minutes: byte; //5分毎の線の幅
    FPenWidthLongHand: byte;      //長針の幅
    FPenWidthShortHand: byte;     //短針の幅
    ValueTextRect: TRect;//Position値の描画領域
    ValueText: string;   //Position値の内容
    TextHeight:byte;  //キャプションとPosition値のフォント高
    FFontSize: Byte; //フォントのサイズ
    FHours: integer;                //時
    FMinutes: integer;              //分
    FLength: integer;               //縦横の長さ
    FOnChange: TNotifyEvent;
    procedure SetHours(const Value: Integer);
    procedure SetMinutes(const Value: Integer);
    procedure SetLength(const Value: Integer);
    procedure SetFontSize(const Value: byte);    //フォントンサイズ設定
    procedure SetPenWidthBorderLine(const Value: byte);    //境界線の幅設定
    procedure SetPenWidthScaleNoon(const Value: byte);    //正午の線の幅設定
    procedure SetPenWidthScale1Minutes(const Value: byte);    //1分毎の線の幅設定
    procedure SetPenWidthScale5Minutes(const Value: byte);    //5分毎の線の幅設定
    procedure SetPenWidthLongHand(const Value: byte);    //長針の幅設定
    procedure SetPenWidthShortHand(const Value: byte);    //短針の幅設定
    function HalfAdjust(x: Extended): Longint; //四捨五入  protected
    { Protected 宣言 }
    procedure Change; virtual; // OnChangeイベントのイベントディスパッチャ
    procedure Paint; override;
  public
    { Public 宣言 }
    constructor Create(AOwner: TComponent); override;
  published
    { Published 宣言 }
    property Length: integer read FLength write SetLength default 600;//縦横の長さ
    property Hours: Integer read FHours write SetHours default 0; // 短針の位置(値)
    property Minutes: Integer read FMinutes write SetMinutes default 0; // 長針の位置(値)
    property FontSize: byte read FFontSize write SetFontSize default 48;// キャプションと「値」のフォントサイズ
    property PenWidthBorderLine: byte read FPenWidthBorderLine write SetPenWidthBorderLine default 3;
    property PenWidthScaleNoon: byte read FPenWidthScaleNoon write SetPenWidthScaleNoon default 11;
    property PenWidthScale1Minutes: byte read FPenWidthScale1Minutes write SetPenWidthScale1Minutes default 3;
    property PenWidthScale5Minutes: byte read FPenWidthScale5Minutes write SetPenWidthScale5Minutes default 5;
    property PenWidthLongHand: byte read FPenWidthLongHand write SetPenWidthLongHand default 17;
    property PenWidthShortHand: byte read FPenWidthShortHand write SetPenWidthShortHand default 25;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnClick;
//    property Font;
  end;

procedure Register;
                                                
implementation

procedure Register;
begin
  RegisterComponents('Samples', [TImageClock]);
end;

function TImageClock.HalfAdjust(x: Extended): Longint; //四捨五入
begin
  if x >= 0 then Result := Trunc(x + 0.5)
  else Result := Trunc(x - 0.5);
end;

constructor TImageClock.Create(AOwner: TComponent);// コンストラクタ
begin
  inherited Create(AOwner);
  rl:=80/100;
  rs:=55/100;
  Length:=600;
  FPenWidthBorderLine:=3;
  FPenWidthScaleNoon:=11;
  FPenWidthScale1Minutes:=3;
  FPenWidthScale5Minutes:=5;
  FPenWidthLongHand:=17;
  FPenWidthShortHand:=25;
  FHours:=0;
  FMinutes:=0;
  FFontSize:= 48;
  TextHeight:=HalfAdjust(Font.Size*4/3);
  // 描画にはチラツキを抑えるためダブルバッファ方式を使う
  DoubleBuffered := True;
end;

procedure TImageClock.Paint;
var i: integer;
begin
  inherited;
  Width:=Length;
  Height:=Length;
  ri:= round(length div 2 *95/100);
  ro:= round(length div 2);

  //境界線
  canvas.Pen.Width:=FPenWidthBorderLine;
  canvas.Pen.Color:= clBlack;
  canvas.Ellipse(canvas.Pen.Width div 2,canvas.Pen.Width div 2,
                        Length-canvas.Pen.Width div 2,
                        Length-canvas.Pen.Width div 2);
  //正午
  canvas.Pen.Width:=PenWidthScaleNoon;
  canvas.MoveTo(round(ro-ri*cos(0*2*pi/12+pi/2)),round(ro-ri*sin(0*2*pi/12+pi/2)));
  canvas.lineTo(round(ro-(ro-canvas.Pen.Width div 2)*cos(0*2*pi/12+pi/2)),
                       round(ro-(ro-canvas.Pen.Width div 2)*sin(0*2*pi/12+pi/2)));
  //1分毎の線
  canvas.Pen.Width:=PenWidthScale1Minutes;
  for i:=1 to 59 do
  begin
    canvas.MoveTo(round(ro-(ri+canvas.Pen.Width*2)*cos(i*2*pi/60+pi/2)),
                         round(ro-(ri+canvas.Pen.Width*2)*sin(i*2*pi/60+pi/2)));
    canvas.lineTo(round(ro-(ro-canvas.Pen.Width)*cos(i*2*pi/60+pi/2)),
                         round(ro-(ro-canvas.Pen.Width)*sin(i*2*pi/60+pi/2)));
  end;
  //5分毎の線
  canvas.Pen.Width:=PenWidthScale5Minutes;
  for i:=1 to 11 do
  begin
    canvas.MoveTo(round(ro-ri*cos(i*2*pi/12+pi/2)),round(ro-ri*sin(i*2*pi/12+pi/2)));
    canvas.lineTo(round(ro-(ro-canvas.Pen.Width)*cos(i*2*pi/12+pi/2)),
                         round(ro-(ro-canvas.Pen.Width)*sin(i*2*pi/12+pi/2)));
  end;

  // 文字盤の数値を描く
  for i:=1 to 12 do
  begin
    ValueText := inttostr(i);
    ValueTextRect := Rect(round(ro-(ri-HalfAdjust(Font.size/2*5/3))*cos(i*2*pi/12+pi/2))-Font.Size,
                          round(ro-(ri-HalfAdjust(Font.size/2*5/3))*sin(i*2*pi/12+pi/2))-HalfAdjust(Font.Size/3*2),
                          round(ro-(ri-HalfAdjust(Font.size/2*5/3))*cos(i*2*pi/12+pi/2))+Font.Size,
                          round(ro-(ri-HalfAdjust(Font.size/2*5/3))*sin(i*2*pi/12+pi/2))+HalfAdjust(Font.Size/3*2));//領域を設定する
    Canvas.Font.Color := clWindowText;
    Canvas.Font.Size:= FFontSize;
//    TextHeight:=HalfAdjust(FFontSize*4/3);
    DrawText(Canvas.Handle, PChar(ValueText), -1, ValueTextRect, DT_CENTER or DT_SINGLELINE);
  end;

//  randomize;
//  hours:= 0;//random(12);
//  minutes:= 0;//random(60);
  //短針
  canvas.Pen.Color:= clRed;
  canvas.Pen.Width:=PenWidthShortHand;
  canvas.MoveTo(round(ro),round(ro));
  canvas.LineTo(round((ro-rs*ro*cos((Fhours+Fminutes/60)*2*pi/12+pi/2))),
                       round((ro-rs*ro*sin((Fhours+Fminutes/60)*2*pi/12+pi/2))));
  //長針
  canvas.Pen.Color:= clBlack;
  canvas.Pen.Width:=PenWidthLongHand;
  canvas.MoveTo(round(ro),round(ro));
  canvas.LineTo(round((ro-rl*ro*cos(Fminutes*2*pi/60+pi/2))),
                       round((ro-rl*ro*sin(Fminutes*2*pi/60+pi/2))));

end;

procedure TImageClock.Change;// OnChangeイベントのイベントディスパッチャ
begin
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TImageClock.SetHours(const Value: Integer);// 短針の位置(値)を変更する
var
  NewHours: Integer;
begin
  NewHours := Value;
  if NewHours > 11 then NewHours := 11;
  if NewHours < 0 then NewHours := 0;
// 新しい値(位置)が前の値と異なるなら位置を更新しOnChangeイベントを起こす
  if FHours <> NewHours then
  begin
    FHours := NewHours;
    Refresh;
    Change;  // OnChangeイベント
  end;
end;

procedure TImageClock.SetMinutes(const Value: Integer);// 長針の位置(値)を変更する
var
  NewMinutes: Integer;
begin
  NewMinutes := Value;
  if NewMinutes > 59 then NewMinutes := 0;
  if NewMinutes < 0 then NewMinutes := 0;
// 新しい値(位置)が前の値と異なるなら位置を更新しOnChangeイベントを起こす
  if FMinutes <> NewMinutes then
  begin
    FMinutes := NewMinutes;
    Refresh;
    Change;  // OnChangeイベント
  end;
end;

procedure TImageClock.SetLength(const Value: Integer);// 縦横の長さを変更する
var
  NewLength: Integer;
begin
  NewLength := Value;
  if NewLength < 100 then NewLength := 100;
// 新しい値(位置)が前の値と異なるなら位置を更新しOnChangeイベントを起こす
  if FLength <> NewLength then
  begin
    FLength := NewLength;
    Width:=FLength;
    Height:= FLength;
    Refresh;
    Change;  // OnChangeイベント
  end;
end;

procedure TImageClock.SetFontSize(const Value: byte);// フォントサイズを変更する
var
  NewFontSize: Byte;
begin
  NewFontSize:= Value;
  if Font.Size <> NewFontSize then
  begin
    Font.Size:= NewFontSize;
    FFontSize:= NewFontSize;
    TextHeight:=HalfAdjust(FFontSize*4/3);

    Refresh;
    Change;
  end;
end;

procedure TImageClock.SetPenWidthBorderLine(const Value: byte);
var
  NewPenWidthBorderLine: byte;
begin
  NewPenWidthBorderLine:= Value;
  if PenWidthBorderLine <> NewPenWidthBorderLine then
  begin
    FPenWidthBorderLine:= NewPenWidthBorderLine;

    Refresh;
    Change;
  end;
end;

procedure TImageClock.SetPenWidthScaleNoon(const Value: byte);
var
  NewPenWidthScaleNoon: byte;
begin
  NewPenWidthScaleNoon:= Value;
  if PenWidthScaleNoon <> NewPenWidthScaleNoon then
  begin
    FPenWidthScaleNoon:= NewPenWidthScaleNoon;

    Refresh;
    Change;
  end;
end;

procedure TImageClock.SetPenWidthScale1Minutes(const Value: byte);
var
  NewPenWidthScale1Minutes: byte;
begin
  NewPenWidthScale1Minutes:= Value;
  if PenWidthScale1Minutes <> NewPenWidthScale1Minutes then
  begin
    FPenWidthScale1Minutes:= NewPenWidthScale1Minutes;

    Refresh;
    Change;
  end;
end;

procedure TImageClock.SetPenWidthScale5Minutes(const Value: byte);
var
  NewPenWidthScale5Minutes: byte;
begin
  NewPenWidthScale5Minutes:= Value;
  if PenWidthScale5Minutes <> NewPenWidthScale5Minutes then
  begin
    FPenWidthScale5Minutes:= NewPenWidthScale5Minutes;

    Refresh;
    Change;
  end;
end;

procedure TImageClock.SetPenWidthLongHand(const Value: byte);
var
  NewPenWidthLongHand: byte;
begin
  NewPenWidthLongHand:= Value;
  if PenWidthLongHand <> NewPenWidthLongHand then
  begin
    FPenWidthLongHand:= NewPenWidthLongHand;

    Refresh;
    Change;
  end;
end;

procedure TImageClock.SetPenWidthShortHand(const Value: byte);
var
  NewPenWidthShortHand: byte;
begin
  NewPenWidthShortHand:= Value;
  if PenWidthShortHand <> NewPenWidthShortHand then
  begin
    FPenWidthShortHand:= NewPenWidthShortHand;

    Refresh;
    Change;
  end;
end;

end.
--------------------------------------------------------------
unit UnitImageClock04;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ImageClock01, StdCtrls;

type
  TForm1 = class(TForm)
    ImageClock1: TImageClock;
    ImageClock2: TImageClock;
    ImageClock3: TImageClock;
    ImageClock4: TImageClock;
    ImageClock5: TImageClock;
    ImageClock6: TImageClock;
    ImageClock7: TImageClock;
    ImageClock8: TImageClock;
    ImageClock9: TImageClock;
    ImageClock10: TImageClock;
    ImageClock11: TImageClock;
    ImageClock12: TImageClock;
    PrinterSetupDialog1: TPrinterSetupDialog;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  width:=2700;
  height:=2220;

  WindowState:=wsMaximized;

  ImageClock1.Top:=120;
  ImageClock2.Top:=120;
  ImageClock3.Top:=120;
  ImageClock4.Top:=120;

  ImageClock5.Top:=920;
  ImageClock6.Top:=920;
  ImageClock7.Top:=920;
  ImageClock8.Top:=920;

  ImageClock9.Top:=1620;
  ImageClock10.Top:=1620;
  ImageClock11.Top:=1620;
  ImageClock12.Top:=1620;

  ImageClock1.left:=0;
  ImageClock5.left:=0;
  ImageClock9.left:=0;

  ImageClock2.left:=700;
  ImageClock6.left:=700;
  ImageClock10.left:=700;

  ImageClock3.left:=1400;
  ImageClock7.left:=1400;
  ImageClock11.left:=1400;

  ImageClock4.left:=2100;
  ImageClock8.left:=2100;
  ImageClock12.left:=2100;

  ImageClock1.FontSize:=48;
  ImageClock2.FontSize:=48;
  ImageClock3.FontSize:=48;
  ImageClock4.FontSize:=48;
  ImageClock5.FontSize:=48;
  ImageClock6.FontSize:=48;
  ImageClock7.FontSize:=48;
  ImageClock8.FontSize:=48;
  ImageClock9.FontSize:=48;
  ImageClock10.FontSize:=48;
  ImageClock11.FontSize:=48;
  ImageClock12.FontSize:=48;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  randomize;
  ImageClock1.Hours:= random(12);
  ImageClock1.Minutes:= random(60);
  ImageClock2.Hours:= random(12);
  ImageClock2.Minutes:= random(60);
  ImageClock3.Hours:= random(12);
  ImageClock3.Minutes:= random(60);
  ImageClock4.Hours:= random(12);
  ImageClock4.Minutes:= random(60);
  ImageClock5.Hours:= random(12);
  ImageClock5.Minutes:= random(60);
  ImageClock6.Hours:= random(12);
  ImageClock6.Minutes:= random(60);
  ImageClock7.Hours:= random(12);
  ImageClock7.Minutes:= random(60);
  ImageClock8.Hours:= random(12);
  ImageClock8.Minutes:= random(60);
  ImageClock9.Hours:= random(12);
  ImageClock9.Minutes:= random(60);
  ImageClock10.Hours:= random(12);
  ImageClock10.Minutes:= random(60);
  ImageClock11.Hours:= random(12);
  ImageClock11.Minutes:= random(60);
  ImageClock12.Hours:= random(12);
  ImageClock12.Minutes:= random(60);

  PrinterSetUpDialog1.Execute;
  Print;
end;

end.


Mr.XRAY  2009-05-12 16:19:36  No: 34340

Mr.XRAYです.
ご自分の世界に入っておられるようですが,

折角のレスがが生かされていない気がします.
問題は,ino668さんが作成されているコンポーネントの動作がどうのこうのと
いうものではないと思いますよ.

問題は,何故それが,何のために必要なのかということだと思います.
わざわざソースを示したということは,
あくまでもフォームを印刷することが目的なんですか?
でしたら,すでに結論は出ています.


Mr.XRAY  2009-05-12 17:15:41  No: 34341

まさか勘違いされるようなことはないと思いすが.

>何のために必要なのかということだと思います.

は,教材に必要だから,とかいう意味ではありません.念のため.
いままでの反応を見ていると,その度にその関係の記述があるので.


KHE00221  2009-05-13 04:57:45  No: 34342

TImageClock = class(TGraphicControl)
  private
  protected
    procedure DoPaint(Canvas: TCanvas; L,T,R,B: Integer);
  public
    procedure Paint;override;
    procedure Print(Canvas: TCanvas; Scale: Integer = 100);
  published
  end;

procedure TImageClock.Paint;
begin
    inherited Paint;
    DoPaint(Canvas,0,0,Width,Height);
end;

procedure TImageClock.Print(Canvas: TCanvas; Scale: Integer = 100);
var
    L,T,R,B: Integer;
begin
    L := Left * Scale div 100;
    T := Top * Scale div 100;
    R := (Left + Width) * Scale div 100;
    B := (Top + Height) * Scale div 100;
    DoPaint(Canvas,L,T,R,B);
end;

procedure TImageClock.DoPaint(Canvas: TCanvas; L,T,R,B: Integer);
begin
    Canvas.Ellipse(L,T,R,B);
end;

procedure Register;
begin
    RegisterComponents('KHE00221 - TGraphicControl', [TImageClock]);
end;

フォームのサイズを
  ClientWidth  := 297;
  ClientHeight := 210;
にして
適当に TImageClock を配置  Button クリックで出来る CanvasBitmap.BMP
を見ればわかる

procedure TForm5.Button1Click(Sender: TObject);
var
    I: Integer;
    Printer: TPrinter;
    CanvasBitmap: TBitmap;
    Scale: Integer;
begin
    CanvasBitmap := TBitmap.Create;
    CanvasBitmap.Width  := 1800;
    CanvasBitmap.Height := ClientHeight * (CanvasBitmap.Width div ClientWidth);
    Scale := (CanvasBitmap.Width div ClientWidth) * 100;

    //Printer := TPrinter.Create;
    //Printer.BeginDoc;
    //Scale := (Printer.PageWidth div ClientWidth) * 100;
    for I:=0 to ComponentCount -1 do
    begin
      if Components[I] is TImageClock then
      begin
        //TSampleComponent(Components[I]).Print(Printer.Canvas,1000);
        TImageClock(Components[I]).Print(CanvasBitmap.Canvas,Scale);
      end;
    end;
    //Printer.EndDoc;
    //Printer.Free;
    CanvasBitmap.SaveToFile('CanvasBitmap.BMP');
    CanvasBitmap.Free;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
    ClientWidth  := 297;
    ClientHeight := 210;
end;


KHE00221  2009-05-13 05:00:00  No: 34343

ClientWidth  := 297;
ClientHeight := 210;

は適当で良いけど比率は合わせるように

CanvasBitmap.Width  := 1800;
は Height を計算しているので 適当


Mr.XRAY  2009-05-13 15:13:49  No: 34344

Mr.XRAYです.

KHE00221さん,お疲れ様です.
そういうことだとは思うんですが.
おそらく,本人は,Printerへの出力を,Printメソッドだけで理解しているのでは
ないかと.
もちろん,既にレスがあり,

TPrinterやPrintメソッドについて、すこしずつ勉強してみます。

とありますが.

Formのスクロールだと,Formのデザインがよくないので,
TScrollBoxを配置して,その上にコンポをおいてテストしてみました.
私はここらへんで退散いたしますです.
後はよろしく.(^^


ino668  2009-05-14 14:47:56  No: 34345

Mr.XRAYさん、KHE00221さん

とんちんかんな質問や思い込みでご迷惑をおかけしているにもかかわらず、
懇切丁寧なご回答、感謝します。

さて、飛び込みで仕事が入ってしまいました。
できるだけ早く成果をあげたいとあせっていますが、申し訳ありません。3、4日後、改めて取り組みたいと思います。
ごめんなさい。


ino668  2009-05-28 14:52:24  No: 34346

ino668です。

printer.Canvasに直接、描画・印刷すればできそうだということがわかりました。

Formに現れていない部分を印刷することはできない。
ならば、別の方法に乗り換えるべきである。
ご指摘いただきながら、それができずにいました。

Mr.XRAYさん、KHE00221さん、くららさん
私の理解が遅く、
さらに要領を得ない質問を掲示したにもかかわらず、
長い間お付き合いいただき、感謝しています。
ありがとうございました。

以下が、そのソースです。
------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs,
  printers, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    PrinterSetupDialog1: TPrinterSetupDialog;
    ButtonPrintPageSize: TButton;
    ButtonPrintScreenSize: TButton;
    ButtonPrintFormSize: TButton;
    procedure ButtonPrintPageSizeClick(Sender: TObject);
    procedure ButtonPrintScreenSizeClick(Sender: TObject);
    procedure ButtonPrintFormSizeClick(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ButtonPrintPageSizeClick(Sender: TObject);
var s: string;
begin
//プリンタのページサイズで描画・印刷
  printer.Orientation:= poPortrait;
  s:= 'Orientation: '+ intToStr( ord( Printer.Orientation))+ chr($0d);
  s:= s+ 'Page Height: '+ intToStr( Printer.PageHeight)+ chr($0d);
  s:= s+ 'Page Width: '+ intToStr( Printer.PageWidth)+ chr($0d);
  Printer.Orientation:= poLandscape;
  s:= s+ 'Orientation: '+ intToStr( ord( Printer.Orientation))+ chr($0d);
  s:= s+ 'Page Height: '+ intToStr( Printer.PageHeight)+ chr($0d);
  s:= s+ 'Page Width: '+ intToStr( Printer.PageWidth)+ chr($0d)+ chr($0a);

  Label1.caption:=s;

  printer.Orientation:= poLandscape;
  PrinterSetUpDialog1.Execute;
  printer.BeginDoc;
  printer.Canvas.Rectangle(0,0,Printer.PageWidth-1,Printer.PageHeight-1);
  Printer.canvas.Ellipse(0,0,Printer.PageWidth-1,Printer.PageHeight-1);
  Printer.Canvas.TextOut(0,0, s);
  Printer.EndDoc;
end;

procedure TForm1.ButtonPrintScreenSizeClick(Sender: TObject);
var s: string;
begin
//スクリーンサイズで描画・印刷
  s:= 'Screen Height: '+ intToStr( Screen.Height)+ chr($0a);
  s:= s+ 'Screen Width: '+ intToStr( Screen.Width)+ chr($0a)+ chr($0a);

  Label1.caption:=s;

  printer.Orientation:= poLandscape;
  PrinterSetUpDialog1.Execute;
  printer.BeginDoc;
  printer.Canvas.Rectangle(0,0,Screen.Width-1,Screen.Height-1);
  Printer.canvas.Ellipse(0,0,Screen.Width-1,Screen.Height-1);
  Printer.Canvas.TextOut(0,0, s);
  Printer.EndDoc;
end;

procedure TForm1.ButtonPrintFormSizeClick(Sender: TObject);
var s: string;
begin
//最大化したフォームサイズで描画・印刷
  Self.WindowState:=wsMaximized;
  s:= 'Form Height: '+ intToStr( Self.Height)+ chr($0a);
  s:= s+ 'Form Width: '+ intToStr( Self.Width)+ chr($0a)+ chr($0a);

  Label1.caption:=s;

  printer.Orientation:= poLandscape;
  PrinterSetUpDialog1.Execute;
  printer.BeginDoc;
  printer.Canvas.Rectangle(0,0,Self.Width-1,Self.Height-1);
  Printer.canvas.Ellipse(0,0,Self.Width-1,Self.Height-1);
  Printer.Canvas.TextOut(0,0, s);
  Printer.EndDoc;
end;

end.
-----------------------------------------------------------

以上、本当にお世話になりました。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加