![]() |
![]() |
|
![]() |
Win32 API and Printers Controlling Printers and Printer Jobs © 2002 Rick Kelly www.crooit.com Preface Libraries and forms (Paradox 9) presented are available as a download here. Paradox 8 is not supported although Paradox 7-32 surprisingly works. After downloading into the folder of your choice, make that folder :WORK: and run the included form for a demonstration. You'll need to run the form before opening it in design mode as it references table :PRIV:__PJobs that is created in the form's INIT event. (If running Paradox 10, or if the table doesn't get created properly, you should first run the BldSpool.ssl script prior to running the form.) Introduction Previous articles in this series:
Referenced Win32 APIs Win32 API method used to set or modify printer attributes. SetPrinter( hPrn cLong, cLevel cLong, pPrinter cLong, command cLong) cLong [stdcall "SetPrinterA"]hPrn - Handle to the printer cLevel = Level or type of printer information structure to return - always 0 for our use pPrinter - pointer to address printer structures - always 0 for our use command - Printer action command to invoke Win32 API methods used to retrieve and set print job attributes. SetJob( hPrn cLong, JobID cLong, cLevel cLong, pJob cLong, command cLong) cLong [stdcall "SetJobA"] GetJob( hPrn cLong, JobID cLong, cLevel cLong, pJob cLong, cdBuf cLong, pcbNeeded cPtr) cLong [stdcall "GetJobA"]hPrn - Handle to the printer JobID - Windows generated print job number cLevel = Level or type of job information structure to return pJob - pointer to address print job structures command - Print job action command to invoke cbBuf - Specifies the size, in bytes, of pJob pcbNeeded = size of memory needed to hold pJob Controlling Printer Status The three actions we will cover are:
In networked environments, you must have adequate permissions to perform these operations. As a check on your permissions, go to Start/Settings/Printers and right click on a printer and select Pause. If you can pause the printer, your permissions are ok. The Win32 API calls for all three actions are identical except for the command code used and we will use the following common procedure: Proc cmSendPrinterControl(var stPrinter String,liControlCode LongInt) Logical ; ; Pause/Purge/Resume Printer ; var liPrinterHandle LongInt liReturn LongInt loReturn Logical endVar liPrinterHandle = 0 loReturn = False switch case cmOpenPrinterAdmin(stPrinter,liPrinterHandle) = False : otherwise : liReturn = SetPrinter( liPrinterHandle, 0, 0, liControlCode) loReturn = (liReturn = 1) liReturn = ClosePrinter(liPrinterHandle) switch case loReturn = False : msgStop(stPrinter,"You don't have permission to modify the " + "settings for this printer. If you need to " + "change the settings, contact your network " + "administrator.") endSwitch endSwitch return loReturn endProcThe procedure "cmOpenPrinterAdmin" was covered in the previous article. With the following referenced constants representing each of the three commands, it is straightforward to develop "wrapper" methods for printer control. Const ; ; Printer Control Codes ; cnPrinterControlPause = 1 cnPrinterControlResume = 2 cnPrinterControlPurge = 3 endConst method PausePrinter(stPrinter String) Logical return cmSendPrinterControl(stPrinter,cnPrinterControlPause) endMethod method ResumePrinter(stPrinter String) Logical return cmSendPrinterControl(stPrinter,cnPrinterControlPause) endMethod method PurgePrinter(stPrinter String) Logical return cmSendPrinterControl(stPrinter,cnPrinterControlPause) endMethod Controlling Print Jobs The six actions we will cover are:
The Win32 API calls for all pausing, resuming, canceling and restarting print jobs are identical except for the command code used and we will use the following common procedure: Proc cmSendJobControl(var stPrinter String, var liJobID LongInt, liControlCode LongInt) Logical ; ; Pause/Purge/Resume Printer Jobs ; var liPrinterHandle LongInt liReturn LongInt loReturn Logical endVar liPrinterHandle = 0 loReturn = False ; ; Get a handle to the printer ; liReturn = OpenPrinter(stPrinter,liPrinterHandle,0) switch case liPrinterHandle = 0 : otherwise : liReturn = SetJob( liPrinterHandle, liJobID, 0, 0, liControlCode) loReturn = (liReturn = 1) liReturn = ClosePrinter(liPrinterHandle) endSwitch return loReturn endProcWith the following referenced constants representing each of the three commands, it is straightforward to develop "wrapper" methods for print jobs. Const ; ; Job Control Codes ; cnJobControlPause = 1 cnJobControlResume = 2 cnJobControlCancel = 3 cnJobControlRestart = 4 cnJobControlDelete = 5 endConst method PauseJob(stPrinter String,liJobID LongInt) Logical return cmSendJobControl(stPrinter,liJobID,cnJobControlPause) endMethod method ResumeJob(stPrinter String,liJobID LongInt) Logical return cmSendJobControl(stPrinter,liJobID,cnJobControlResume) endMethod method CancelJob(stPrinter String,liJobID LongInt) Logical ; ; Starting with NT4, the control code for a job cancel ; changed ; return cmSendJobControl(stPrinter,liJobID, iif(osi.OSPlatformID = 2 and osi.OSMajorVersion >= 4, cnJobControlDelete, cnJobControlCancel)) endMethod method RestartJob(stPrinter String,liJobID LongInt) Logical return cmSendJobControl(stPrinter,liJobID,cnJobControlRestart) endMethodNote the extra check for the Windows version (covered in the first article) when we want to cancel a print job. Adjusting a print jobs position in the spooler queue involves retrieving and updating the print job information attributes. The re-usuable procedure is shown below. Proc cmAdjustJobPosition(var stPrinter String, var liJobID LongInt, liDirection LongInt) Logical ; ; Adjust Print Job queue positon ; var liPrinterHandle LongInt liReturn LongInt loReturn Logical liSizeNeeded LongInt liMemoryStructure LongInt liPosition LongInt endVar liPrinterHandle = 0 loReturn = False switch ; ; Administrative access required ; case cmOpenPrinterAdmin(stPrinter,liPrinterHandle) = False : otherwise : liSizeNeeded = 0 ; ; Get Size of Job structure needed ; liReturn = GetJob( liPrinterHandle, liJobID, 1, 0, 0, liSizeNeeded) switch case liSizeNeeded = 0 : otherwise : ; ; Allocate memory for Job Info Level 1 Structure and fill it ; ; Job Info Level 1 Definition ; ; +0 JobID LongInt ; +4 PrinterName LongInt (Pointer) ; +8 MachineName LongInt (Pointer) ; +12 UserName LongInt (Pointer) ; +16 DocumentName LongInt (Pointer) ; +20 DataType LongInt (Pointer) ; +24 StatusString LongInt (Pointer) ; +28 Status LongInt ; +32 Priority LongInt ; +36 Position LongInt ; +40 TotalPages LongInt ; +44 PagesPrinted LongInt ; +48 SystemTime ; +48 Year SmallInt ; +50 Month SmallInt ; +52 WeekDay SmallInt ; +54 Day SmallInt ; +56 Hour SmallInt ; +58 Minute SmallInt ; +60 Second SmallInt ; +62 MilliSecond SmallInt ; liMemoryStructure = GlobalAlloc(fromHex("0x40"),liSizeNeeded) liReturn = GetJob( liPrinterHandle, liJobID, 1, liMemoryStructure, liSizeNeeded, liSizeNeeded) switch case liReturn <> 1 : otherwise : ; ; Retrieve current position, adjust it up or down ; and attempt to update job ; liPosition = 0 MoveFromMemory( liPosition, liMemoryStructure + 36,4) liPosition = liPosition + liDirection MoveToMemory( liMemoryStructure + 36, liPosition,4) liReturn = SetJob( liPrinterHandle, liJobID, 1, liMemoryStructure, 0) loReturn = (liReturn = 1) endSwitch GlobalFree(liMemoryStructure) endSwitch liReturn = ClosePrinter(liPrinterHandle) endSwitch return loReturn endProcOur supporting "wrappers" are: method MoveJobDown(stPrinter String,liJobID LongInt) Logical return cmAdjustJobPosition(stPrinter,liJobID,1) endMethod method MoveJobUp(stPrinter String,liJobID LongInt) Logical return cmAdjustJobPosition(stPrinter,liJobID,-1) endMethod Conclusion We now have methods that provide access to the Win32 API for controlling printers and print jobs. Next: Printing Directly to a Printer Discussion of this article |
![]() Feedback | Paradox Day | Who Uses Paradox | I Use Paradox | Downloads ![]() |
|
![]() The information provided on this Web site is not in any way sponsored or endorsed by Corel Corporation. Paradox is a registered trademark of Corel Corporation. ![]() |
|
![]() Modified: 15 May 2003 Terms of Use / Legal Disclaimer ![]() |
![]() Copyright © 2001- 2003 Paradox Community. All rights reserved. Company and product names are trademarks or registered trademarks of their respective companies. Authors hold the copyrights to their own works. Please contact the author of any article for details. ![]() |
![]() |
|