Delphi Programming / Object Pascal
[掲載 2002年03月06日] [更新 2016年04月25日] プリンタ設定コンポーネント |
プリンタ設定コンポーネント
テストプログラム UserSizePaper |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro |
ユーザ定義用紙作成メソッドのテストプログラムです.Edit に入力した 0.1 mm 単位の数値で「テスト用紙」という用紙を作成し,その用紙を選択します.設定した用紙サイズの確認表示もします. |
|
図1
設計時画面 |
|
図2
実行画面
- 右側のボタンは確認ダイアログの表示用
- [プリントサーバのプロパティ] で,実際にプリントサーバに用紙名とサイズが登録,削除できたかを確認できる
|
|
図3
プリントサーバへの登録が成功した場合
- 同じ名前の用紙がプリントサーバに登録されている場合も同じ.ただし,用紙サイズは変更される
- この用紙は別のプリンタからも使用可能
- ただし,独自でユーザ定義サイズを管理しているプリンタドライバではリストされない場合がある
|
|
図4
削除に成功した場合
- 別のプリンタドライバからも削除可能.ただし,そのプリンタドライバがプリントサーバの操作が可能な場合に限る
- 削除した後に再度削除を実行すると,削除に失敗する
|
ユーザ定義用紙のサイズを独自で管理しているプリンタドライバがあります.
下図はそのようなプリンタドライバで操作した結果例です.
このプリンタドライバでは既存の [ユーザー定義サイズ] という名前の用紙に,その用紙のサイズが変更されて登録されます.名前は違っていても,この用紙サイズの設定は有効となります.実用的には問題ありません.
ユーザ定義用紙のサイズを独自で管理しているプリンタドライバでは,たとえ,プリントサーバに削除対象の用紙名が存在しても削除できない場合があります. |
|
図5
別の用紙名で登録される場合
- ユーザ定義の用紙サイズを独自に管理するプリンタドライバの場合
- このプリンタドライバには [テスト用紙] という名前は登録されないが,プリントサーバに [テスト用紙] の用紙名を登録するプリンタドライバもある
|
|
図6
削除に失敗する
- プリントサーバに登録された [テスト用紙] も削除されない
- プリントサーバに登録された [テスト用紙] を削除するには別のプリンタドライバで行う
|
[備考 1]
上の実行結果は,ユーザ定義サイズを独自管理しているプリンタドライバの例ですが,
ユーザ定義の用紙名はプリントサーバに登録しますが,削除はしません.
ユーザ定義サイズを独自管理する機能を持つプリンタドライバでも,プリントサーバへの用紙名の登録,削除を実行するものもあります.
動作仕様は,プリンタドライバによって違いがあります.本テストプログラムのコードがそのまま利用できるとは限りません.残念ですが,筆者はこの違いを検出,調べる方法を知りません.
|
[備考 2]
プログラマは,ユーザ定義用紙の登録,削除の状態に関心があるかも知れません.
アプリケーションを使用するユーザにとって,
その用紙が使用できればいいわけです.その用紙がプリントサーバに登録されたままであろうが,削除されようが関心はないでしょう.プリントサーバ等という専門用語にも興味がないかも知れません.
用紙の登録,登録削除は,基本的には管理者が [プリントサーバーのプロパティ] から操作すれば,十分目的は果たせるのではないかと思われます.
|
unit UserSizePaperUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, plSetPrinter, Buttons;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
plSetPrinter1: TplSetPrinter;
Panel1: TPanel;
Edit1: TEdit;
Panel2: TPanel;
Edit2: TEdit;
Panel3: TPanel;
Panel5: TPanel;
Panel4: TPanel;
Panel6: TPanel;
BitBtn1: TBitBtn;
ComboBox1: TComboBox;
PrinterSetupDialog1: TPrinterSetupDialog;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
private
{ Private 宣言 }
FUserPaperName: string;
FResultPaperName : string;
procedure DisplayPaperSize;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
Printers,
Math,
ShellAPI;
{$R *.DFM}
//=============================================================================
// 用紙のサイズを指定
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
//プリンタの一覧を作成
ComboBox1.Style := csDropDownList;
ComboBox1.Items.Assign(plSetPrinter1.PrinterList);
plSetPrinter1.PrinterName := Printer.Printers[Printer.PrinterIndex];
ComboBox1.ItemIndex := ComboBox1.Items.IndexOf(plSetPrinter1.PrinterName);
if ComboBox1.ItemIndex = -1 then ComboBox1.ItemIndex := 0;
//ユーザ定義用紙のサイズの初期値
Edit1.Text := '1200';
Edit2.Text := '1800';
//用紙名
FUserPaperName := 'テスト用紙';
end;
//=============================================================================
// プリンタを選択
// Delphi6,7であればOnCloseUpイベントに記述した方がよい.
//=============================================================================
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
plSetPrinter1.PrinterName := ComboBox1.Text;
end;
//=============================================================================
// ユーザ定義用紙を作成して結果を表示
// サイズが範囲外だと失敗
// WindowsNT,2000の場合,作成の権限がないと失敗
// ユーザ定義サイズを独自管理している場合は同じ用紙名が登録済みだと失敗
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LPaperHorz : Integer;
LPaperVert : Integer;
LResText : string;
begin
LPaperHorz := StrToInt(Edit1.Text);
LPaperVert := StrToInt(Edit2.Text);
if plSetPrinter1.SetUserPaper(FUserPaperName, LPaperHorz, LPaperVert) then begin
FResultPaperName := plSetPrinter1.PaperName;
LResText := '指定用紙サイズが次の用紙名で使用可能になりました.' + sLineBreak
+ FResultPaperName;
MessageBox(Handle, PChar(LResText), '結果', MB_ICONINFORMATION);
end else begin
FResultPaperName := '';
LResText := '以下の用紙名またはサイズの登録に失敗しました ' + sLineBreak
+ 'プリントサーバには登録された可能性があります.' + sLineBreak
+ FUserPaperName;
MessageBox(Handle, PChar(LResText), '結果', MB_ICONINFORMATION);
end;
DisplayPaperSize;
end;
//=============================================================================
// ユーザ定義用紙の削除
// Windows95,98では常に成功(実際には削除しない)
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LText : string;
begin
if plSetPrinter1.DeleteUserPaper(FUserPaperName) then begin
if plSetPrinter1.PaperList.IndexOf(FUserPaperName) < 0 then begin
LText := 'プリントサーバから以下の用紙名を削除しました.' + sLineBreak
+ FUserPaperName;
end else begin
LText := '以下の用紙名の削除に失敗しました.' + sLineBreak
+ FUserPaperName;
end;
MessageBox(Handle, PChar(LText), '結果', MB_ICONINFORMATION);
end else begin
if (FUserPaperName <> FResultPaperName) and (FResultPaperName <> '') then begin
LText := '以下の用紙名を使用しましたが,用紙サイズを設定しただけです.'
+ sLineBreak
+ FResultPaperName + sLineBreak
+ 'プリントサーバに以下の用紙名が残っているかも知れません.' + sLineBreak
+ FUserPaperName;
end else begin
if plSetPrinter1.PaperList.IndexOf(FUserPaperName) < 0 then begin
LText := '以下の用紙名は既に削除されているか,存在しません.' + sLineBreak
+ FUserPaperName;
end else begin
LText := '以下の用紙名の削除に失敗しました.' + sLineBreak
+ 'プリントサーバに登録されたままの可能性がありますが,' + sLineBreak
+ 'このプリンタドライバからは削除できません.' + sLineBreak
+ FUserPaperName;
end;
end;
MessageBox(Handle, PChar(LText), '結果', MB_ICONINFORMATION);
end;
//削除した場合はデフォルトの用紙サイズを表示
plSetPrinter1.GetPrinterInfo;
DisplayPaperSize;
end;
//=============================================================================
// [プリンタの設定]ダイアログを表示して結果を確認
// プリンタに変更があった場合はGetPrinterInfoを実行しないと変更されない
//=============================================================================
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if PrinterSetupDialog1.Execute then begin
plSetPrinter1.GetPrinterInfo;
DisplayPaperSize;
end;
end;
//=============================================================================
// [プリンタのプロパティ]ダイアログを表示して結果を確認
// 本コンポのメソッドShowDialogではGetPrinterInfoは不要
//=============================================================================
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
plSetPrinter1.ShowDialog;
DisplayPaperSize;
end;
//-----------------------------------------------------------------------------
// 32ビットのWindowsか64ビットのWindowsかを調べる関数
// 64ビット版のWindowsの場合はTrueを返す
//-----------------------------------------------------------------------------
function Is64bitWindows: Boolean;
var
Wow64Proc : function(hProcess: THandle; var Wow64: BOOL): BOOL stdcall;
RetFlag : LongBool;
begin
@Wow64Proc := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'IsWow64Process');
if @Wow64Proc <> nil then begin
Wow64Proc(GetCurrentProcess, RetFlag);
if SizeOf(THandle) = 4 then begin
Result := RetFlag;
end else
if SizeOf(THandle) = 8 then begin
Result := True;
end;
end else begin
//Windows XPの64ビット版か
Result := CheckWin32Version(5, 2);
end;
end;
//=============================================================================
// [プリントサーバのプロパティ]ダイアログを表示
// ユーザ定義用紙の登録と削除の確認用
//
// ShellExecuteの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.BitBtn3Click(Sender: TObject);
var
LCmdExe : string;
LCmdParam : string;
begin
//64ビットWindowsの場合で32ビットEXEの場合
if (Is64bitWindows) and (SizeOf(Pointer) = 4) then begin
LCmdExe := 'C:\Windows\Sysnative\rundll32';
end else begin
LCmdExe := 'rundll32';
end;
LCmdParam := 'printui.dll,PrintUIEntry /s';
ShellExecute(0, nil, PChar(LCmdExe), PChar(LCmdParam), nil, SW_SHOWNORMAL);
end;
//-----------------------------------------------------------------------------
// 取得した用紙の幅と長さを表示
//-----------------------------------------------------------------------------
procedure TForm1.DisplayPaperSize;
var
LPaperWmm : Integer;
LPaperHmm : Integer;
begin
//幅を0.1mm単位に換算
LPaperWmm := Ceil(plSetPrinter1.PaperWidth * 254.0 / plSetPrinter1.XResolution);
//長さを0.1mm単位に換算
LPaperHmm := Ceil(plSetPrinter1.PaperHeight * 254.0 / plSetPrinter1.YResolution);
//計算結果を文字列にして表示
Panel5.Caption := ' ' + IntToStr(LPaperWmm);
Panel6.Caption := ' ' + InttoStr(LPaperHmm);
end;
end.
|