Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2009年03月28日] [更新 2016年11月11日] Delphi サンプルプログラム集
013_プリンタのプロパティ設定
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro
013_SetPrinterProperty.zip [3,796 KB] 2016年11月11日版 (EXE 同梱)



  • 2012年01月08日
  • 全体的に記事の構成を見直し、サンプルコードも修正
  • 2016年11月11日
  • TPrintDialog ダイアログ等によるプロパティの設定サンプルを追加




プリンタのプロパティ設定


印刷の時に使用するプリンタと用紙関係のプロパティの設定のサンプルです。ダイアログを表示して設定する方法と、ダイアログを表示しないで、コード設定する両方を掲載しています。

印刷は、TPrinter オブジェクトのインスタンスである Printer のメソッドやプロパティを使用します。Printer インスタンスは自動で生成されます。create する必要はありません。
プリンタを指定しない場合は、[通常使用するプリンタ] が対象のプリンタになります。



現在アクティブで操作対象のプリンタの名前は、以下のコードで取得できます。
TPrinter のメソッドやプロパティは、このプリンタに対する操作となります。


uses
  Printers;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  LPrinerName : string;
begin
  LPrinerName := Printer.Printers[Printer.PrinterIndex];
  ShowMessage(LPrinerName);
end;


また、[通常使用するプリンタ] は以下のコードで設定して取得できます。
この設定は、TPrinter オブジェクトで使用するプリンタを [通常使用するプリンタ] に設定するものであって、システムの [通常使用するプリンタ] を変更するわけではありません。


procedure TForm1.Button1Click(Sender: TObject);
var
  LPrinerName : string;
begin
  Printer.PrinterIndex := -1;
  LPrinerName := Printer.Printers[Printer.PrinterIndex];
  ShowMessage(IntToStr(Printer.PrinterIndex) + '  ' + LPrinerName);
end;


[備考]
印刷の強制終了用の TPrinter.Abort メソッドがあります。印刷の描画データは印刷スプールに送られて印刷されます。Abort メソッドは、印刷スプールに格納されたジョブに対しては無効です。
強制的に印刷を終了したい場合は、Abort メソッドと同時に、印刷ジョブをスプールから削除する方法を検討してみてください。





01_TPrinter のプロパティによる設定と TPrinterCapabilities


TPrinter には印刷部数と印刷の用紙の向きの設定のプロパティがあります。それらを設定するサンプルプログラムです。設定内容を実際に印刷して確認できるようにしています。
TPrinterCapabilities を使用すると、現在のプリンタが [印刷部数], [用紙の向き (印刷の方向)], [部単位の印刷] をサポートしているか確認できます。その確認のコードも追加しています。ただし、TPrinter には [部単位での印刷] を設定するプロパティはありません。


図1
実行時画面
  • サポートしている機能にチェックが入る
図2
印刷結果の例
  • 印刷時の解像度 (DPI) によって異なる

リスト1
TPrinter オブジェクトのプロパティでプリンタのプロパティを設定
TPrinterCapabilities で設定可能かを確認してから設定
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    FDevice     : array[0..MAX_PATH - 1] of Char;
    fDriver     : array[0..MAX_PATH - 1] of Char;
    FPort       : array[0..MAX_PATH - 1] of Char;
    FDeviceMode : THandle;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Printers;

{$R *.dfm}

