Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2000年12月12日] [更新 2016年04月19日] 印刷プレビュー制御コンポーネント
   
印刷プレビュー制御コンポーネント
テストプログラム EnterFormRealTime
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro







入力画面を兼ねたプレビューフォーム ( 逐次表示方式 )


逐次表示方式の特性を利用し,フォームにデータの入力用のコントロールを配置して帳票類入力を行います.元の帳票イメージはプレビューするだけで印刷はしません.このテストプログラムでは,テストを兼ねて帳票原稿はワードで作成したメタファイルを使用していますが,面倒でもコード書いた方が速度は速くなります.


図1
メインフォーム
図2
継承フォームの設計画面
図3
実行画面

リスト1
メインフォーム側のコード
unit MainFormUnit;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  EnterFormUnit;

{$R *.DFM}

//=============================================================================
//  プレビューフォームを表示
//  このフォームは意識的に作成したプレビューの継承フォーム 
//  [プロジェクト][オプション]で自動生成から外しておく
//  実際の描画コードは継承プレビューフォームのユニットに書いてある
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  EnterForm := TEnterForm.Create(Self);
  try
    EnterForm.ShowModal;
  finally
    //FreeAndNil(EnterForm)でも可
    EnterForm.Release;
    EnterForm := nil;
  end;
end;

end.


リスト2
プレビューフォームのコード
unit EnterFormUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs,PLPREVFRM, Menus, ExtCtrls, ComCtrls, Buttons,
  plPrev, StdCtrls, ToolWin;

