Win32 API Print not asking user input - c++

We have something like Secure Print.
I go to my control panel >> Printers and Devices >> Printer >> Printer Preference Here i assign a 4 digit pin code ..
I fire a print from Word or Excel ... go to the printer >> retrieve jobs >> select my print job and enter my pin code.
Only then my job gets printed.
Now Our application has two source codes for printing
While firing print from our Application the print is instantaneously done .... I.e. it doesn't store my job in the queue and wait for pin ... but just prints immediately
Some source code
bResult = OpenPrinter(szDevice, &hPrinter, NULL);
// szDevice contains printer name
startDocPrtInfo.pDocName = msg;
startDocPrtInfo.pOutputFile = NULL;
startDocPrtInfo.pDatatype = "RAW";
bPrntErr = (StartDocPrinter(hPrinter,1,(LPBYTE)&startDocPrtInfo) == 0);
WritePrinter(hPrinter, &buffer[2], i, &cnt);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
The Code is printing the given document however its not waiting for user to enter his pin code
QUESTION How to make the above code wait just like its doing for other applications ? is there some setting that I am missing here ?
To give you more details .
We have another Print subroutine in the same application that works as desierd .. I.e. waits for User to enter his PIN
However the subroutine uses TextOut method instead of WritePrinter
Any idea why print is not waiting when i use the WritePrinter methods of printing?
Thanks in Anticipation CP

I resolved this.
There is NO CODE CHANGES.
In our Printer Settings, we need to UNCHECK the "Allow Escape Sequence"
Thanks to the forum tho for entertaining the question.
Will visit often with more questions and resolutions to Questions that others raise
Good Luck
A Clueless Programmer :)

Related

How to reprint the C++ print request file

If personal information is included in the requested print using C++ language, cancel the current print and print again after receiving approval from the server.
※This event is raised when the user directly outputs an open file.
(In other words, if the user directly requests printing of an open file in the same way as ctrl+p, printing will be requested for the open file because the dll I created works.)
Approval is at EndDoc, the point at which the print is almost finished.
The problematic part is how to print again.
I was using the implementation to request a print again as shown below.
[refer to variable]
RequestDevModeW -> When printing is requested for the first time, the information is saved and used for reprint. (Saved when calling DocumentPropertiesW API.)
RequestDOCInfoW -> When printing is requested for the first time, the information is saved and used for reprint. (This is a structure stored in StartDocW when requesting a print for the first time.)
nPageCnt -> The number of startpage <-> Endpage is stored when the first print request is made.
[Code]
//... skip ...//
hReprintDC = CreateDCW(NULL, wszPrintName, NULL, &RequestDevModeW);
if (hReprintDC)
{
RequestDOCInfoW.lpszDocName = (LPCWSTR)wszDocName;
StartDocW(hReprintDC, &RequestDOCInfoW);
for (int nPage = 0; nPage < nPageCnt; ++nPage)
{
StartPage(hReprintDC);
EndPage(hReprintDC);
}
EndDoc(hReprintDC);
DeleteDC(hReprintDC);
g_hRePrintDC = NULL;
}
//... skip ...//
However, the code above is causing an error when displaying textbox in some documents (excel, word).
So I used the ShellExecuteEX API.
It prints very well, but I can't get the print attributes to work.
What I mean by print properties is that you have no control over these details, such as printing specific pages.
I'm curious about how to make a detailed request for a print using C++ code.
In addition, the print dialog should be output as it is with the existing specifications without being displayed.

User input without newline?

