Windows默认打印机未设置时,“没有select默认打印机”错误

当没有Windows默认打印机设置时,我需要打开打印机对话框。 当Windows默认打印机设置时,它可以正常工作。

TPrintDialog *dlgPrint = new TPrintDialog(frmDisplayDetail); if( dlgPrint->Execute()) { //code here } 

但是,如果在Windows中没有默认的打印机设置,则dlgPrint->Execute()将引发一个exception:

没有select默认打印机

要检查默认的打印机索引,我使用了Printer()->PrinterIndex 。 没有Windows打印机设置时,此值变得不可访问:

错误E2122函数调用在地址XXX处由未处理的exceptionXXX终止

难道我做错了什么? 请提出解决scheme。

Solutions Collecting From Web of "Windows默认打印机未设置时,“没有select默认打印机”错误"

当出现以下情况时,仅通过TPrinter::SetToDefaultPrinter()方法抛出异常“没有当前选定的默认打印机”

  • 枚举(未PRINTER_ENUM_DEFAULTPRINTER_ENUM_DEFAULT标志时,Win32 API EnumPrinters()函数将失败,并显示ERROR_INVALID_NAME错误代码。

  • TPrinter::Printers列表不包含默认打印机。 如果上面的EnumPrinters()没有报告默认的设备,那么将从Win32 API GetDefaultPrinter()函数(Delphi / C ++ Builder 2009及更高版本)或%windir%\win.ini[windows]部分的device值中查询默认值%windir%\win.ini (Delphi / C ++ Builder 2007及更早版本)。

TPrinter::SetToDefaultPrinter()仅被调用:

  • 如果FPrinterIndex成员当前为-1, TPrinter::PrinterIndex getter。

  • 如果FPrinterIndex成员当前为-1,或者属性设置为-1, TPrinter::PrinterIndex设置程序。

TPrintDialog::Execute() (使用Win32 API PrintDlg()函数)首先调用TPrinter::GetPrinter()获取当前选定打印机的DEVMODE的句柄,然后用它初始化对话框(通过PRINTDLG::hDevMode字段)。 TPrinter::GetPrinter()读取TPrinter::PrinterIndex属性,所以如果没有当前选定的打印机和没有默认的打印机,引发异常。

如果没有配置默认打印机,那么基本上是不幸的,因为您甚至无法将TPrinter::PrinterIndex属性设置为TPrinter::PrinterIndex 0的值,因为它在检查新值是否匹配之前将首先调用SetToDefaultPrinter()当前值。

当在Windows中没有配置默认打印机时, TPrinter具有很长的故障/崩溃历史。 要解决此问题,您应该直接调用Win32 API PrintDlg()函数。 至少可以手动调用TPrinter::GetPrinter() (获取最初的DEVMODE )并将其封装在try/catch块中,以放弃可能抛出的异常。

如果对话结果指示成功,则可以手动调用TPrinter::SetPrinter()将选定的打印机选项分配给TPrinter以供后续打印。

我在对话框使用之前检查打印机的存在:

 // check printer interface TPrinter *prn = Printer(); int pxs,pys,i=0; if (prn==NULL)i=1; if (prn->Printers==NULL) i=1; if (prn->Printers->Count<=0) i=1; if (i) return; // use dialog dlg_print->Options.Clear(); dlg_print->Options<<poPrintToFile; if (!dlg_print->Execute()) return; // print prn = Printer(); pxs=prn->PageWidth; pys=prn->PageHeight; prn->BeginDoc(); for (i=0;i<dlg_print->Copies;i++) { if (i) prn->NewPage(); // here render page into prn->Canvas as image in resolution pxs,pys } prn->EndDoc(); 

其中dlg_print是我的对话框放置在窗体上。