type
  TEnterForm = class(TplPrevForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Panel1: TPanel;
    Panel2: TPanel;
    GroupBox1: TGroupBox;
    Panel3: TPanel;
    Panel4: TPanel;
    Panel5: TPanel;
    Panel6: TPanel;
    Panel7: TPanel;
    Panel8: TPanel;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    plPrev1: TplPrev;
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure plPrev1FormShow(Sender: TObject);
    procedure plPrev1FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Edit1Change(Sender: TObject);
  private
    { Private 宣言 }
    MyPaperWidth: Integer;
    MyPaperHeight: Integer;
    procedure DrawTest;
  public
    { Public 宣言 }
  end;

var
  EnterForm: TEnterForm;

implementation

uses Printers;

{$R *.DFM}

//=============================================================================
//  TplPrevのOnFormShowイベント
//  ここで各データの初期値を設定
//  この初期化がなければ表示は速い
//=============================================================================
procedure TEnterForm.plPrev1FormShow(Sender: TObject);
begin
  plPrev1.Title := '郵便払込取扱票入力画面';

  //現実のアプリではデータベース等からの読出しに相当
  Edit1.Text := '31500';
  Edit2.Text := 'ボーランドジャパン株式会社';
  Edit3.Text := '151-8533';
  Edit4.Text := '東京都渋谷区笹塚1-50-1';
  Edit5.Text := '笹塚NAビルディング';
  Edit6.Text := '□□□□ソフト株式会社';
  Edit7.Text := '□□ □';
  Edit8.Text := '03-1234-5678';

  //払込用紙の大きさは横180.0mm縦115.0mm
  MyPaperWidth  := 1800;
  MyPaperHeight := 1150;

  //用紙の表示サイズと同じユーザ定義用紙を作成
  plPrev1.plSetPrinter.SetUserPaper ('払込用紙', MyPaperWidth, MyPaperHeight);

  //表示の幅と高さを用紙と同じにする
  plPrev1.ViewWidth  := MyPaperWidth;
  plPrev1.ViewHeight := MyPaperHeight;

  //描画ルーチン指定
  plPrev1.ProcName := DrawTest;
  //入力開始位置にフォーカスをセット
  ActiveControl := Edit1;
  //このフォーム自身を表示するのでShowModalメソッドは不要
end;

//=============================================================================
//  TplPrevのOnFormCloseイベント
//  フォームを閉じる時にはユーザ定義用紙を削除しておく
//=============================================================================
procedure TEnterForm.plPrev1FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  plPrev1.plSetPrinter.DeleteUserPaper('払込用紙');
end;

//-----------------------------------------------------------------------------
//  実際の描画コード
//  逐次方式のプレビューなのでEditへの入力内容に応じて描画を変更
//  ここでは帳票台紙の画像を読込んで表示しているが,面倒でも描画コードをゴリゴ
//  リ書いた方が描画速度は速い.
//-----------------------------------------------------------------------------
procedure TEnterForm.DrawTest;
var
  LLeft   : Integer;
  LRight  : Integer;
  LTop    : Integer;
  LBottom : Integer;
  LXRatio : Extended;
  LYRatio : Extended;
begin
  //数値は払込票の大きさと印刷位置の設定用
  //読込んで使用するメタファイルに応じて調整する
  //ちょっと作り方が悪かったので...
  LLeft   := -41;
  LTop    := 15;
  LXRatio := 1.0213;
  LYRatio := 0.9896;
  LRight  := LLeft + Round(MyPaperWidth * LXRatio);
  LBottom := LTop+Round(MyPaperHeight * LYRatio);

  //郵便払込票のメタファイルをディスクから読出して表示
  //プリンタには背景の帳票を出力しない,逐次方式のみ利用可能
  if not(plPrev1.Printing) then begin
    plPrev1.StretchDrawPict(LLeft, LRight, LTop, LBottom, True, 'HaraikomiPaper.emf');
  end;

  with plPrev1 do begin
    //金額
    FontName('MS Pゴシック');
    FontSize(14);
    TextRectFit( 800, 1200, 160, 240, 8, '\' + Edit1.Text);
    TextRectFit(1350, 1760, 480, 560, 8, '\' + Edit1.Text);

    //加入者名
    FontName('MS 明朝');
    FontSize(12);
    TextOutCC(425, 290, Edit2.Text);

    //右側の加入者名
    FontSize(8);
    TextOutLC(1370, 400, Edit2.Text);

    //通信欄.ここでは固定文字列としている
    FontSize(12);
    FontName('MS 明朝');
    TextOutLC(150,500, 'Delphi6 入門講座(2日間)');
    TextOutLC(150,550, '講習会受講料');

    //払込人住所氏名
    FontSize(9);
    TextOutLC(220, 725, Edit3.Text);
    FontSize(10);
    TextOutLC(120, 770, Edit4.Text + Edit5.Text);
    TextOutLC(120, 810, Edit6.Text);
    TextOutLC(250, 850, Edit7.Text);

    //右側の払込人住所氏名
    FontSize(8);
    TextOutLC(1360, 600, Edit4.Text);
    TextOutLC(1360, 630, Edit5.Text);
    TextOutLC(1360, 660, Edit6.Text);
    TextOutLC(1450, 710, Edit7.Text);

    //電話番号
    FontSize(9);
    TextOutLC(585, 885, Edit8.Text);
  end;
end;

//=============================================================================
//  各TEditのOnKeyPressイベント処理
//  [Enter]はKeyDownで処理するので0に
//=============================================================================
procedure TEnterForm.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (Ord(Key) = VK_RETURN) then begin
    Key := Chr(0);
  end;
end;

//=============================================================================
//  各TEditのOnKeyDownイベント処理
//  [Enger]で次の入力コントロールへ移動
//=============================================================================
procedure TEnterForm.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then begin
    //最後の入力項目が終了したら最初の入力コントロールに移動
    if (Sender = Edit8) then begin
      Edit1.SetFocus;
    end else begin
      //次のタブ順序のコントロールにフォーカスを移動
      SelectNext(ActiveControl, True, True);
    end;
    Key := 0;
  end;
end;

//=============================================================================
//  各TEditのOnChangeイベント処理
//  リアルタイムで変更をプレビューに反映させる
//=============================================================================
procedure TEnterForm.Edit1Change(Sender: TObject);
begin
  plPrev1.Display(plPrev1.PageNumber);
end;

end.




次のタブ順のコントロールに移動


上のテストプログラムでは,[Enter] キーで次の入力コントロールにフォーカスを移動しています.
この動作に,SelectNext 関数を使用していますが,この引数を変更すると,タブ順で 1 つ前のコントールにフォーカス移動できます.


リスト3
次のタブ順のコントロールに移動
//=============================================================================
//  タブ順で次のTWindControlにフォーカス移動
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  SelectNext(ActiveControl as TWinControl, True, True);
end;

//=============================================================================
//  タブ順で1つ舞うのTWindControlにフォーカス移動
//  例えば[Shift]キーを押して動作させるようにする
//=============================================================================
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  SelectNext(ActiveControl as TWinControl, False, True);
end;