Мне нужно открыть диалоговое окно принтера, когда нет настроек принтера по умолчанию в Windows. Он работает нормально с приведенным ниже кодом, когда установлен принтер по умолчанию для Windows.
TPrintDialog *dlgPrint = new TPrintDialog(frmDisplayDetail);
if( dlgPrint->Execute()) { //code here }
Но если в Windows нет настроек принтера по умолчанию, dlgPrint->Execute()
выдает исключение:
Не выбран принтер по умолчанию
Чтобы проверить индекс принтера по умолчанию, я использовал Printer()->PrinterIndex
, Это значение становится недоступным, когда нет настройки принтера Windows:
ошибка E2122 Вызов функции завершен необработанным исключением XXX по адресу XXX
Я делаю что-то неправильно? Пожалуйста, предложите решение.
Исключение «В настоящее время не выбран принтер по умолчанию» выбрасывается только TPrinter::SetToDefaultPrinter()
метод, когда либо:
Win32 API EnumPrinters()
функция не работает с ERROR_INVALID_NAME
код ошибки при перечислении с (недокументированным) PRINTER_ENUM_DEFAULT
флаг.
TPrinter::Printers
список не содержит принтер по умолчанию. Если EnumPrinters()
выше не сообщает устройство по умолчанию, по умолчанию запрашивается из Win32 API GetDefaultPrinter()
функция (Delphi / C ++ Builder 2009 и более поздние версии) или device
значение [windows]
раздел %windir%\win.ini
(Delphi / C ++ Builder 2007 и более ранние версии).
TPrinter::SetToDefaultPrinter()
вызывается только:
TPrinter::PrinterIndex
добытчик, если FPrinterIndex
участник в настоящее время -1.
TPrinter::PrinterIndex
сеттер, если FPrinterIndex
member в настоящее время -1, или свойство устанавливается в -1.
TPrintDialog::Execute()
(который использует Win32 API PrintDlg()
функция) первые звонки TPrinter::GetPrinter()
чтобы справиться с DEVMODE
текущего выбранного принтера, который он затем использует для инициализации диалога (через PRINTDLG::hDevMode
поле). TPrinter::GetPrinter()
читает TPrinter::PrinterIndex
свойство, поэтому если в данный момент нет выбранного принтера и принтера по умолчанию, генерируется исключение.
Если принтер по умолчанию не настроен, вам в основном не повезло, поскольку вы даже не можете установить TPrinter::PrinterIndex
свойство к значению> = 0, так как оно будет сначала вызывать SetToDefaultPrinter()
перед проверкой, соответствует ли новое значение текущему значению.
TPrinter
имеет долгую историю сбоя / сбоя, когда в Windows не настроен принтер по умолчанию. Чтобы обойти это, вы должны вызвать 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
мой диалог размещен в форме.