Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2005年01月01日] [更新 2020年04月21日] Delphi サンプルプログラム集
   
拙作のコンポーネント類を使用したサンプル
T160_TRichEdit
を印刷プレビュー ( 頁内のみ )
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro
以下の拙作のコンポーネント類が必要
TplSetPrinter, TplPrev
T160_RichEdit1.zip [804 KB] 2020年04月21日版 (EXE 同梱)



  • 2005年11月13日 (他の履歴は省略)
  • RichEdit 印刷終了後に plPrev の Canvas のプロパティの設定が不正となる現象を修正




TRichEdit の内容を印刷プレビュー ( 頁内のみ )


メインフォームに配置した TRichEdit の内容を印刷プレビューする例です.ここでは,印刷する内容が 1 頁に収まるものと仮定しているので,逐次表示方式を使用しています.


図1
設計時画面
  • [プレビュー] ボタンを配置
  • 実行すると添付の RTF ファイルを読込んで表示
図2
実行
図3
プレビュー画面
  • 最初に説明文字列
  • 続いて RichEdit の中身
  • RichEdit の印刷の後に文字列

リスト1
TRichEdit のテキストを印刷プレビュー
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, plPrev, RichEdit, ComCtrls;

type
  TForm1 = class(TForm)
    plPrev1: TplPrev;
    btnPreview: TSpeedButton;
    RichEdit1: TRichEdit;
    procedure btnPreviewClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    procedure TestPrint;
    procedure RichEditPrint(X1, X2, Y1, Y2: Integer ; Rich: TRichEdit);
  public
    { Public 宣言 }
  end;

  function MiliToTwips(V: Integer): Integer;
  function TwipsToMili(V: Integer): Integer;

var
  Form1: TForm1;

implementation

type
  TPrev = class(TCustomplPrev);

{$R *.DFM}

//=============================================================================
//  TRichEdit (書式付きテキスト) の読込み
//  ワードの文書を RTF 形式で保存しておけば読込み可能
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
var
  AFilePath : String;
begin
  AFilePath := ExtractFilePath(Application.ExeName) + 'RichText.RTF';
  if FileExists(AFilePath) then begin
    RichEdit1.Lines.LoadFromFile(AFilePath);
    Self.Width  := 750;
    Self.Height := 500;
  end;
end;

//=============================================================================
//  [プレビュー] ボタンで印刷プレビュー開始
//  逐次表示方式
//=============================================================================
procedure TForm1.btnPreviewClick(Sender: TObject);
begin
  plPrev1.Title    := 'TRichEdit 印刷テスト';
  plPrev1.ProcName := TestPrint;
  plPrev1.ShowModal;
end;

//=============================================================================
//  印刷プレビュー(逐次表示方式)の印刷メソッド
//  逐次表示方式の ProcName プロパティで指定するメソッドには引数が使用できない
//  ここでは別の描画ルーチン作成して呼出している.
//=============================================================================
procedure TForm1.TestPrint;
var
  LPaperWidth    : Integer;
  LPaperHeight   : Integer; 
begin
  // 現在のプリンタの設定を TplSetPrinter コンポの値として取得
  plPrev1.plSetPrinter.GetPrinterInfo;
  // TplSetPrinter の情報を元にして用紙サイズ等のプロパティをセット
  TPrev(plPrev1).SetPaperInfo;  

  //  用紙サイズ (0.1 mm 単位) を取得しておく
  LPaperWidth  := plPrev1.PaperWidth;
  LPaperHeight := plPrev1.PaperHeight;


  plPrev1.FontHeight(60);
  plPrev1.TextOut(200, 200, 'リッチエディトの印刷例');
  RichEditPrint(300, LPaperWidth - 300, 450, LPaperHeight - 300, RichEdit1);
end;

//=============================================================================
//  TRichEdit の内容を描画
//  X1       : 描画領域の左端 X 座標値 (0.1 mm 単位)
//  X2       : 描画領域の右端 X 座標値 (0.1 mm 単位)
//  Y1       : 描画領域の上端 Y 座標値 (0.1 mm 単位)
//  Y2       : 描画領域の下端 Y 座標値 (0.1 mm 単位)
//  RichEdit : TRichEdit
//=============================================================================
procedure TForm1.RichEditPrint(X1, X2, Y1, Y2: Integer; Rich: TRichEdit);
var
  LRange   : TFormatRange;
  LSaveMap : Integer;
begin
  // Rangeを 0 (null) で埋める
  FillChar(LRange, SizeOf(TFormatRange), #0);

  // RichEdit1の設定
  // 出力先デバイスのハンドル
  LRange.hdc := plPrev1.Canvas.Handle;
  // 書式設定するデバイスのハンドル
  LRange.hdcTarget := LRange.hdc;

  // 描画領域の指定 (Twips 単位)
  LRange.rc.Left   := MiliToTwips(X1);
  LRange.rc.Right  := MiliToTwips(X2);
  LRange.rc.Top    := MiliToTwips(Y1);
  LRange.rc.Bottom := MiliToTwips(Y2);

  //用紙1頁のサイズ
  // 本当は用紙サイズを Twips で指定すべき?
  LRange.rcPage := LRange.rc;

  // テキストの最初から
  LRange.chrg.cpMin := 0;
  // 最後まで (-1 で自動計算)
  LRange.chrg.cpMax := -1;

  // マップモード MM_TEXT にして前のマップモードを LSaveMap に保存
  LSaveMap := SetMapMode(LRange.hdc, MM_TEXT);
  // バッファのフラッシュ}
  SendMessage(Rich.Handle, EM_FORMATRANGE, 0, 0);
  try

    SendMessage(Rich.Handle, EM_FORMATRANGE, 1, Longint(Addr(LRange)));
  finally
    // バッファのフラッシュ
    SendMessage(Rich.Handle, EM_FORMATRANGE, 0, 0);
    // マップモードを元に戻す
    // TplPrevでは 0.1 mmm 単位に戻すということ
    SetMapMode(LRange.hdc, LSaveMap);
    TPrev(plPrev1).ScaleInitialize(plPrev1.Canvas, False);
  end;

  // TRichEdit 印刷終了後のY座標値を TwipsToMilli で取得して印刷
  plPrev1.Canvas.Font.Size := 15;
  plPrev1.Canvas.TextOut(200, TwipsToMili(LRange.rc.Bottom), '次の行');
end;

//-----------------------------------------------------------------------------
//  0.1 mm 単位の座標値を Twips 値に変換する関数
//
//  参考
//  1 [inch] = 72 [pt]
//  1 [inch] = 1440 [Twips]
//  1 [pt]   = 20 [Twips]
//  1 [inch] = 25.4 [mm]
//  例 x mm を pt (ポイント) に換算する式
//     pt := x * 72 / 25.4
//
//  この計算式は TplPrev コンポ専用.一般的な換算はプリンタの解像度の考慮が必要
//-----------------------------------------------------------------------------
function MiliToTwips(V: Integer): Integer;
begin
  Result := Trunc(V * 1440.0 / 254.0);
end;

//-------------------------------------------------------------------------------
//  Twips 単位の値を 0.1 mm 単位の座標値に変換する関数
//  この計算式はTplPrevコンポ専用.一般的な換算はプリンタの解像度の考慮が必要
//-------------------------------------------------------------------------------
function TwipsToMili(V: Integer): Integer;
begin
  Result := Trunc(V * 254.0 / 1440)
end;

end.