& quot; Не выбран принтер по умолчанию & quot; ошибка, когда принтер по умолчанию Windows не настроен

Мне нужно открыть диалоговое окно принтера, когда нет настроек принтера по умолчанию в Windows. Он работает нормально с приведенным ниже кодом, когда установлен принтер по умолчанию для Windows.

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

Но если в Windows нет настроек принтера по умолчанию, dlgPrint->Execute() выдает исключение:

Не выбран принтер по умолчанию

Чтобы проверить индекс принтера по умолчанию, я использовал Printer()->PrinterIndex, Это значение становится недоступным, когда нет настройки принтера Windows:

ошибка E2122 Вызов функции завершен необработанным исключением XXX по адресу XXX

Я делаю что-то неправильно? Пожалуйста, предложите решение.

-1

Решение

Исключение «В настоящее время не выбран принтер по умолчанию» выбрасывается только 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 для последующей печати.

2

Другие решения

Я проверяю наличие принтеров перед использованием диалога:

// 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 мой диалог размещен в форме.

0

По вопросам рекламы [email protected]