//=============================================================================
//  印刷のプロパティの設定
//  Printerオブジェクトのプロパティを使用する例
//  Printer.Capabilitiesで使用可能な機能をチェック
//
//  PrinterはTPrinterオブジェクトのインスタンス(Createは必要ない)
//  usesにPrintersが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LCapabilities : TPrinterCapabilities;
begin
  //現在のプリンタの情報を取得
  //これを実行しないとPrinter.Capabilitiesの値は取得できない
  Printer.GetPrinter(FDevice, fDriver, FPort, FDeviceMode);

  //現在のプリンタの機能を調べる
  LCapabilities := Printer.Capabilities;

  //印刷部数の設定が可能なら設定する
  if pcCopies in LCapabilities then begin
    CheckBox1.Checked := True;
    Printer.Copies := 2;
  end;
  //用紙の向きの設定が可能なら設定する
  if pcOrientation in LCapabilities then begin
    CheckBox2.Checked := True;
    Printer.Orientation := poPortrait;
  end;
  //部単位の印刷が可能な場合
  //Printerのプロパティには部単位の値はない
  //印刷ダイアログを表示した後、ダイアログのプロパティとして取得可能
  if pcCollation in LCapabilities then begin
    CheckBox3.Checked := True;
  end;


  //印刷開始
  Printer.Title := '印刷テスト';
  Printer.BeginDoc;
  try
    Printer.Canvas.Brush.Style := bsClear;
    Printer.Canvas.Font.Size := 50;
    Printer.Canvas.TextOut(360, 360, 'A4 印刷方向 縦');
    Printer.Canvas.Rectangle(360, 360, 1080, 1800);
  finally
    Printer.EndDoc;
  end;
end;

end.




02_TPrintDialog ダイアログによる設定


TPrintDialog ダイアログを表示して設定するサンプルです。
TPrintDialog ダイアログでは、[印刷開始ページ], [印刷の終了ページ], [印刷部数], [部単位での印刷] プロパティが取得できます。
[プロパティ] ボタンをクリックすれば、プリンタドライバが提供しているダイアログを表示してプロパティを設定できます。



図3
印刷設定ダイアログ

リスト2
TPrintDialog ダイアログで印刷のプロパティを設定
unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

uses
  Printers;

{$R *.dfm}

//=============================================================================
//  印刷のプロパティの設定
//  TPrintDialogダイアログを使用する例
//
//  usesにPrintersが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LPageNo : Integer;
  LText   : string;
begin
  if not PrintDialog1.Execute then exit;


  //ダイアログで設定した内容で印刷開始
  Printer.Title := '印刷テスト';
  Printer.BeginDoc;
  try
    for LPageNo := 1 to 3 do begin
      LText := '印刷ページ : ' + IntTostr(LPageNo);
      Printer.Canvas.Brush.Style := bsClear;
      Printer.Canvas.Font.Size   := 30;
      Printer.Canvas.TextOut(360, 360, LText);
      Printer.Canvas.Rectangle(360, 360, 1080, 1800);

      //指定ページまで印刷したら終了
      if LPageNo = 3 then break;
      //指定ページ内の場合は改ページ
      Printer.NewPage;
     end;
  finally
    Printer.EndDoc;
  end;
end;

end.




03_TPrinterSetupDialog ダイアログによる設定


TPrinterSetupDialog ダイアログを表示して設定するサンプルです。
TPrinterSetupDialog では主に用紙関係の設定を行います。設定した用紙関係の値は、TPrinter のプロパティとして取得できます。
[プロパティ] ボタンをクリックすれば、プリンタドライバが提供しているダイアログを表示してプロパティを設定できます。


図4
プリンタの設定ダイアログ
  • 設定した用紙関係のプロパティは、TPrinter のプロパティとして取得できる

リスト3
TPrinterSetupDialog ダイアログで用紙関係の設定
unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

uses
  Printers;

{$R *.dfm}

//=============================================================================
//  印刷のプロパティの設定
//  TPrinterSetupDialogダイアログを使用する例
//
//  usesにPrintersが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if not PrinterSetupDialog1.Execute then exit;


  //ダイアログで設定した内容で印刷開始
  Printer.Title := '印刷テスト';
  Printer.BeginDoc;
  try
    Printer.Canvas.Brush.Style := bsClear;
    Printer.Canvas.Font.Size   := 50;
    Printer.Canvas.TextOut(360, 360, '印刷テスト');
    Printer.Canvas.Rectangle(360, 360, 1080, 1800);
  finally
    Printer.EndDoc;
  end;
end;

end.




04_プロパティのダイアログで設定  -  DocumentProperties


プリンタのプロパティのダイアログを表示して設定する方法です。
このダイアログは、TPrintDialog ダイアログ、TPrinterSetupDialog ダイアログで、[プロパティ] ボタンをクリックした時に表示されるダイアログです。
このダイアログを表示すれば、印刷する前にプロパティの設定を確認することができます。このダイアログは、DocumentProperties 関数を使用して表示しています。