Basically I need user input for an integer, I tried these methods:
#include <iostream>
int main() {
int PID;
scanf("%i",&PID); //attempt 0
cin >> PID; //attempt 1
}
any ideas?
Most command-line input methods require the user to press ENTER to signal the end of the input, even if the app does not use the line break.
If you do not want the user to end the input with ENTER then you will likely have to resort to reading the input 1 character at a time and handle data conversions manually. The problem is, without a line break, how do you know when the user has finished typing the input? When the user has typed X number of characters/digits? What if the user types fewer then your max? Start a timer and stop reading when the user stops typing for X seconds? See the problem?
Line breaks are not something to be ignored. You should re-design your input logic to accept them, not avoid them. If that is really not an option, then maybe you need to re-think why you are creating a command-line app in the first place instead of a GUI app where the user can press a button when ready.

Implementing a printer spooler

We have an assignment in which we have to implement a printer spooler using linked lists. I have used the list from STL to implement everything. I can get the program to send the print command and maintain status of documents. The problem is I don't know how to mimic/send a dummy print command so the document gets printed. If I use Sleep() there is a delay in the whole program.while I want printing on backhand and others users to have access to the program.
Any help will be appreciated regarding my problem thanks.
In a REAL print spooler, either there are multiple threads (or in Unix, maybe a fork) or the system uses a "wait for several objects" type approach, and when there is something to print, a portion of the document is sent to the printer, set up so that when that portion is "consumed", a waitable object is "ready". Then the spooler waits for something to happen (either a new job or the printed). When the wait is completed, it determines what happened. If it's a new print job, queue it, if it's "some printing completed", it checks if that's the last of the printing and completes the job, or sends more stuff to the printer.
In pseudocdoe it may look something like this:
for(;;)
{
what = wait_for_work();
switch (what)
{
case new_job:
add_new_job();
break;
case print_write_done:
if (document_complete)
remove_current_job();
else
send_more_from_current_job();
break;
case spooler_terminate:
exit(0);
default:
print_error_message();
}
}
Obviously, without seeing your code, it's hard to say how you should implement it. But one could have a timer to simulate the "document being printed in small chunks", say, 10KB is consumed every 100ms, for example.

FindNextPrinterChangeNotification returns NULL for ppPrinterNotifyInfo

