当没有Windows默认打印机设置时,我需要打开打印机对话框。当设置Windows默认打印机时,它可以正常使用以下代码。
TPrintDialog *dlgPrint = new TPrintDialog(frmDisplayDetail);
if( dlgPrint->Execute()) { //code here }
但如果Windows中没有默认的打印机设置,dlgPrint->Execute()
会抛出异常:
没有选择默认打印机
要检查默认的打印机索引,我使用了Printer()->PrinterIndex
。没有Windows打印机设置时,此值无法访问:
错误E2122函数调用因地址XXX
处的未处理异常XXX而终止
我做错了吗?请提出解决方案。
答案 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}在检查新值是否与当前值匹配之前。
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
是我在窗体上放置的对话框。