2013-04-29 2 views
1

Я застрял на проблемы были, я хотел бы попросить о помощи:FindNextPrinterChangeNotification возвращает NULL для ppPrinterNotifyInfo

У меня есть задание, чтобы напечатать несколько файлов разных типов с использованием ShellExecuteEx с «печать» глаголом и нужно гарантируйте порядок печати всех файлов. Поэтому я использую FindFirstPrinterChangeNotification и FindNextPrinterChangeNotification для отслеживания событий PRINTER_CHANGE_ADD_JOB и PRINTER_CHANGE_DELETE_JOB с использованием двух разных потоков в фоновом режиме, которые я запускаю перед вызовом ShellExecuteEx, поскольку я ничего не знаю о приложении, которое будет печатать файлы и т. Д. Единственное, что я знаю, это то, что Я единственная печать и файл, который я печатаю. Мое решение, похоже, хорошо работает, моя программа успешно распознает событие PRINTER_CHANGE_ADD_JOB для моего файла, я даже проверяю, что это событие выдается для моего файла, проверяя, что мне дает дополнительную информацию, указав JOB_NOTIFY_FIELD_DOCUMENT.

Проблема теперь связана с событием PRINTER_CHANGE_DELETE_JOB, где я не получаю дополнительной информации о задании на печать, хотя моя логика для обоих событий одинакова: я написал одну общую функцию потока, которая просто выполняется с событием, для которого он используется. Мой поток распознает событие PRINTER_CHANGE_DELETE_JOB, но при каждом вызове FindNextPrinterChangeNotification всякий раз, когда это событие происходило, я не получаю никаких дополнительных данных в ppPrinterNotifyInfo. Это работает для события начала, однако, я проверил использование моих журналов и отладчика. Но с PRINTER_CHANGE_DELETE_JOB я получаю только NULL.

Я уже искал в Интернете, и есть некоторые подобные вопросы, но большую часть времени относится к VB или просто без ответа. Я использую проект на C++, и поскольку мой код работает для события ADD_JOB, я не думаю, что я делаю что-то совершенно неправильное. Но даже MSDN не упоминает об этом поведении, и я действительно хотел бы удостовериться, что событие DELETE_JOB является единственным для моего документа, и я не могу без какой-либо информации о задании на печать. После того, как я получаю событие DELETE_JOB, мой код даже не распознает другие события, это нормально, потому что после этого выполняется задание на печать.

Ниже то, что я думаю, что соответствующий код уведомления:

WORD      jobNotifyFields[1] = {JOB_NOTIFY_FIELD_DOCUMENT}; 
PRINTER_NOTIFY_OPTIONS_TYPE pnot[1]    = {JOB_NOTIFY_TYPE, 0, 0, 0, 1, jobNotifyFields}; 
PRINTER_NOTIFY_OPTIONS  pno     = {2, 0, 1, pnot}; 
HANDLE      defaultPrinter  = PrintWaiter::openDefaultPrinter(); 
HANDLE      changeNotification = FindFirstPrinterChangeNotification( defaultPrinter, 
                         threadArgs->event, 
                         0, &pno); 