図5
プロパティのダイアログ
  • コンボボックスはプリンタ選択用
  • ダイアログはプリンタドライバによって異なる

リスト4
DocumentProperties 関数でプリンタのプロパティのダイアログを表示して設定
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Select(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    FDevice     : array[0..MAX_PATH - 1] of Char;
    FDriver     : array[0..MAX_PATH - 1] of Char;
    FPort       : array[0..MAX_PATH - 1] of Char;
    FDeviceMode : THandle;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Printers,
  WinSpool;

{$R *.dfm}

//=============================================================================
//  プリンタのリストをコンボボックスにセット
//  PRINTER_INFO_4構造体から取得した方が正確
//  Printerオブジェクトから取得したプリンタ名と順番や内容が異なる場合がある
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ComboBox1.Items.Clear;

  ComboBox1.Items.Assign(Printer.Printers);
  ComboBox1.ItemIndex := Printer.PrinterIndex;

  //選択したプリンタを初期化
  //ここでは通常使うプリンタとなっている
  ComboBox1Select(nil);
end;

//=============================================================================
//  プリンタを変更したらそのプリンタのデフォルト値で初期化
//  前のプリンタの設定値を引き継ぐことは原則的にできない
//=============================================================================
procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  //選択したプリンタを現在のプリンタとする
  Printer.PrinterIndex := ComboBox1.ItemIndex;

  //ここで取得するFDeviceMode1には、変更前のプリンタの情報が格納されている
  //その他の値は現在(変更後)のプリンタの情報となっている
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);
  //FDeviceMode初期化
  Printer.SetPrinter(FDevice, FDriver, FPort, 0);
  //FDeviceModeが新しいプリンタドライバの値となる
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

//=============================================================================
//  選択したプリンタのプロパティダイアログを表示して設定
//  DocumentProperties関数を実行
//
//  該当プリンタドライバ専用の設定ダイアログがある場合は、そのプロパティダイア
//  ログを表示、それ以外は[ドキュメントのプロパティ]ダイアログを表示
//
//  FDevice, FDriver, FPort, FDeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LDevMode  : PDeviceMode;
  LMode     : Cardinal;
  LhPrinter : THandle;
begin
  //FDeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
  LDevMode := GlobalLock(FDeviceMode);

  try
    //対象のプリンタのハンドルを取得
    if WinSpool.OpenPrinter(FDevice, LhPrinter, nil) then begin
      try
        //このLModeの値によって、ダイアログ表示かプロパティの設定かが決まる
        LMode := DM_IN_PROMPT or DM_OUT_BUFFER or DM_IN_BUFFER;
        DocumentProperties(Handle, LhPrinter, FDevice, LDevMode^, LDevMode^, LMode);
      finally
        //Openしたら閉じる
        ClosePrinter(LhPrinter);
      end;
    end;
  finally
    //ロック解除
    GlobalUnlock(FDeviceMode);
  end;
  //なくても設定は行われるが、次回のGetPrinter実行時に反映されない場合がある
  Printer.SetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

end.




05_プロパティのダイアログで設定  - AdvancedDocumentProperties


同じくプリンタのプロパティダイアログを表示してプロパティを設定する例です。
本サンプルは、AdvancedDocumentProperties 関数を使用しています。この関数では、Windows が提供しているプリンタドライバの場合、下図のように [詳細設定] のダイアログを表示します。それ以外のプリンタドライバの場合は、プリンタドライバによって異なります。


図6
プロパティのダイアログ
  • コンボボックスはプリンタ選択用
  • Windows が提供しているドライバの場合は [詳細設定]
  • メーカ独自のドライバの場合はプリンタドライバによってダイアログは異なる

