In the previous blog post, I mainly described how to get and set the system's default printer, this article will describe how to monitor the status of the printer in real-time, recording the printed documents, the number of copies printed, as well as the printing time and other printing information.
1. Printer Collapse Machine Technology
Before we formally introduce how to monitor the state of the printer in real time, we need to know about the printer collapse machine technology first.
An exclusive device is an exclusive device during the entire run of a program (job, user) until the program (job, user) finishes. The exclusive device of the system is limited (for example, a computer can only connect to a printer) and often does not meet the requirements of multiple processes, causing a large number of processes to be blocked by waiting for certain exclusive devices. On the other hand, the process of applying to a standalone device occupies the device during its entire operation, and the utilization rate is very low, resulting in an exclusive device being idle for a long time.
To solve this contradiction, the most common way is to use shared devices to simulate exclusive devices, thereby improving system efficiency and the utilization of exclusive equipment. The technology is the collapse machine technology (spool:simultaneous peripaheral operation on line).
The printer is a typical exclusive device, after the introduction of the collapse machine technology, the user's print request is passed to the spool system, rather than the actual distribution of the printer to the user. The spool system first requests an idle area on the disk, transfers the data that needs to be printed to the inside, and then hangs the user's print request onto the printer queue. If the printer is idle, a print request is taken from the printer queue and the data is fetched from the corresponding area of the disk to perform the print operation. Because the disk is shared, the spool system can respond to print requests at any time and cache the data to achieve exclusive device emulation of shared devices, thereby improving system efficiency and exclusive device utilization.
2. Enumerate the print tasks for the current printer
Some of the following print-related enumeration functions are available in the Windows API:
EnumForms (); Enumerate all page types supported by the current printer
EnumJobs (); Enumerate print tasks for the current printer
Enummonitors (); Enumerate available Monitors
Enumports (); Enumerate the available print ports
Enumprinterdrivers (); Enumerate printer drivers
EnumPrinters (); Enumerate printers
Enumprinterprocessors (); Enumerating Print processes
To monitor the printer status, we need to use the EnumJobs () function to enumerate the print tasks of the current printer. The function is prototyped as follows:
1 BOOL2 WINAPI3 EnumJobs (4 HANDLE hprinter,5 DWORD Firstjob,6 DWORD Nojobs,7 DWORD level,8 lpbyte Pjob,9 DWORD Cbbuf,Ten Lpdword pcbneeded, One Lpdword pcreturned A);
Where the parameter hprinter represents a handle to the printer object, and the parameter Firstjob represents the index of the first job to enumerate in the job list (index number starts at 0), the parameter nojobs represents the number of jobs to enumerate, and the level of the parameter, which can be 1 or 2. The parameter pjob represents the buffer of the JOB_INFO_X structure (x is determined by the parameter level), the parameter cbbuf represents the buffer size of the job_info_x structure, and the parameter pcbneeded is used to save the requested buffer length The parameter pcreturned indicates the number of structures loaded into the buffer.
3. Specific programming implementation
Once we understand the enumjobs () function, we can start writing the code.
3.1 Getting the Printer object handle
We know that the first parameter of the EnumJobs () function is the printer object handle hprinter, so before calling the EnumJobs () function, we need to get a handle to the printer object, which can be achieved by calling the OpenPrinter () function. The function prototype is:
1 BOOL 2 WINAPI 3 OpenPrinter (4 LPSTR pprintername,5 lphandle phprinter, 6 lpprinter_defaults pdefault7 );
Where the parameter pprintername is the name of the printer, and the parameter phprinter is the handle to the printer object we want to get.
3.2 Get print status
Once we get the handle to the printer object, we can use the enumjobs () function to enumerate the print tasks and get the print status. The implementation method is as follows:
1 /*2 * Function function: Display printer status3 * Remark:4 * Author: Blog Park is still indifferent5 */6 voidcprintdemodlg::showprinterstatus ()7 {8HANDLE PrinterHandle;//Printer Device handle9 Ten //detect if opening the printer device is successful One if(! OpenPrinter (M_strprintername.getbuffer (0), &PrinterHandle, NULL)) A return; - - DWORD nbyteneeded; the DWORD nreturned; - DWORD nbyteused; - - //get the number of jobs by calling the GetPrinter () function +printer_info_2* Pprinterinfo =NULL; -GetPrinter (PrinterHandle,2Null0, &nbyteneeded); +Pprinterinfo = (printer_info_2*) malloc (nbyteneeded); AGetPrinter (PrinterHandle,2, (LPBYTE) Pprinterinfo, nbyteneeded, &nbyteused); at - //Enumerate print tasks by calling the EnumJobs () function -job_info_2* pJobInfo =NULL; -EnumJobs (PrinterHandle,0, Pprinterinfo->cjobs,2Null0, -(Lpdword) &nbyteneeded, (Lpdword) &nreturned); -pJobInfo = (job_info_2*) malloc (nbyteneeded); in ZeroMemory (pJobInfo, nbyteneeded); -EnumJobs (PrinterHandle,0, Pprinterinfo->cjobs,2, (LPBYTE) pJobInfo, nbyteneeded, to(Lpdword) &nbyteused, (Lpdword) &nreturned); + - //detects whether there is currently a print task the if(Pprinterinfo->cjobs = =0) * return; $ Panax Notoginseng //Paper Type -CString strpagesize = _t (""); the if(pjobinfo[0].pdevmode->dmpapersize = =dmpaper_a4) +Strpagesize = _t ("A4"); A Else if(pjobinfo[0].pdevmode->dmpapersize = =dmpaper_b5) theStrpagesize = _t ("B5"); + - //number of copies printed $CString strprintcopies = _t (""); $Strprintcopies.format ("%d", pjobinfo[0].pdevmode->dmcopies); - - //Print Color theCString Strprintcolor = _t (""); - if(pjobinfo[0].pdevmode->dmcolor = =Dmcolor_color)WuyiStrprintcolor = _t ("Color"); the Else if(pjobinfo[0].pdevmode->dmcolor = =dmcolor_monochrome) -Strprintcolor = _t ("Black"); Wu - //Print Time AboutCString strsubmitted = _t (""); $Strsubmitted.format ("%d-%d-%d%d:%d:%d", -pjobinfo[0]. Submitted.wyear, pjobinfo[0]. Submitted.wmonth, pjobinfo[0]. Submitted.wday, -pjobinfo[0]. submitted.whour+8, pjobinfo[0]. Submitted.wminute, pjobinfo[0]. Submitted.wsecond); - A //Update printer Status list control +Updatedataprinterstatuslistctrl (pjobinfo[0].pdocument, Strpagesize, the strprintcopies, Strprintcolor, strsubmitted); - $ Free (pprinterinfo); the the //Turn off the printer device the ClosePrinter (printerhandle); the}
As you can see, in the above code, we first call the OpenPrinter () function to get the printer device handle PrinterHandle, and then call the GetPrinter () function to Printer_info_ The 2 structure object Pprinterinfo is assigned so that the number of printer jobs can be obtained further through Pprinterinfo->cjobs. We then enumerate the print task by calling the EnumJobs () function to assign a value to the Job_info_2 struct object pjobinfo. The JOB_INFO_2 structure stores a series of printer status information that we need to get. Finally, we call the Updatedataprinterstatuslistctrl () function to display the printer status information on a list control.
The program runs as shown in result 1. In the printer selection drop-down list, all the printers in the current system are listed, after selecting the printer to listen on, click on the Start Listener button to create a sub-thread to listen to the printer status (I'm using a virtual printer Adobe PDF because I don't have a printer attached). When a document is printed, the print status is displayed in the list in real time.
Figure 1 Printer Status monitoring
As can be seen from Figure 1, we can now get information on the printed document name, paper type, number of copies, print color, and print time. How can I get more printing information? such as the path to print documents, content, size, number of pages and other information, such as adding a custom header, footer, or watermark in the printed document. These features I am also in the further study of learning, which Bo friends if there is experience in this area, but also hope that the guidance, I will be greatly appreciated.
"VC + + Technology 003" Printing technology printer status monitoring