Workaround for Printing from Delphi (or the Delphi IDE): three strikes and you get “Printer is not currently printing.” – yes I mentioned “Delphi 8!”
Posted by jpluimers on 2016/08/31
Recently when printing the 3rd time and up, you get this error in many Delphi programs and the Delphi IDE:
In the past this only occurred when you used a TPrinter
and forgot to call BeginDoc
.
But now it always occurs after reusing the same TPrinter
instance for the 3rd time and up. Since the Delphi Galileo based IDEs (8 and higher; likely older ones as well: the source code printing hasn’t changed in a long time). The error actually occurs twice: after starting a source code print job, but also after cancelling the same failed source code print job.
The second error stroke me as odd, so I went searching for “printer is not currently printing” “IDE” leading to this stack overflow question: c++builder – Why is TPrinter (XE7) suddenly having problems today? – Stack Overflow [WayBack].
The pattern there is using the
Printer()
function which has been the way the (un)official code examples have shown for ages (Delphi 2007 Printers.Printer Function [WayBack]; earlier examples like Delphi 7 [WayBack] usually in PDF files).Like in the Delphi 7 “5-32 Developer’s Guide” page example:
procedure TForm1.Button1Click(Sender: TObject); var r: TRect; i: Integer; begin with Printer do begin r := Rect(200,200,(Pagewidth - 200),(PageHeight - 200)); BeginDoc; Canvas.Brush.Style := bsClear; for i := 0 to Memo1.Lines.Count do Canvas.TextOut(200,200 + (i * Canvas.TextHeight(Memo1.Lines.Strings[i])), Memo1.Lines.Strings[i]); Canvas.Brush.Color := clBlack; Canvas.FrameRect(r); EndDoc; end; end;(Yes, that’s back in the D7 days when examples were still using with and not using try/finally statements for resource cleanup).
Actual cause and permanent fix
The printing problems are caused by various recent Windows updates part of MS16-098:
- KB3177725 MS16-098 may cause printer problems – Microsoft Community
- KB3176493 for Windows 10 and KB3177725 for Windows 7 broke printing in – Microsoft Community
Though MS16-098: Security update for Windows kernel-mode drivers: August 9, 2016 mentions the issue without a fix, KB3177725 in MS16-098: Description of the security update for Windows kernel-mode drivers: August 9, 2016 mentions both the issue and a permanent fix:
After you apply this security update and you print multiple documents in succession, the first two documents may print successfully. However, the third and subsequent documents may not print.
To resolve this issue, install update 3187022. For more information, click the following article number to view the article in the Microsoft Knowledge Base:
3187022 Print functionality is broken after any of the MS16-098 security updates are installed
This article describes printing issues that occur after any of the security updates that are described in Microsoft Security Bulletin MS16-098 are installed in Windows. You can fix these issues by installing the update that is described in this article. Before you install this update, check out the Prerequisites section.
This update applies to the following operating systems:
- Windows Server 2012 R2
- Windows 8.1
- Windows RT 8.1
- Windows Server 2012
- Windows Server 2008 R2 Service Pack 1 (SP1)
- Windows 7 SP1
- Windows Server 2008 Service Pack 2 (SP2)
- Windows Vista SP2
No solution for Windows 10 yet…
Until you install the fix: workarounds
For your own code (Thanks Remy Lebau for your answer), add this code for your BeginDoc
call:
MyPrinter.Copies := MyPrinter.Copies;
You might want to keep including this in your code as you’re never sure when the end-users apply which Windows update.
For the Delphi IDE either:
- Press the “Setup…” button in the “Print Selection” dialog when printing source code, then “OK” in the “Print Setup” dialog:
- Uninstall the security updated marked in blue (Security Update for Microsoft Windows (KB3177725):
–jeroen
IDE stack trace when the print job fails:
[506B57F5]{vcl220.bpl } Vcl.Printers.RaiseError (Line 249, "Vcl.Printers.pas" + 1) + $E [506B62B2]{vcl220.bpl } Vcl.Printers.TPrinter.CheckPrinting (Line 882, "Vcl.Printers.pas" + 2) + $14 [506B6040]{vcl220.bpl } Vcl.Printers.TPrinterCanvas.Changing (Line 691, "Vcl.Printers.pas" + 1) + $5 [50660837]{vcl220.bpl } Vcl.Graphics.TCanvas.GetHandle (Line 4144, "Vcl.Graphics.pas" + 1) + $4 [20761344]{coreide220.bpl} PrintSes.TPrintSession.PrintHeader (Line 312, "PrintSes.pas" + 12) + $16 [20760D49]{coreide220.bpl} PrintSes.DoUpdatePage (Line 108, "PrintSes.pas" + 3) + $7 [207611D5]{coreide220.bpl} PrintSes.TPrintSession.PrintBody (Line 279, "PrintSes.pas" + 4) + $7 [2076066A]{coreide220.bpl} PrintSts.TPrintStatusDlg.StartPrinting (Line 51, "PrintSts.pas" + 1) + $4 [50682FE9]{vcl220.bpl } Vcl.Controls.TControl.WndProc (Line 7245, "Vcl.Controls.pas" + 91) + $6 [50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6 [2185459B]{vclactnband220.bpl} Vcl.ActnMenus.CallWindowHook (Line 748, "Vcl.ActnMenus.pas" + 20) + $F [500605B4]{rtl220.bpl } System.TMonitor.TryEnter (Line 17939, "System.pas" + 10) + $0 [50060134]{rtl220.bpl } System.TMonitor.Enter (Line 17632, "System.pas" + 4) + $2 [5005FFB8]{rtl220.bpl } System.TMonitor.CheckOwningThread (Line 17550, "System.pas" + 2) + $0 [500602C2]{rtl220.bpl } System.TMonitor.Exit (Line 17736, "System.pas" + 1) + $2 [50060313]{rtl220.bpl } System.TMonitor.Exit (Line 17758, "System.pas" + 2) + $7 [50664E27]{vcl220.bpl } Vcl.Graphics.FreeMemoryContexts (Line 7051, "Vcl.Graphics.pas" + 12) + $8 [50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6 [507C1F58]{vcl220.bpl } Vcl.Forms.TCustomForm.WndProc (Line 4427, "Vcl.Forms.pas" + 206) + $5 (002818D1){mmx_bds16.dll} [100F28D1] [506871B0]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9786, "Vcl.Controls.pas" + 3) + $6 [50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0 [5067DD2E]{vcl220.bpl } Vcl.Controls.FindControl (Line 3574, "Vcl.Controls.pas" + 6) + $9 [507CB41F]{vcl220.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10352, "Vcl.Forms.pas" + 23) + $1 [507CB462]{vcl220.bpl } Vcl.Forms.TApplication.HandleMessage (Line 10382, "Vcl.Forms.pas" + 1) + $4 [507C69DA]{vcl220.bpl } Vcl.Forms.TCustomForm.ShowModal (Line 7148, "Vcl.Forms.pas" + 33) + $5 [20760BFD]{coreide220.bpl} PrintSes.TPrintSession.Print (Line 81, "PrintSes.pas" + 18) + $0 [20775605]{coreide220.bpl} EditorControl.PrintEditView (Line 6450, "EditorControl.pas" + 13) + $12 [207756D1]{coreide220.bpl} EditorControl.TCustomEditControl.Print (Line 6476, "EditorControl.pas" + 0) + $1 [207219FF]{coreide220.bpl} EditorBuffer.TEditView.EditAction (Line 5478, "EditorBuffer.pas" + 12) + $2 [20754799]{coreide220.bpl} EditorForm.TEditWindow.EditAction (Line 1200, "EditorForm.pas" + 18) + $2 [00422C30]{bds.exe } AppMain.TAppBuilder.FormEdit (Line 3901, "AppMain.pas" + 4) + $9 [00422CD9]{bds.exe } AppMain.TAppBuilder.DoEditAction (Line 3916, "AppMain.pas" + 2) + $4 [0041EEBD]{bds.exe } AppMain.TAppBuilder.FilePrint (Line 2680, "AppMain.pas" + 0) + $5 [50172097]{rtl220.bpl } System.Classes.TBasicAction.Execute (Line 16378, "System.Classes.pas" + 3) + $7 [5066C5DA]{vcl220.bpl } Vcl.ActnList.TCustomAction.Execute (Line 259, "Vcl.ActnList.pas" + 19) + $35 [50171EEF]{rtl220.bpl } System.Classes.TBasicActionLink.Execute (Line 16289, "System.Classes.pas" + 2) + $7 [2185508D]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.ExecAction (Line 1077, "Vcl.ActnMenus.pas" + 6) + $D [21856930]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.TrackMenu (Line 1843, "Vcl.ActnMenus.pas" + 19) + $15 [2185A34A]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMainMenuBar.TrackMenu (Line 3637, "Vcl.ActnMenus.pas" + 5) + $3 [21854C53]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.CMEnterMenuLoop (Line 962, "Vcl.ActnMenus.pas" + 1) + $4 [50682FE9]{vcl220.bpl } Vcl.Controls.TControl.WndProc (Line 7245, "Vcl.Controls.pas" + 91) + $6 [50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6 [500605B4]{rtl220.bpl } System.TMonitor.TryEnter (Line 17939, "System.pas" + 10) + $0 [50060134]{rtl220.bpl } System.TMonitor.Enter (Line 17632, "System.pas" + 4) + $2 [5005FFB8]{rtl220.bpl } System.TMonitor.CheckOwningThread (Line 17550, "System.pas" + 2) + $0 [500602C2]{rtl220.bpl } System.TMonitor.Exit (Line 17736, "System.pas" + 1) + $2 [50060313]{rtl220.bpl } System.TMonitor.Exit (Line 17758, "System.pas" + 2) + $7 [50664E27]{vcl220.bpl } Vcl.Graphics.FreeMemoryContexts (Line 7051, "Vcl.Graphics.pas" + 12) + $8 [506871B0]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9786, "Vcl.Controls.pas" + 3) + $6 [506871C5]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9789, "Vcl.Controls.pas" + 6) + $0 [50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0 [50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6 [500605B4]{rtl220.bpl } System.TMonitor.TryEnter (Line 17939, "System.pas" + 10) + $0 [50060134]{rtl220.bpl } System.TMonitor.Enter (Line 17632, "System.pas" + 4) + $2 [21856A46]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.WndProc (Line 1882, "Vcl.ActnMenus.pas" + 25) + $4 [506871B0]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9786, "Vcl.Controls.pas" + 3) + $6 [50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0 [5067DD2E]{vcl220.bpl } Vcl.Controls.FindControl (Line 3574, "Vcl.Controls.pas" + 6) + $9 [507CB41F]{vcl220.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10352, "Vcl.Forms.pas" + 23) + $1 [507CB462]{vcl220.bpl } Vcl.Forms.TApplication.HandleMessage (Line 10382, "Vcl.Forms.pas" + 1) + $4 [507CB795]{vcl220.bpl } Vcl.Forms.TApplication.Run (Line 10520, "Vcl.Forms.pas" + 26) + $3
Stack trace leading to the “Printer is not currently printing.” error.
Stack trace after cancelling the print job:
[506B57F5]{vcl220.bpl } Vcl.Printers.RaiseError (Line 249, "Vcl.Printers.pas" + 1) + $E [506B62B2]{vcl220.bpl } Vcl.Printers.TPrinter.CheckPrinting (Line 882, "Vcl.Printers.pas" + 2) + $14 [506B62FB]{vcl220.bpl } Vcl.Printers.TPrinter.Abort (Line 889, "Vcl.Printers.pas" + 1) + $4 [20760C16]{coreide220.bpl} PrintSes.TPrintSession.Print (Line 82, "PrintSes.pas" + 19) + $C [20775605]{coreide220.bpl} EditorControl.PrintEditView (Line 6450, "EditorControl.pas" + 13) + $12 [207756D1]{coreide220.bpl} EditorControl.TCustomEditControl.Print (Line 6476, "EditorControl.pas" + 0) + $1 [207219FF]{coreide220.bpl} EditorBuffer.TEditView.EditAction (Line 5478, "EditorBuffer.pas" + 12) + $2 [20754799]{coreide220.bpl} EditorForm.TEditWindow.EditAction (Line 1200, "EditorForm.pas" + 18) + $2 [00422C30]{bds.exe } AppMain.TAppBuilder.FormEdit (Line 3901, "AppMain.pas" + 4) + $9 [00422CD9]{bds.exe } AppMain.TAppBuilder.DoEditAction (Line 3916, "AppMain.pas" + 2) + $4 [0041EEBD]{bds.exe } AppMain.TAppBuilder.FilePrint (Line 2680, "AppMain.pas" + 0) + $5 [50172097]{rtl220.bpl } System.Classes.TBasicAction.Execute (Line 16378, "System.Classes.pas" + 3) + $7 [5066C5DA]{vcl220.bpl } Vcl.ActnList.TCustomAction.Execute (Line 259, "Vcl.ActnList.pas" + 19) + $35 [50171EEF]{rtl220.bpl } System.Classes.TBasicActionLink.Execute (Line 16289, "System.Classes.pas" + 2) + $7 [2185508D]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.ExecAction (Line 1077, "Vcl.ActnMenus.pas" + 6) + $D [21856930]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.TrackMenu (Line 1843, "Vcl.ActnMenus.pas" + 19) + $15 [2185A34A]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMainMenuBar.TrackMenu (Line 3637, "Vcl.ActnMenus.pas" + 5) + $3 [21854C53]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.CMEnterMenuLoop (Line 962, "Vcl.ActnMenus.pas" + 1) + $4 [50682FE9]{vcl220.bpl } Vcl.Controls.TControl.WndProc (Line 7245, "Vcl.Controls.pas" + 91) + $6 [50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6 [500605B4]{rtl220.bpl } System.TMonitor.TryEnter (Line 17939, "System.pas" + 10) + $0 [50060134]{rtl220.bpl } System.TMonitor.Enter (Line 17632, "System.pas" + 4) + $2 [5005FFB8]{rtl220.bpl } System.TMonitor.CheckOwningThread (Line 17550, "System.pas" + 2) + $0 [500602C2]{rtl220.bpl } System.TMonitor.Exit (Line 17736, "System.pas" + 1) + $2 [50060313]{rtl220.bpl } System.TMonitor.Exit (Line 17758, "System.pas" + 2) + $7 [50664E27]{vcl220.bpl } Vcl.Graphics.FreeMemoryContexts (Line 7051, "Vcl.Graphics.pas" + 12) + $8 [506871B0]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9786, "Vcl.Controls.pas" + 3) + $6 [506871C5]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9789, "Vcl.Controls.pas" + 6) + $0 [50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0 [50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6 [500605B4]{rtl220.bpl } System.TMonitor.TryEnter (Line 17939, "System.pas" + 10) + $0 [50060134]{rtl220.bpl } System.TMonitor.Enter (Line 17632, "System.pas" + 4) + $2 [21856A46]{vclactnband220.bpl} Vcl.ActnMenus.TCustomActionMenuBar.WndProc (Line 1882, "Vcl.ActnMenus.pas" + 25) + $4 [506871B0]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9786, "Vcl.Controls.pas" + 3) + $6 [50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0 [5067DD2E]{vcl220.bpl } Vcl.Controls.FindControl (Line 3574, "Vcl.Controls.pas" + 6) + $9 [507CB41F]{vcl220.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10352, "Vcl.Forms.pas" + 23) + $1 [507CB462]{vcl220.bpl } Vcl.Forms.TApplication.HandleMessage (Line 10382, "Vcl.Forms.pas" + 1) + $4 [507CB795]{vcl220.bpl } Vcl.Forms.TApplication.Run (Line 10520, "Vcl.Forms.pas" + 26) + $3
Gorazd said
Or use code to reset printer, works on Win10.
Procedure PrintInit;
// Reset printer if needed
Var
Device, Driver, Port: Array[0..80] Of Char;
DevMode: THandle;
Begin
Printer.GetPrinter (Device, Driver, Port, DevMode);
Printer.SetPrinter (Device, Driver, Port, 0);
End;
jpluimers said
Is a bit more convoluted, right?