リスト5
AdvancedDocumentProperties 関数でプリンタのプロパティのダイアログを表示して設定
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Select(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    FDevice     : array[0..MAX_PATH - 1] of Char;
    FDriver     : array[0..MAX_PATH - 1] of Char;
    FPort       : array[0..MAX_PATH - 1] of Char;
    FDeviceMode : THandle;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Printers,
  WinSpool;

{$R *.dfm}

//=============================================================================
//  プリンタのリストをコンボボックスにセット
//  PRINTER_INFO_4構造体から取得した方が正確
//  Printerオブジェクトから取得したプリンタ名と順番や内容が異なる場合がある
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ComboBox1.Items.Clear;

  ComboBox1.Items.Assign(Printer.Printers);
  ComboBox1.ItemIndex := Printer.PrinterIndex;

  //選択したプリンタを初期化
  //ここでは通常使うプリンタとなっている
  ComboBox1Select(nil);
end;

//=============================================================================
//  プリンタを変更したらそのプリンタのデフォルト値で初期化
//  前のプリンタの設定値を引き継ぐことは原則的にできない
//=============================================================================
procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  //選択したプリンタを現在のプリンタとする
  Printer.PrinterIndex := ComboBox1.ItemIndex;

  //ここで取得するFDeviceModeには、変更前のプリンタの情報が格納されている
  //その他の値は現在(変更後)のプリンタの情報となっている
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);
  //FDeviceMode初期化
  Printer.SetPrinter(FDevice, FDriver, FPort, 0);
  //FDeviceModeが新しいプリンタドライバの値となる
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

//=============================================================================
//  選択したプリンタのプロパティダイアログを表示して設定
//  関数AdvancedDocumentPropertiesを使用した例
//
//  該当プリンタドライバ専用の設定ダイアログがある場合は、そのプロパティダイア
//  ログを表示、それ以外は[ドキュメントのプロパティ]ダイアログで[詳細設定]をク
//  リックした時に表示されるダイアログを表示する
//
//  FDevice, FDriver, FPort, FDeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LDevMode  : PDeviceMode;
  LhPrinter : THandle;
begin
  //FDeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
  LDevMode := GlobalLock(FDeviceMode);

  try
    //対象のプリンタのハンドルを取得
    if WinSpool.OpenPrinter(FDevice, LhPrinter, nil) then begin
      try
        AdvancedDocumentProperties(Handle,
                                   LhPrinter,
                                   FDevice,
                                   LDevMode,
                                   LDevMode);
      finally
        //Openしたら閉じる
        ClosePrinter(LhPrinter);
      end;
    end;
  finally
    //ロック解除
    GlobalUnlock(FDeviceMode);
  end;
  //なくても設定は行われるが、次回のGetPrinter実行時に反映されない場合がある
  Printer.SetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

end.




06_TPageSetupDialog ダイアログによる設定


印刷に関係したダイアログとして TPageSetupDialog ダイアログがあります。このダイアログでも、用紙サイズ、給紙方法 (トレイ)、印刷の向きが設定できます。
このダイアログの [余白] の設定は、プログラマが自由に利用できる値で、プリンタや用紙関係がこの値で設定されるわけではありません。

設定の確認に [プロパティ] のダイアログを表示するようにしています。
上のサンプルでは、プロパティのダイアログを表示する前に、TComboBox で対象のプリンタを選択しています。その時に TPrinter.GetPrinter で DEVMODE 構造体を取得していますが、本サンプルでは、ダイアログの表示前にこのコードを最初に実行しています。TPrinter.GetPrinter を実行しないとプリンタの情報は取得できません。



図7
ページ設定ダイアログ
  • 余白はユーザ定義の値として利用するための値

リスト6
ページ設定ダイアログを表示する
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    PageSetupDialog1: TPageSetupDialog;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    FDevice     : array[0..MAX_PATH - 1] of Char;
    FDriver     : array[0..MAX_PATH - 1] of Char;
    FPort       : array[0..MAX_PATH - 1] of Char;
    FDeviceMode : THandle;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Printers,
  WinSpool;

{$R *.dfm}

//=============================================================================
//  ページ設定関係の設定
//  TPageSetupDialogダイアログを表示
//
//  usesにPrintersが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if PageSetupDialog1.Execute then begin
  end;
end;

