|
Delphi Programming / Object Pascal
[掲載 2012年01月08日] [更新 2015年06月05日] Delphi サンプルプログラム集 |
017_通常使うプリンタを変更 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro |
|
017_ChangeDefaultPrinter.zip [2,224 KB] 2015年06月05日版 (EXE 同梱) |
- 2013年10月01日
- WMI を使用したサンプルを追加
|
システムの「通常使うプリンタ」(デフォルトのプリンタ) をコードで変更するサンプルです.
プリンタの変更部分は関数にしてあります.使用している関数や構造体は,他のプリンタ関係のサンプルプログラムの記事の説明や MSDN オンラインの記事を参考にしてください.
この,通常使うプリンタを変更する関数は,管理者でログインしていないと設定に失敗します.
プリンタのプロパティも同時に変更するテストがありますが,注意が必要です.
プロパティを変更してしまうと,そのプロパティの値が,そのプリンタのデフォルトのプロパティとなってしまいます.他のアプリケーションでそのプリンタで使用している場合に設定の変更が必要となるような状況が発生します.
これを避けるには,通常使うプリンタだけを変更した後,[013_プリンタのプロパティ設定] [03_コードでプロパティを設定] のようなコードでプロパティを設定します.
そうすれば,そのプロパティの設定は,現在のアプリだけで有効な設定となります.
現在はどうなっているか分かりませんが,一部の帳票作成用コンポーネントでは,内部で通常使うプリンタを変更しているものがあります.ワードやエクセルもそうです.用紙等のプロパティが希望通りに設定できないことがあります.そのような場合,この関数であらかじめ通常使うプリンタのプロパティを設定して印刷するようにしておけば,希望通りの印刷が可能なことがあります.
|
|
図1
設計時画面
|
|
図2
実行時画面例
- コンボボックスに表示されているプリンタを通常使うプリンタにする
|
リスト1
通常使うプリンタを変更する関数と,そのテストプログラム |
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;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure ComboBox1Select(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
ADevice : array[0..MAX_PATH - 1] of Char;
ADriver : array[0..MAX_PATH - 1] of Char;
APort : array[0..MAX_PATH - 1] of Char;
ADeviceMode : THandle;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses Printers, WinSpool;
{$R *.dfm}
//-----------------------------------------------------------------------------
// 通常使うプリンタ(デフォルトのプリンタ)を変更する関数
// ただし,管理者でログインしていないと設定できない
// この関数を使用するには,usesにPrintersとWinSpoolが必要
//
// PrinterName : プリンタ名の文字列
// DevMode : プリンタのプロパティも変更する場合のDEVMODE構造体
// プロパティを変更しない場合はnilとする
//
// この関数は,プロパティの設定にDocumentProperties関数ではなくPRINTER_INFO_2
// 構造体を使用している
//
// この関数では,指定プリンタドライバのデータの取得にGetPrinterDriver関数を使
// 用しているが,DriverNameには
// Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
// で取得したADriverも使用可能(DelphiのPrinter.pas内の関数はプリンタ名も同時に
// 取得できる等,この意味で便利)
// このplChangeDefaultPrinterでは,変更するプリンタ名とプロパティを引数にして
// 動作を独立するためにWindows APIのGetPrinterDriver関数を使用
// また,ポート名もPRINTER_INFO_2でpPInfo2^.pPortNameで取得しているが,これも
// Printer.GetPrinterの3番目の引数の値が使用可能
//-----------------------------------------------------------------------------
function plChangeDefaultPrinter(PrinterName: String; DevMode: PDeviceMode): Boolean;
var
hPrinter : THandle;
PDefaults : TPrinterDefaults;
dwNeeded : DWORD;
pPInfo2 : PPrinterInfo2;
pDrvInfo : PDriverInfo2;
DefaultPrinter : String;
DriverName : String;
begin
//Windows APIでプリンタを操作するにはOpenPrinter関数をまず実行
//アクセス権をPRINTER_ALL_ACCESSにして変更可能とする
FillChar(PDefaults, SizeOf(PDefaults), 0);
PDefaults.DesiredAccess := PRINTER_ALL_ACCESS;
//プリンタの変更権限がない場合(一般ユーザ等)はOpenPrinterの実行に失敗する
if not WinSpool.OpenPrinter(PChar(PrinterName), hPrinter, @PDefaults) then begin
Result := False;
exit;
end;
try
//PRINTER_INFO_2構造体の配列に必要なバイト数を取得して確保
WinSpool.GetPrinter(hPrinter, 2, nil, 0, @dwNeeded);
GetMem(pPinfo2, dwNeeded);
try
//PRINTER_INFO_2構造体の値を取得して設定
WinSpool.GetPrinter(hPrinter, 2, pPInfo2, dwNeeded, @dwNeeded);
pPInfo2^.Attributes := pPInfo2^.Attributes or PRINTER_ATTRIBUTE_DEFAULT;
//引数のDEVMODE構造体がnilでなければ,その値でプリンタを設定
if DevMode <> nil then pPInfo2^.pDevMode := DevMode;
WinSpool.SetPrinter(hPrinter, 2, pPInfo2, 0);
//プリンタドライバのデータ構造体の配列に必要なバイト数を取得して確保
GetPrinterDriver(hPrinter, nil, 2, nil, 0, dwNeeded);
GetMem(pDrvInfo, dwNeeded);
try
//指定プリンタドライバのデータを取得
GetPrinterDriver(hPrinter, nil, 2, pDrvInfo, dwNeeded, dwNeeded);
//WriteProfileString関数の引数に渡す値を作成
DriverName := ExtractFileName(String(pDrvInfo^.pDriverPath));
DriverName := ChangeFileExt(DriverName, '');
DefaultPrinter := String(pPInfo2^.pPrinterName) + ',' +
DriverName + ',' +
String(pPInfo2^.pPortName);
//レジストリへ情報を書き込む
//この関数は16bitとの互換性のためにあるが現在も使用可能なようだ
Result := WriteProfileString('windows', 'device', PChar(DefaultPrinter));
finally
FreeMem(pDrvInfo);
end;
//変更をシステムに通知
//WM_WININICHANGEも互換性のために残されているとあるが使用可能
Result := not PostMessage(HWND_BROADCAST, WM_WININICHANGE, 0, 0);
finally
FreeMem(pPInfo2);
end;
finally
ClosePrinter(hPrinter);
end;
end;
//=============================================================================
// プリンタのリストをコンボボックスにセット
// 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;
//=============================================================================
// TComboBoxのOnSelectイベント
// プリンタを変更したらそのプリンタのデフォルト値で初期化
// 前のプリンタの設定値を引き継ぐことは原則的にできない
//=============================================================================
procedure TForm1.ComboBox1Select(Sender: TObject);
begin
//選択したプリンタを現在のプリンタとする
Printer.PrinterIndex := ComboBox1.ItemIndex;
//ここで取得するADeviceMode1には,変更前のプリンタの情報が格納されている
//その他の値は現在(変更後)のプリンタの情報となっている
Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
//ADeviceMode初期化
Printer.SetPrinter(ADevice, ADriver, APort, 0);
//現在のプリンタのデフォルト値情報を取得
//ADeviceModeが新しいプリンタドライバの値となる
Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
end;
//=============================================================================
// plChangeDefaultPrinterの使用例
// 通常使うプリンタを変更するだけ
// そのプリンタのプロパティは変更しない
//
// ADevice, ADriver, APort, ADeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
//ADeviceModeのメモリをロック
GlobalLock(ADeviceMode);
try
//ADeviceがプリンタ名
if not plChangeDefaultPrinter(ADevice, nil) then begin
Application.MessageBox('設定には管理者権限が必要です.', 'プリンタの変更');
end;
finally
GlobalUnlock(ADeviceMode);
end;
end;
//=============================================================================
// plChangeDefaultPrinterの使用例
// 通常使うプリンタを変更し,そのプリンタのプロパティも変更する場合
//
// 【重要な注意】
// ここでプロパティの変更をすると,そのプリンタのデフォルトの設定がこの値にな
// ってしまう.他のアプリからこのプリンタを使用する際には注意が必要
// テストが終了したら,元に戻しておいた方が無難
// 日本の多くのプリンタのデフォルト値は
// ADevMode^.dmPaperSize := DMPAPER_A4;
// ADevMode^.dmOrientation := DMORIENT_PORTRAIT;
// となっている
//
// ADevice, ADriver, APort, ADeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
ADevMode : PDeviceMode;
begin
//ADeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
ADevMode := GlobalLock(ADeviceMode);
try
//用紙サイズをB5に,印刷方向を横に設定
//実際には,該当するプロパティをサポートしているかを確認してから設定する
ADevMode^.dmPaperSize := DMPAPER_B5;
ADevMode^.dmOrientation := DMORIENT_LANDSCAPE;
//ADeviceがプリンタ名
if not plChangeDefaultPrinter(ADevice, ADevMode) then begin
Application.MessageBox('設定には管理者権限が必要です.', 'プリンタの変更');
end;
finally
GlobalUnlock(ADeviceMode);
end;
end;
//=============================================================================
// AdvancedDocumentProperties関数でプロパティダイアログを表示
// 設定の確認用
// ADevice, ADriver, APort, ADeviceModeはPrinter.GetPrinterで取得したもの
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
ADevMode : PDeviceMode;
hPrinter : THandle;
begin
//ADeviceModeのメモリをロックしDEVMODE構造体のポインタを取得
ADevMode := GlobalLock(ADeviceMode);
try
//対象のプリンタのハンドルを取得
if WinSpool.OpenPrinter(ADevice, hPrinter, nil) then begin
try
AdvancedDocumentProperties(Handle, hPrinter, ADevice, ADevMode, ADevMode);
finally
//Openしたら閉じる
ClosePrinter(hPrinter);
end;
end;
finally
//ロック解除
GlobalUnlock(ADeviceMode);
end;
//なくても設定は行われるが,次回のGetPrinter実行時に反映されない場合がある
Printer.SetPrinter(ADevice, ADriver, APort, ADeviceMode);
end;
end.
02_通常使うプリンタの変更 - WMI を使用した方法 |
WMI の Win32_Printer クラスを使用すると,通常使用するプリンタを変更できます.
次のサンプルでは,タイプライブラリの取り込みでインポートした WbemScripting_TL.pas ファイルを使用して,通常使用するプリンタ名の取得と設定を行います.印刷ジョブのクリアのサンプルも追加しておきました.
本サンプルでは,ボタンクリックごとに WMI オブジェクトを生成し,WMI サービスに接続していますが,実際にはアプリの開始時に実行しておけば済みます.サンプルとして,グローパル変数を使用しないようにしているだけです.
プリンタの DEVMODE 構造体の値を操作するには,上のサンプルの TComboBox.OnSelect イベントと同じような処理が必要です.
|
|
図3
設計時画面
- コンボボックスはプリンタ選択用
- EXE を起動すると,コンボボックスには,通常使用するプリンタ名が表示される
|
|
図4
[通常使用するプリンタを取得]
|
|
図5
[通常使用するプリンタを変更]
- コンボボックスで選択したプリンタ名を,通常使うプリンタにする
|
|
図6
[印刷ジョブを全てクリア]
- インストールされている全てのプリンタの印刷ジョブをクリア
- 各プリンタに印刷ジョブがあるかのチェックはしていない
|
リスト2
WMI を使用して通常使うプリンタを変更するサンプル |
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;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses Printers, WbemScripting_TLB, ActiveX;
{$R *.dfm}
//=============================================================================
// プリンタのリストをコンボボックスにセット
// PRINTER_INFO_4構造体から取得した方が正確
// Printerオブジェクトから取得したプリンタ名と順番や内容が異なる場合がある
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.Clear;
ComboBox1.Items.Assign(Printer.Printers);
ComboBox1.ItemIndex := Printer.PrinterIndex;
end;
//=============================================================================
// 通常使用するプリンタ名を取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
objWMILocator : ISWbemLocator;
objWMIService : ISWbemServices;
objPropSet : ISWbemObjectSet;
objPropSetEnum : IEnumVariant;
objTemp : OleVariant;
iValue : LongWord;
strText : String;
begin
//Wbemのオブジェクトを生成
objWMILocator := CoSWbemLocator.Create;
//WMIサービスに接続.引数は必要に応じて設定
objWMIService := objWMILocator.ConnectServer(
'Localhost', //コンピュータ名.ローカルの場合は空白でも可
'root\cimv2', //名前空間
'', //ユーザ名.ローカルの場合は空文字にする
'', //パスワード.ローカルの場合は空文字にする
'', //ロケール識別子
'', //ドメイン名
0, //応答フラグ
nil);
//クエリーを実行して,プロパティのセットのオブジェクトを取得
objPropSet := objWMIService.ExecQuery(
'SELECT * FROM Win32_Printer Where Default = True',
'WQL',
wbemFlagForwardOnly,
nil);
//プロパティのセットのコレクションを取得
objPropSetEnum := objPropSet._NewEnum as IEnumVariant;
//-------------------------------------------------------------------------
// 以下がプロパティの取得または操作コード
//-------------------------------------------------------------------------
//取り出す
while objPropSetEnum.Next(1, objTemp, iValue) = 0 do begin
strText := '通常使用するプリンタは' + sLineBreak + String(ObjTemp.Name);
MessageBox(Handle, PChar(strText), '結果', MB_ICONINFORMATION);
objTemp := Unassigned;
end;
end;
//=============================================================================
// 通常使用するプリンタを変更
// コンボボックスで選択中のプリンタにする
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
objWMILocator : ISWbemLocator;
objWMIService : ISWbemServices;
objPropSet : ISWbemObjectSet;
objPropSetEnum : IEnumVariant;
objTemp : OleVariant;
iValue : LongWord;
NewPrinterName : String;
strText : String;
begin
//Wbemのオブジェクトを生成
objWMILocator := CoSWbemLocator.Create;
//WMIサービスに接続.引数は必要に応じて設定
objWMIService := objWMILocator.ConnectServer(
'Localhost', //コンピュータ名.ローカルの場合は空白でも可
'root\cimv2', //名前空間
'', //ユーザ名.ローカルの場合は空文字にする
'', //パスワード.ローカルの場合は空文字にする
'', //ロケール識別子
'', //ドメイン名
0, //応答フラグ
nil);
//クエリーを実行して,プロパティのセットのオブジェクトを取得
//クエリー文の中の変数は," (ダブルクォーテーション)で囲む
NewPrinterName := AnsiQuotedStr(ComboBox1.Items[ComboBox1.ItemIndex], '"');
objPropSet := objWMIService.ExecQuery(
'SELECT * FROM Win32_Printer Where Name = ' + NewPrinterName,
'WQL',
wbemFlagForwardOnly,
nil);
//プロパティのセットのコレクションを取得
objPropSetEnum := objPropSet._NewEnum as IEnumVariant;
//-------------------------------------------------------------------------
// 以下がプロパティの取得または操作コード
//-------------------------------------------------------------------------
//クエリーの結果のオブジェクトを取り出す
while objPropSetEnum.Next(1, objTemp, iValue) = 0 do begin
objTemp.SetDefaultPrinter;
objTemp := Unassigned;
strText := '通常使用するプリンタを変更';
MessageBox(Handle, PChar(strText), '結果', MB_ICONINFORMATION);
end;
end;
//=============================================================================
// 全てのプリンタの印刷ジョブをクリア
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
objWMILocator : ISWbemLocator;
objWMIService : ISWbemServices;
objPropSet : ISWbemObjectSet;
objPropSetEnum : IEnumVariant;
objTemp : OleVariant;
iValue : LongWord;
strText : String;
begin
//Wbemのオブジェクトを生成
objWMILocator := CoSWbemLocator.Create;
//WMIサービスに接続.引数は必要に応じて設定
objWMIService := objWMILocator.ConnectServer(
'Localhost', //コンピュータ名.ローカルの場合は空白でも可
'root\cimv2', //名前空間
'', //ユーザ名.ローカルの場合は空文字にする
'', //パスワード.ローカルの場合は空文字にする
'', //ロケール識別子
'', //ドメイン名
0, //応答フラグ
nil);
//クエリーを実行して,プロパティのセットのオブジェクトを取得
objPropSet := objWMIService.ExecQuery(
'SELECT * FROM Win32_Printer',
'WQL',
wbemFlagForwardOnly,
nil);
//プロパティのセットのコレクションを取得
objPropSetEnum := objPropSet._NewEnum as IEnumVariant;
//-------------------------------------------------------------------------
// 以下がプロパティの取得または操作コード
//-------------------------------------------------------------------------
//クエリーの結果のオブジェクトを取り出す
while objPropSetEnum.Next(1, objTemp, iValue) = 0 do begin
objTemp.CancelAllJobs;
strText := String(objTemp.Name) + sLineBreak + ' の印刷ジョブをクリア';
MessageBox(Handle, PChar(strText), '結果', MB_ICONINFORMATION);
objTemp := Unassigned;
end;
end;
end.
03_通常使うプリンタの変更 - WMI を OleVariant 型で扱う |
WMI のインスタンスを CreateOleObject で生成して,通常使用するプリンタを変更します.
COM オブジェクトのインスタンスを CreateOleObject で生成して,OleVariant 型で扱うと,タイプライブラリの取り込みで作成したファイルが必要ありません.ただし,WbemScripting_TL.pas を使用しない場合は,定数名が使えません.自分で定義して使用することになります.
定数名の実際の値は,WbemScripting_TL.pas 内に定義があります.これを参考にします.
WbemScripting_TL.pas の使用の有無にかかわらず,WbemScripting_TL.pas を作成しておくと,開発には便利です.
実行結果は上のサンプルと全く同じです.
本サンプルでも,ボタンクリックごとに WMI オブジェクトを生成し,WMI サービスに接続していますが,実際にはアプリの開始時に実行しておけば済みます.サンプルとして,グローパル変数を使用しないようにしているだけです. |
リスト3
WMI を CreateOleObject で生成して,通常使うプリンタを変更する例 |
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;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses Printers, ComObj, ActiveX;
{$R *.dfm}
//=============================================================================
// プリンタのリストをコンボボックスにセット
// PRINTER_INFO_4構造体から取得した方が正確
// Printerオブジェクトから取得したプリンタ名と順番や内容が異なる場合がある
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.Clear;
ComboBox1.Items.Assign(Printer.Printers);
ComboBox1.ItemIndex := Printer.PrinterIndex;
end;
//=============================================================================
// 通常使用するプリンタ名を取得
//
// WbemScripting_TLBを使用しないので,定数名は定義して使用
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
const
wbemFlagForwardOnly = $00000020;
var
objWMILocator : OleVariant;
objWMIService : OleVariant;
objPropSet : OleVariant;
objPropSetEnum : IEnumVariant;
objTemp : OleVariant;
iValue : LongWord;
strText : String;
begin
//WMIオブジェクトを生成
ObjWMILocator := CreateOleObject('WbemScripting.SWbemLocator');
//WMIサービスに接続
//第1引数はコンピュータ名(Localhostまたは空白なら自分のマシン)
ObjWMIService := ObjWMILocator.ConnectServer('Localhost', 'root\CIMV2');
//クエリーの実行
objPropSet := objWMIService.ExecQuery(
'SELECT * FROM Win32_Printer Where Default = True', 'WQL', wbemFlagForwardOnly);
//プロパティのセットのコレクションを取得
objPropSetEnum := IUnknown(objPropSet._NewEnum) as IEnumVariant;
//-------------------------------------------------------------------------
// 以下がプロパティの取得または操作コード
//-------------------------------------------------------------------------
//取り出す
while objPropSetEnum.Next(1, objTemp, iValue) = 0 do begin
strText := '通常使用するプリンタは' + sLineBreak + String(ObjTemp.Name);
MessageBox(Handle, PChar(strText), '結果', MB_ICONINFORMATION);
objTemp := Unassigned;
end;
end;
//=============================================================================
// 通常使用するプリンタを変更
// コンボボックスで選択中のプリンタにする
//
// WbemScripting_TLBを使用しないので,定数名は定義して使用
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
const
wbemFlagForwardOnly = $00000020;
var
objWMILocator : OleVariant;
objWMIService : OleVariant;
objPropSet : OleVariant;
objPropSetEnum : IEnumVariant;
objTemp : OleVariant;
iValue : LongWord;
NewPrinterName : String;
strText : String;
begin
//WMIオブジェクトを生成
ObjWMILocator := CreateOleObject('WbemScripting.SWbemLocator');
//WMIサービスに接続
//第1引数はコンピュータ名(Localhostまたは空白なら自分のマシン)
ObjWMIService := ObjWMILocator.ConnectServer('Localhost', 'root\CIMV2');
//クエリーの実行
//クエリー文の中の変数は," (ダブルクォーテーション)で囲む
NewPrinterName := AnsiQuotedStr(ComboBox1.Items[ComboBox1.ItemIndex], '"');
objPropSet := objWMIService.ExecQuery(
'SELECT * FROM Win32_Printer Where Name = ' + NewPrinterName,
'WQL',
wbemFlagForwardOnly);
//プロパティのセットのコレクションを取得
objPropSetEnum := IUnknown(objPropSet._NewEnum) as IEnumVariant;
//-------------------------------------------------------------------------
// 以下がプロパティの取得または操作コード
//-------------------------------------------------------------------------
//クエリーの結果のオブジェクトを取り出す
while objPropSetEnum.Next(1, objTemp, iValue) = 0 do begin
objTemp.SetDefaultPrinter;
objTemp := Unassigned;
strText := '通常使用するプリンタを変更';
MessageBox(Handle, PChar(strText), '結果', MB_ICONINFORMATION);
end;
end;
//=============================================================================
// 全てのプリンタの印刷ジョブをクリア
//
// WbemScripting_TLBを使用しないので,定数名は定義して使用
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
const
wbemFlagForwardOnly = $00000020;
var
objWMILocator : OleVariant;
objWMIService : OleVariant;
objPropSet : OleVariant;
objPropSetEnum : IEnumVariant;
objTemp : OleVariant;
iValue : LongWord;
strText : String;
begin
//WMIオブジェクトを生成
ObjWMILocator := CreateOleObject('WbemScripting.SWbemLocator');
//WMIサービスに接続
//第1引数はコンピュータ名(Localhostまたは空白なら自分のマシン)
ObjWMIService := ObjWMILocator.ConnectServer('Localhost', 'root\CIMV2');
//クエリーの実行
objPropSet := objWMIService.ExecQuery(
'SELECT * FROM Win32_Printer', 'WQL', wbemFlagForwardOnly);
//プロパティのセットのコレクションを取得
objPropSetEnum := IUnknown(objPropSet._NewEnum) as IEnumVariant;
//-------------------------------------------------------------------------
// 以下がプロパティの取得または操作コード
//-------------------------------------------------------------------------
//クエリーの結果のオブジェクトを取り出す
while objPropSetEnum.Next(1, objTemp, iValue) = 0 do begin
objTemp.CancelAllJobs;
strText := String(objTemp.Name) + sLineBreak + ' の印刷ジョブをクリア';
MessageBox(Handle, PChar(strText), '結果', MB_ICONINFORMATION);
objTemp := Unassigned;
end;
end;
end.
Delphi のアプリケーションで使用するプリンタは,Printer.PrinterIndex の値にプリンタの番号を指定すると設定できます.
「通常使用するプリンタ」を使用したい場合は,通常使用するプリンタの番号が不明でも,次のサンプルコードのように,Printer.PrinterIndex := -1; を実行すると設定できます.
この時,Printer.PrinterIndex プロパティには,-1 という値ではなく,実際の「通常使用するプリンタ」の番号が代入されます. |
|
図7
実行時に使用するプリンタの指定とその結果 |
リスト4
実行時に使用するプリンタの指定とその設定結果を確認 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
ADevice : array[0..MAX_PATH - 1] of Char;
ADriver : array[0..MAX_PATH - 1] of Char;
APort : array[0..MAX_PATH - 1] of Char;
ADeviceMode : THandle;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
Printers;
{$R *.dfm}
//=============================================================================
// 使用するプリンタを設定・取得
// usesにPrintersが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LPrtIndex : Integer;
LPrinterName : String;
LTheText : String;
begin
//-1にすると通常使用するブリンタのインデックスになる
Printer.PrinterIndex := -1;
//改めて通常使用するプリンタ(デフォルトのプリンタ)のインデックスを取得
LPrtIndex := Printer.PrinterIndex;
//そのインデックスのプリンタ名を取得
LPrinterName := Printer.Printers[LPrtIndex];
//実際のインデックスの値とプリンタ名を表示
LTheText := IntToStr(LPrtIndex) + sLineBreak + LPrinterName;
MessageBox(Handle, PChar(LTheText), '結果', MB_ICONINFORMATION);
//実際のプリンタの切り換えには以下のコードが必要
//コードの動作については他のサンプルのコメントを参照
Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
Printer.SetPrinter(ADevice, ADriver, APort, 0);
//以下はDEVMODEを操作する必要がなければ不要(慣習的に実行した方がいいかも知れない)
Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
end;
end.
|