Печать в XPS работает, на принтер — нет
Есть код, который выводит документ на печать. Всё замечательно работает для виртуального XPS-принтера, но при попытке вывести на реальный возникает ошибка, причём не в коде программы (я проверял коды возврата), а в самой очереди печати. У меня даже идей нет, в чём может быть дело. Ведь по сути, подсистема печати абстрагирует код от устройства, поэтому неважно, виртуальное оно или реальное — если код выводит в виртуальный принтер, то и в реальный должен выводить. Но на практике это почему-то не так. Что я делаю не так?
На всякий случай еще поле размера можно заполнить lpDI->cbSize=sizeof(*lpDI);
Остальные поля видимо можно оставить
Может дело в принтере? Если хотите, выложите экзешник - завтра вечером проверю на своем принтере. У меня импорт в Code::Blocks не удался, скомпилировать не смог.
Ну раз мы находимся в теме WIN32 API. То нужно смотреть в сторону GetPrinter, SetPrinter, GetPrinterData, SetPrinterData, OpenPrinter и т.д.
Короче потом нужно физический принтер сделать по умолчанию.
P/S
Типа так в трёх словах.
Принтер по умолчанию влиять не должен. Или что, если по умолчанию выбран XPS, то при попытке печати на другой я ошибку должен получить? Бред. Тем более, пробовалось и на системе, где установлен по умолчанию обычный принтер. То же самое.
Код:
BOOL OpenPrinter(
_In_ LPTSTR pPrinterName,
_Out_ LPHANDLE phPrinter,
_In_ LPPRINTER_DEFAULTS pDefault
);
_In_ LPTSTR pPrinterName,
_Out_ LPHANDLE phPrinter,
_In_ LPPRINTER_DEFAULTS pDefault
);
И что мне это дало? Объявление функции я смогу прекрасно посмотреть на MSDN, а для открытия принтера эта функция необязательна — принтер у меня выбирается с помощью PrintDlg(), а открывается для использования с помощью CreateDC().
По-умолчанию принтер реальный. С него и начинал. Файл NomenclatureList брал из изначального архива.
ОБНОВЛЕНИЕ ПОСТА
----------------------------------
С XPS-ом заработала и больше не тормозит с PDF принтером. Причина была в блокировке программы файрволом - доступ к памяти ему не понравился и он ее в песочницу поместил. Перенес в доверенные, больше не блокируется. Но с реальным принтером - все то же, также фатально вылетает с ошибкой.
MSDN для CreateDC в случае принтеров рекомендует первый параметр NULL, поскольку lpszDriver игнорируется для принтеров. Вряд ли поможет, но можно попробовать.
Цитата: sadovoya
MSDN для CreateDC в случае принтеров рекомендует первый параметр NULL, поскольку lpszDriver игнорируется для принтеров
Так я вроде и делал подобным образом (в архиве должна быть последняя версия кода). Это я вычитал, когда интересовался кодами ошибок функций. Как потом оказалось, они у меня ошибок не возвращали, но какая-то ошибка случалась в очереди печати.
Кстати, есть у тебя возможность отладить и посмотреть, в каком месте возникает ошибка, из-за которой приложение падает?
Посмотреть мне не получится в полной мере. Но ошибка явно в районе CreateDC, видимо сразу за ним.
Как запасной вариант: может на физический принтер лучше не рисовать, а временный файл делать и его печатать?
Program received signal SIGSEGV, Segmentation fault.
In wcslen () (C:\Windows\system32\msvcrt.dll)
Последнее, что происходит - постановка в очередь, потом крах.
Можешь выложить дебаговскую сборку с символами? Может удасться выудить что-то более понятное.
P.S. Самому мне собрать не удается, Code::Blocks нормально не импортирует ресурсы студийные. Сперва давала странную ошибку нехватки памяти - но это удалось победить, поменяв кодировку на UTF-8. Загадочная ситуация.. Но потом, стала просто на ресурсы как на сплошную синтаксическую ошибку ворчать :)
Сбойное приложение DocFolders.exe, версия 0.0.0.0, штамп времени 0x54dcbeb4, сбойный модуль msvcrt.dll, версия 7.0.6001.18000, штамп времени 0x4791a727, код исключения 0xc0000005, смещение ошибки 0x0000f3e7, ИД процесса 0x2d4, время запуска приложения 0x01d047ccc3e832d6.
Так, ну это уже днём… А вот wcslen() меня удивила — я же её не использую :) Да и MSVCRT тоже. Выложу тебе .pdb к релизу, наверное — для дебага тебе надо дебажные версии MSVCR….dll иметь.
Там дебажных библиотек потребуется возможно не одна :) Давай пока с .pdb попробую. Но экзешник релизный крохотный, скорее всего символы отладочные в нем не содержатся. Нет настроек сгенерить релиз без удаления лишних символов? У меня в компиляторе такое возможно.
Так-то да, я отключаю генерацию отладочной информации, но тут включил специально. Надеюсь, всё корректно.
DOCINFO* lpDI=(DOCINFO*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof DOCINFO);
lpDI->lpszDocName="нечто"; lpDI->... и т.д.
Код:
HDC hDC=CreateDC((LPSTR)dn+dn->wDriverOffset,LPSTR(dn)+dn->wDeviceOffset,0,dm);
Код:
HDC hDC=CreateDC((LPSTR)dn+dn->wDriverOffset,LPSTR(dn)+dn->wDeviceOffset,NULL,dm);
CreateDC - создать контекст устройства (DC)
OpenPrinter - открыть заданный принтер
Вам нужно понять , что есть спулер
Выше я печатал код , на который Вы громко стучали по клаве так вот
В переменной phPrinter нужно убедиться , что нет begin space and end space.
И соотвественно для мня тема закрыто.
Цитата: sadovoya
надо заполнить структуру DOCINFO
Откуда такое предположение? ☺
Просто в XPS же всё печатается и так, но если проблема только в отсутствии имени документа, то сделаю.
Цитата: UserNet2008
Изначально не надо путать 0 с ПУСТО (NULL)
Это одно и то же. Или NULL внезапно может не в 0 превратиться в данном коде? =)
Цитата: UserNet2008
CreateDC и OpenPrinter это есть разные понятие. Т.Е что автомобиль заводить замком багажника.
Рекомендую всё же почитать про CreateDC() и про печать от Microsoft.
ВСЁ ТЕМА ДЛЯ МНЯ CLOSE.
P/S
Не надо бычеться. Тема началось с Очень нужна ваша помощь.
Код:
...
if(hDC){
DOCINFO* lpDI=(DOCINFO*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof DOCINFO);
lpDI->lpszDocName="";//добавил
lpDI->cbSize=sizeof(*lpDI);//добавил
if(StartDoc(hDC,lpDI)>0){
...
if(hDC){
DOCINFO* lpDI=(DOCINFO*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof DOCINFO);
lpDI->lpszDocName="";//добавил
lpDI->cbSize=sizeof(*lpDI);//добавил
if(StartDoc(hDC,lpDI)>0){
...
Вот ведь засада, вроде не написано, что обязательно к заполнению, такая мелочь, но такие проблемы!
С форматированием буду разбираться, это уже второй вопрос =)
Я добавил проверку на ошибки функций открытия/закрытия документа/страницы, но они отрабатывают без ошибок. Не знаю, куда ещё копать.