//=============================================================================
//  プリンタのプロパティダイアログを表示(確認用)
//
//  該当プリンタドライバ専用の設定ダイアログがある場合は、そのプロパティダイア
//  ログを表示、それ以外は[ドキュメントのプロパティ]ダイアログで[詳細設定]をク
//  リックした時に表示されるダイアログを表示する
//
//  FDevice, FDriver, FPort, FDeviceModeはPrinter.GetPrinterで取得する
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LDevMode  : PDeviceMode;
  LhPrinter : THandle;
begin
  //FDeviceModeにプリンタドライバの値となる
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);

  //FDeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
  LDevMode := GlobalLock(FDeviceMode);

  try
    //対象のプリンタのハンドルを取得
    if WinSpool.OpenPrinter(FDevice, LhPrinter, nil) then begin
      try
        AdvancedDocumentProperties(Handle,
                                   LhPrinter,
                                   FDevice,
                                   LDevMode,
                                   LDevMode);
      finally
        //Openしたら閉じる
        ClosePrinter(LhPrinter);
      end;
    end;
  finally
    //ロック解除
    GlobalUnlock(FDeviceMode);
  end;
  //なくても設定は行われるが、次回のGetPrinter実行時に反映されない場合がある
  Printer.SetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

end.




07_コードでプロパティを設定 - DEVMODE 構造体のメンバの設定


ダイアログを表示しないで、プリンタのプロパティをコードで設定する例です。
[部単位での印刷] 等、TPrinter では設定できないプロパティは、DEVMODE 構造体の該当メンバに値をセットして設定できます。設定可能なのは dmFields メンバーにそのプロパティのフラグがある場合です。設定するプロパティ値は、プリンタドライバがサポートしていないと設定に失敗します。

TPrinter のプロパティで設定した値も、ダイアログで設定した値も全て DEVMODE 構造体のメンバにセットされます。DEVMODE 構造体を直接操作してプリンタや用紙のプロパティを取得したり設定する方法は、汎用的で一般的に行われている方法です。



図8
設定した内容をプロパティのダイアログで確認中
  • 本サンプルでは以下の値を設定
    印刷方向 (用紙の向き)
    用紙サイズ

リスト7
DEVMODE 構造体のメンバに用紙や印刷関係のプロパティを設定する
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    ComboBox1: TComboBox;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Select(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    FDevice     : array[0..MAX_PATH - 1] of Char;
    FDriver     : array[0..MAX_PATH - 1] of Char;
    FPort       : array[0..MAX_PATH - 1] of Char;
    FDeviceMode : THandle;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Printers,
  WinSpool;

{$R *.dfm}

//=============================================================================
//  プリンタのリストをコンボボックスにセット
//  PRINTER_INFO_4構造体から取得した方が正確
//  Printerオブジェクトから取得したプリンタ名と順番や内容が異なる場合がある
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ComboBox1.Items.Clear;

  ComboBox1.Items.Assign(Printer.Printers);
  ComboBox1.ItemIndex := Printer.PrinterIndex;

  //選択したプリンタを初期化
  //ここでは通常使うプリンタとなっている
  ComboBox1Select(nil);
end;

//=============================================================================
//  プリンタを変更したらそのプリンタのデフォルト値で初期化
//  前のプリンタの設定値を引き継ぐことは原則的にできない
//=============================================================================
procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  //選択したプリンタを現在のプリンタとする
  Printer.PrinterIndex := ComboBox1.ItemIndex;

  //ここで取得するFDeviceModeには、変更前のプリンタの情報が格納されている
  //その他の値は現在(変更後)のプリンタの情報となっている
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);
  //FDeviceMode初期化
  Printer.SetPrinter(FDevice, FDriver, FPort, 0);
  //FDeviceModeが新しいプリンタドライバの値(デフォルトのプロパティ値)となる
  Printer.GetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

//=============================================================================
//  選択したプリンタのプロパティをコードで設定
//
//  どんなメンバーがあるかはソースコードのPDeviceMode(Windows.pas)で確認可能
//  FDevice, FDriver, FPort, FDeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LDevMode  : PDeviceMode;
  LMode     : Cardinal;
  LhPrinter : THandle;
