"没有选择默认打印机"未设置Windows默认打印机时出错

时间:2017-02-17 18:56:36

标签: c++ windows c++builder printers network-printers

当没有Windows默认打印机设置时,我需要打开打印机对话框。当设置Windows默认打印机时,它可以正常使用以下代码。

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

但如果Windows中没有默认的打印机设置,dlgPrint->Execute()会抛出异常:

  

没有选择默认打印机

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

  

错误E2122函数调用因地址XXX

处的未处理异常XXX而终止

我做错了吗?请提出解决方案。

2 个答案:

答案 0 :(得分:3)

例外"当前没有选择默认打印机"仅在TPrinter::SetToDefaultPrinter()方法时抛出:

  • 使用(未记录的)ERROR_INVALID_NAME标记进行枚举时,Win32 API EnumPrinters()函数失败并显示PRINTER_ENUM_DEFAULT错误代码。

  • TPrinter::Printers列表不包含默认打印机。如果上面的EnumPrinters()未报告默认设备,则会从Win32 API GetDefaultPrinter()函数(Delphi / C ++ Builder 2009及更高版本)或device值查询默认设置。 [windows]的{​​{1}}部分(Delphi / C ++ Builder 2007及更早版本)。

%windir%\win.ini只能通过以下方式调用:

    如果TPrinter::SetToDefaultPrinter()成员当前为-1,则
  • TPrinter::PrinterIndex获取者。

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

FPrinterIndex(使用Win32 API PrintDlg()函数)首先调用TPrintDialog::Execute()来获取当前所选打印机TPrinter::GetPrinter()的句柄,然后将其用于初始化对话框(通过PRINTDLG::hDevMode字段)。 DEVMODE读取TPrinter::GetPrinter()属性,因此如果当前没有选择打印机且没有默认打印机,则抛出异常。

如果没有配置默认打印机,您基本上不走运,因为您甚至无法将TPrinter::PrinterIndex属性设置为值> = 0,因为它将首先调用{{1}在检查新值是否与当前值匹配之前。

当Windows中没有配置默认打印机时,

TPrinter::PrinterIndex有很长的失败/崩溃历史。要解决此问题,您应该直接调用Win32 API SetToDefaultPrinter()函数。至少在那时,您可以手动调用TPrinter(以获取初始PrintDlg())并将其包装在TPrinter::GetPrinter()块中以丢弃它可能抛出的任何异常。

如果对话框结果显示成功,您可以手动调用DEVMODE将所选打印机选项分配到try/catch以进行后续打印。

答案 1 :(得分:0)

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

// 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是我在窗体上放置的对话框。