I'm stuck on problem were I would like to ask for some help:
I have the task to print some files of different types using ShellExecuteEx with the "print" verb and need to guarantee print order of all files. Therefore I use FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification to monitor the events PRINTER_CHANGE_ADD_JOB and PRINTER_CHANGE_DELETE_JOB using two different threads in the background which I start before calling ShellExecuteEx as I don't know anything about the application which will print the files etc. The only thing I know is that I'm the only one printing and which file I print. My solution seems to work well, my program successfully recognizes the event PRINTER_CHANGE_ADD_JOB for my file, I even verify that this event is issued for my file by checking what is give to me as additional info by specifying JOB_NOTIFY_FIELD_DOCUMENT.
The problem now is with the event PRINTER_CHANGE_DELETE_JOB, where I don't get any addition info about the print job, though my logic is exactly the same for both events: I've written one generic thread function which simply gets executed with the event it is used for. My thread is recognizing the PRINTER_CHANGE_DELETE_JOB event, but on each call to FindNextPrinterChangeNotification whenever this event occured I don't get any addition data in ppPrinterNotifyInfo. This works for the start event, though, I verified using my logs and the debugger. But with PRINTER_CHANGE_DELETE_JOB the only thing I get is NULL.
I already searched the web and there are some similar questions, but most of the time related to VB or simply unanswered. I'm using a C++ project and as my code works for the ADD_JOB-event I don't think I'm doing something completely wrong. But even MSDN doesn't mention this behavior and I would really like to make sure that the DELETE_JOB event is the one for my document, which I can't without any information about the print job. After I get the DELETE_JOB event my code doesn't even recognize other events, which is OK because the print job is done afterwards.
The following is what I think is the relevant notification code:
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;
}
[...]
I would really appreciate if anyone could give some hints on why I don't get any data regarding the print job. Thanks!
https://forums.embarcadero.com/thread.jspa?threadID=86657&stqc=true
Here's what I think is going on:
I observe two events in two different threads for the start and end of each print job. With some debugging and logging I recognized that FindNextPrinterChangeNotification doesn't always return only the two distinct events I've notified for, but some 0-events in general. In those cases FindNextPrinterChangeNotification returns 0 as the events in pdwChange. If I print a simple text file using notepad.exe I only get one event for creation of the print job with value 256 for pdwChange and the data I need in notifyInfo to compare my printed file name against and comparing both succeeds. If I print a pdf file using current Acrobat Reader 11 I get two events, one has pdwChange as 256, but gives something like "local printdatafile" as the name of the print job started, which is obviously not the file I printed. The second event has a pdwChange of 0, but the name of the print job provided in notifyInfo is the file name I used to print. As I use FreePDF for testing pruproses, I think the first printer event is something internal to my special setup.
The notifications for the deletion of a print job create 0 events, too. This time those are sent before FindNextPrinterChangeNotification returns 1024 in pdwChange, and timely very close after the start of the print job. In this case the exactly one generated 0 event contains notifyInfo with a document name which equals the file name I started printing. After the 0 event there's exactly one additional event with pdwChange of 1024, but without any data for notifyInfo.
I think Windows is using some mechanism which provides additional notifications for the same event as 0 events after the initial event has been fired with it's real value the user notified with, e.g. 256 for PRINTER_CHANGE_ADD_JOB. On the other hand it seems that some 0 events are simply fired to provide data for an upcoming event which then gets the real value of e.g. 1024 for PRINTER_CHANGE_DELETE_JOB, but without anymore data because that has already been delivered to the event consumer with a very early 0 event. Something like "Look, there's more for the last events." and "Look, something is going to happen with the data I already provide now." Implementing such an approach my prints now seem to work as expected.
Of course what I wrote doesn't fit to what is documented for FindNextPrinterChangeNotification, but it makes a bit of sense to me. ;-)
You're not checking for overflows or errors.
The documentation for FindNextPrinterChangeNotification says this:
If the PRINTER_NOTIFY_INFO_DISCARDED bit is set in the Flags member of
the PRINTER_NOTIFY_INFO structure, an overflow or error occurred, and
notifications may have been lost. In this case, no additional
notifications will be sent until you make a second
FindNextPrinterChangeNotification call that specifies
PRINTER_NOTIFY_OPTIONS_REFRESH.
You need to check for that flag and do as described above, and you should also be checking the return code from FindNextPrinterChangeNotification.

WritePrinter not asking for PIN Code

We have something like Secure Print.
I go to my control panel >> Printers and Devices >> Printer >> Printer Preference
Here i assign a 4 digit pin code ..
I fire a print from Word or Excel ... go to the printer >> retrieve jobs >> select my print job and enter my pin code.
Only then my job gets printed.
Now Our application has two source codes for printing
While firing print from our Application the print is instantaneously done .... I.e. it doesn't store my job in the queue and wait for pin ... but just prints immediately
Some source code
bResult = OpenPrinter(szDevice, &hPrinter, NULL);
// szDevice contains printer name
startDocPrtInfo.pDocName = msg;
startDocPrtInfo.pOutputFile = NULL;
startDocPrtInfo.pDatatype = "RAW";
bPrntErr = (StartDocPrinter(hPrinter,1,(LPBYTE)&startDocPrtInfo) == 0);
WritePrinter(hPrinter, &buffer[2], i, &cnt);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
~~~~~
The Code is printing the given document however its not waiting for user to enter his pin code
QUESTION
How to make the above code wait just like its doing for other applications ? is there some setting that I am missing here ?
Thanks in Anticipation
CP
I resolved this.
There are NO CODE CHANGES.
In our Printer Settings, we UNCHECKED the "Allow Escape Sequence" and it worked.
Thanks to the forum tho for entertaining the question.
Will visit often with more questions and resolutions to Questions that others raise
Good Luck
A Clueless Programmer :)