begin
  //ADeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
  LDevMode := GlobalLock(FDeviceMode);

  try
    //対象のプリンタのハンドルを取得
    if WinSpool.OpenPrinter(FDevice, LhPrinter, nil) then begin
      try
        //印刷方向を設定
        //dmFieldをチェックしてサポートしているプロパティの場合のみ設定
        if (LDevMode^.dmFields and DM_ORIENTATION) <> 0 then begin
          LDevMode^.dmOrientation := DMORIENT_LANDSCAPE;
        end;

        //用紙サイズを設定
        //dmFieldをチェックしてサポートしているプロパティの場合のみ設定
        if (LDevMode^.dmFields and DM_PAPERSIZE) <> 0 then begin
          LDevMode^.dmPaperSize := DMPAPER_B5;
        end;

        //このLModeの値によって、ダイアログ表示かプロパティの設定かが決まる
        LMode := DM_OUT_BUFFER or DM_IN_BUFFER;
        //プロパティの整合をチェックして設定
        DocumentProperties(Handle, LhPrinter, FDevice, LDevMode^, LDevMode^, LMode);
      finally
        //Openしたら閉じる
        ClosePrinter(LhPrinter);
      end;
    end;
  finally
    //ロック解除
    GlobalUnlock(FDeviceMode);
  end;
  //なくても設定は行われるが、次回のGetPrinter実行時に反映されない場合がある
  Printer.SetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

//=============================================================================
//  プリンタのプロパティダイアログを表示して設定結果を確認
//  DocumentProperties関数を使用
//
//  該当プリンタドライバ専用の設定ダイアログがある場合は、そのプロパティダイア
//  ログを表示、それ以外は[ドキュメントのプロパティ]ダイアログを表示
//  FDevice, FDriver, FPort, FDeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LDevMode  : PDeviceMode;
  LMode     : Cardinal;
  LhPrinter : THandle;
begin
  //ADeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
  LDevMode := GlobalLock(FDeviceMode);

  try
    //対象のプリンタのハンドルを取得
    if WinSpool.OpenPrinter(FDevice, LhPrinter, nil) then begin
      try
        //このLModeの値によって、ダイアログ表示かプロパティの設定かが決まる
        LMode := DM_IN_PROMPT or DM_OUT_BUFFER or DM_IN_BUFFER;
        DocumentProperties(Handle, LhPrinter, FDevice, LDevMode^, LDevMode^, LMode);
      finally
        //Openしたら閉じる
        ClosePrinter(LhPrinter);
      end;
    end;
  finally
    //ロック解除
    GlobalUnlock(FDeviceMode);
  end;
  //なくても設定は行われるが、次回のGetPrinter実行時に反映されない場合がある
  Printer.SetPrinter(FDevice, FDriver, FPort, FDeviceMode);
end;

end.


印刷部数と印刷の方向だけであれば、本ページの最初のサンプルのように、TPrinter オブジェクトに実装されているプロパティで、以下のように設定できます。


  //印刷部数をセット
  Printer.Copies := 3;

  //印刷の用紙方向をセット
  Printer.Orientation := poLandscape;




08_印刷品質または解像度の設定


印刷品質または解像度も、他のプロパティと同様に設定可能でなければ設定できません。
下図は設定できないプリンタドライバの例です。

これらの図は [011_プリンタドライバの情報取得] のサンプルを使用して取得しています。


図9
設定不可のプリンタ

下図は、印刷品質または解像度が設定可能なプリンタドライバの例です。
このプリンタは、dmFields の DM_PRINTQUALITY フラグがあるので設定可能です。ただしこのプリンタの場合、DMRES_MEDIUM のような定数値ではなく、解像度の数値で指定するようです。
この他に Y 方向の印刷品質という dmYResolution メンバーがあります。印刷品質をドット数で指定する場合、こちらの指定が必要かも知れません。この値の組合せは、[012] [03_使用可能な解像度のリスト] で確認できます。
なお、印刷品質は必ずしも解像度を意味するとは限りません。印刷の品質を向上させる技術は他にもあります。


図10
設定可能プリンタ
  • 解像度の値で設定するタイプ