One of your issues with the PDF is that it is different from other reports, but this one is already different because you a requiring the user to remember never to print from preview.
Well, the requirement to not print from preview was the status quo ante. The objective of this thread's underlying question was to get rid of this requirement.
and how quickly your queue sampling code got to it.
That was a problem with the polling of the printer queue suggested by others. Polling the queue is indeed problematic and for exactly this reason I rejected those suggestions. - My solution (outlined before and below) does not suffer from this problem.
Try the code below that uses Windows Management Instrumentation through the GetObject function to detect the status of remote print jobs.
This was that type of unverified AI output I asked not to post.
The
QueueStatus property does not exist and the translation of numeric status to text does not make sense to me with any of the actually existing status properties one could get from the WMI printer object.
But the fatal problem of this approach is something else...
Use a timer to poll the status every 500 ticks (half second).You can set a limit of 10 seconds, (20 polls) using a loop. Play with the polling frequency and total time until you feel it's right.
The code you posted takes on average 850 ticks to run when querying the queue of a
local printer already. I couldn't test it, but I'm convinced it will take longer for a remote print queue.
850 ticks is already much too long, to reliably catch a document in the queue of a PDF printer (which admittedly was/is not my primary concern).
I'm with RonPaii on the idea that this is ALSO an employee education problem.
I find it hard already to justify to educate users to not use an innocent keyboard shortcut like [CTRL]+[P]. - I personally hate it, when applications do not support generic standard shortcuts of the OS.
The idea to "guide" users by taking away well-known sensible features/functionality because the application cannot cope with them is a an absolute last resort to me. I strongly dislike the idea to make user's lives harder or more uncomfortable to make my work easier. This often is an easy approach to solve problems such as this one, but it is also a declaration of UX design bankruptcy by the developer.
Of course, pouring this amount of effort into this problem is highly questionable from an economic point of view. My client would have never approved this in advance and would be extremely upset if I would charge them for this in full without prior approval. - I won't.
I'm going to mark this thread as resolved now.
I pieced together all my individual proof-of-concept code snippets based on the
Printer Change Notification Functions API.
My solution sketched:
When the report is opened in preview, I create a change notification object using FindFirstPrinterChangeNotification monitoring the print spooler of the report's printer for new jobs being added to the queue.
Luckily I discovered the RegisterWaitForSingleObject function, which allows to wait for an Windows event (signal) and then have the OS create a new thread invoking a callback function in my VBA code.
Unfortunately, the FindNextPrinterChangeNotification intended to retrieve additional information about the event behaves not entirely predictable. So I query the print spooler using the GetJob API to check whether the print job raising the event matches my report.
If yes,
the report was printed.
My solution works reliably during runtime in my local environment. I will deploy this into the client's environment in the next couple of days and then will see if it also works reliably there.
I'm not sure yet if I will publish the source code for this. Certainly not before the client confirmed it working for them.
Of course, querying an external entity such as the print spooler to know if and when my report was printer is not the ideal solution. However, after my initial research and the discussions in this thread, I believe it is the only way this can be reliably achieved.
Thank you all for your valuable contributions to this thread and for all your suggestions.