こんにちは
ある複合機の機能を使用するために印刷ジョブを分けずに用紙サイズを変更する処理を作成しています
添付しているソースだと2ページ目でA3に変更しようとした時点で「現在印刷中です」というエラーが発生します
私自身「印刷中に用紙サイズの変更はできない」と認識しておりエラーも当然だと思っていましたが、
Word等のアプリケーションでは同一ジョブ内で異なる用紙サイズ出力を実現させています
印刷中に用紙サイズを変更する方法をご存じではないでしょうか
よろしくお願いします
uses
Printers;
var
Def_Port,
Def_Device,
Def_Driver : array[0..250] of Char;
Def_pDev : PDevMode;
Def_hDeviceMode: THandle;
procedure ChangePapersize(PaperName: String);
begin
Printer.GetPrinter(Def_Device,Def_Driver,Def_Port,Def_hDeviceMode);
Def_pDev:=GlobalLock(Def_hDeviceMode);
if PaperName = 'A3' then Def_pDev^.dmPaperSize:=DmPaper_A3 else
if PaperName = 'A4' then Def_pDev^.dmPaperSize:=DmPaper_A4;
GlobalUnlock(Def_hDeviceMode);
Printer.SetPrinter(Def_Device,Def_Driver,Def_Port,Def_hDeviceMode);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if PrintDialog1.execute then
begin
ChangePapersize('A4');
Printer.BeginDoc;
Printer.canvas.TextOut(100,100,PChar('PAGE1'));
Printer.NewPage;
ChangePapersize('A3');
Printer.canvas.TextOut(100,100,PChar('PAGE2'));
Printer.EndDoc;
end;
end;
TPrinter.NewPageの実装が
procedure TPrinter.NewPage;
begin
CheckPrinting(True);
EndPage(DC);
StartPage(DC);
Inc(FPageNumber);
Canvas.Refresh;
end;
となっていて、NewPageを呼び出したら新しいページの処理が始まっちゃってるのが原因な気がします。
例えば
uses
Vcl.Consts;
type
TChangingPageProc = reference to procedure ();
TPrinterHelper = class helper for TPrinter
public
procedure NewPage2(ChangingPageProc: TChangingPageProc);
end;
procedure TPrinterHelper.NewPage2(ChangingPageProc: TChangingPageProc);
begin
if Printing = False then
begin
raise EPrinter.Create(SNotPrinting);
end;
EndPage(Handle);
if Assigned(ChangingPageProc) then
begin
ChangingPageProc();
end;
StartPage(Handle);
Canvas.Refresh;
end;
こんなのを用意して、
ChangePapersize('A4');
Printer.BeginDoc;
Printer.canvas.TextOut(100,100,PChar('PAGE1'));
Printer.NewPage2(
procedure
begin
ChangePapersize('A3');
end);
Printer.canvas.TextOut(100,100,PChar('PAGE2'));
Printer.EndDoc;
こんな感じで用紙サイズを変更したらどうでしょう?
(動かして試していないのでダメだったらすいません
HFUKUSHIさん ありがとうございます
Delphi11にて試してみましたが「現在印刷中です」というメッセージが表示され現象は変わらずでした
このメッセージはTPrinter.SetPrinter内の1行目CheckPrintingメソッドが発生させていました
TPrinter.SetPrinter内の全てを理解することはできませんがOpenPrinterやClosePrinterが行われていることから印刷実行中に使用するのは問題がありそうです
プリンタ設定を変更する方法としてTPrinter.SetPrinterに替る他の方法はあるのでしょうか
よろしくお願いします
わからんけど
procedure ChangePapersize(PaperName: String);
begin
Printer.GetPrinter(Def_Device,Def_Driver,Def_Port,Def_hDeviceMode);
Def_pDev:=GlobalLock(Def_hDeviceMode);
if PaperName = 'A3' then Def_pDev^.dmPaperSize:=DmPaper_A3 else
if PaperName = 'A4' then Def_pDev^.dmPaperSize:=DmPaper_A4;
GlobalUnlock(Def_hDeviceMode);
ResetDC(Printer.Handle,Def_pDev^);
//Printer.SetPrinter(Def_Device,Def_Driver,Def_Port,Def_hDeviceMode);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if PrintDialog1.execute then
begin
ChangePapersize('A4');
Printer.BeginDoc;
Printer.canvas.TextOut(100,100,PChar('PAGE1'));
EndPage(Printer.Handle);
ChangePapersize('A3');
StartPage(Printer.Handle);
Printer.canvas.TextOut(100,100,PChar('PAGE2'));
Printer.EndDoc;
end;
end;
AAAAA さん
ResetDCを使用することで目的の処理を実現できました
大変助かりました
お返事いただいた皆さん、ありがとうございました