[...] 
DWORD waitResult = WAIT_FAILED; 
while ((waitResult = WaitForSingleObject(changeNotification, threadArgs->wfsoTimeout)) == WAIT_OBJECT_0) 
{ 
    LOG4CXX_DEBUG(logger, L"Irgendein Druckereignis im Thread zum Warten auf Ereignis " << LogStringConv(threadArgs->event) << L" erkannt."); 

[...] 
    PPRINTER_NOTIFY_INFO notifyInfo = NULL; 
    DWORD     events  = 0; 
    FindNextPrinterChangeNotification(changeNotification, &events, NULL, (LPVOID*) &notifyInfo); 
    if (!(events & threadArgs->event) || !notifyInfo || !notifyInfo->Count) 
    { 
     LOG4CXX_DEBUG(logger, L"unpassendes Ereignis " << LogStringConv(events) << L" ignoriert"); 
     FreePrinterNotifyInfo(notifyInfo); 
     continue; 
    } 
[...] 

Я был бы очень признателен, если кто-нибудь может дать некоторые подсказки о том, почему я не получаю никаких данных о задании на печать. Благодаря!

https://forums.embarcadero.com/thread.jspa?threadID=86657&stqc=true

ответ

0

Вот что я думаю, что происходит:

Я наблюдаю два события в двух разных потоках для начала и окончания каждого задания печати. При некоторой отладке и регистрации я понял, что FindNextPrinterChangeNotification не всегда возвращает только два разных события, о которых я уведомлял, но некоторые 0-события в целом. В тех случаях FindNextPrinterChangeNotification возвращает 0 как события в pdwChange. Если я печатаю простой текстовый файл с помощью notepad.exe, я получаю только одно событие для создания задания печати со значением 256 для pdwChange и данных, которые мне нужны в notifyInfo для сравнения моего напечатанного имени файла и сравнения обоих успешных результатов. Если я распечатаю pdf-файл с использованием текущего Acrobat Reader 11, я получаю два события, у одного есть pdwChange как 256, но дает что-то вроде «local printdatafile» в качестве имени задания на печать, которое, очевидно, не является файлом, который я напечатал. Второе событие имеет pdwChange 0, но имя задания печати, предоставленного в notifyInfo, - это имя файла, которое я использовал для печати. Поскольку я использую FreePDF для тестирования pruproses, я думаю, что первое событие принтера является чем-то внутренним для моей специальной настройки.

Уведомления об удалении задания на печать также создают 0 событий. На этот раз они отправляются до того, как FindNextPrinterChangeNotification вернет 1024 в pdwChange и своевременно закроется после начала задания на печать.В этом случае только одно сгенерированное событие 0 содержит notifyInfo с именем документа, которое равно имени файла, которое я начал печатать. После события 0 есть ровно одно дополнительное событие с pdwChange 1024, но без каких-либо данных для notifyInfo.

Я думаю, что Windows использует какой-то механизм, который предоставляет дополнительные уведомления для того же события, что и 0 событий после того, как начальное событие было запущено с его реальным значением, которое пользователь уведомляет, например. 256 для PRINTER_CHANGE_ADD_JOB. С другой стороны, кажется, что некоторые 0 событий просто запускаются для предоставления данных для предстоящего события, которое затем получает реальное значение, например. 1024 для PRINTER_CHANGE_DELETE_JOB, но без данных, поскольку это уже было доставлено потребителю событий с очень ранним событием 0. Что-то вроде «Послушайте, для последних событий есть больше». и «Послушайте, что-то произойдет с данными, которые я уже предоставляю сейчас». Внедряя такой подход, мои отпечатки теперь работают так, как ожидалось.

Конечно, то, что я написал, не соответствует тому, что документировано для FindNextPrinterChangeNotification, но для меня это немного имеет смысл. ;-)

+0

Любая причина, по которой это объяснение было проголосовано? Даже MSDN говорит что-то о сворачивающихся событиях, нескольких событиях событий в одном уведомлении и т. Д. –

0

Вы не проверяете наличие переполнений или ошибок.

Документация FindNextPrinterChangeNotification говорит следующее:

Если PRINTER_NOTIFY_INFO_DISCARDED бит установлен в элементе Flags из структуры PRINTER_NOTIFY_INFO, переполнение или произошла ошибка, и уведомления могут быть потеряны. В этом случае никакие дополнительные уведомления не будут отправлены, пока вы не сделаете второй вызов FindNextPrinterChangeNotification, который указывает PRINTER_NOTIFY_OPTIONS_REFRESH.

Вам необходимо проверить этот флаг и выполнить описанные выше действия, и вы также должны проверить код возврата от FindNextPrinterChangeNotification.

+0

Я уже добавил проверку ошибок, но это ничего не изменило в отношении моей проблемы, и никакие данные никогда не были отброшены. Отброшенные события всегда являются ошибкой в ​​моем случае, так как мне нужно знать, было ли задание на печать удалено, и это событие также могло быть отброшено и больше никогда не будет отправлено. –

Смежные вопросы