Announcement

Collapse
No announcement yet.

Cancel Print Jobs

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cancel Print Jobs

    Anyone have a command to cancel all print jobs?
    I do a lot of background printing and would
    like to cancel jobs from within a program.
    How long is an idea? Write it down.

  • #2
    Mike --
    During the search, I found VB code, which could be useful for you
    (I didn't test it)
    Code:
    Public Declare Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, pPrinter As Byte, ByVal Command As Long) As Long
    
    Public Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As Any) As Long
    
    Public Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long 
    
    Public Const PRINTER_CONTROL_PURGE = 3
    
    'DeletePrinterJob
    Sub DeletePrinterJob()
    
    Dim PrinterName$
    Dim ret&
    Dim hPrinter&
    
    PrinterName = Printer.DeviceName 
    ret = OpenPrinter(PrinterName, hPrinter, 0) 
    ret = SetPrinter(hPrinter, 0, vbNull, PRINTER_CONTROL_PURGE) 
    ret = ClosePrinter(hPrinter) 
    
    End Sub


    ------------------

    Comment


    • #3
      Code:
      'Any help on getting a routine for cancelling printer 
      'would be appreicated.  
      
      'PrinterName = Printer.DeviceName  'where does that come from?
      'Anyway this compiles, but doesn't do anything.  
      'What types should be used?
      
      #COMPILE EXE
      #DIM ALL
      #REGISTER NONE
      
      '  size of a device name string
      %CCHDEVICENAME                               = 32
      '  size of a form name string
      %CCHFORMNAME                                 = 32
      %NULL                                        = 0
      TYPE DEVMODE
        dmDeviceName AS ASCIIZ * %CCHDEVICENAME
        dmSpecVersion AS WORD
        dmDriverVersion AS WORD
        dmSize AS WORD
        dmDriverExtra AS WORD
        dmFields AS DWORD
        dmOrientation AS INTEGER
        dmPaperSize AS INTEGER
        dmPaperLength AS INTEGER
        dmPaperWidth AS INTEGER
        dmScale AS INTEGER
        dmCopies AS INTEGER
        dmDefaultSource AS INTEGER
        dmPrintQuality AS INTEGER
        dmColor AS INTEGER
        dmDuplex AS INTEGER
        dmYResolution AS INTEGER
        dmTTOption AS INTEGER
        dmCollate AS INTEGER
        dmFormName AS ASCIIZ * %CCHFORMNAME
        dmLogPixels AS WORD
        dmBitsPerPel AS DWORD
        dmPelsWidth AS DWORD
        dmPelsHeight AS DWORD
        dmDisplayFlags AS DWORD
        dmDisplayFrequency AS DWORD
        dmICMMethod AS DWORD
        dmICMIntent AS DWORD
        dmMediaType AS DWORD
        dmDitherType AS DWORD
        dmICCManufacturer AS DWORD
        dmICCModel AS DWORD
      '  dmPanningWidth AS DWORD     ' this & below apply if WINVER >= &H500
      '  dmPanningHeight AS DWORD    ' ...or if _WIN32_WINNT >= &H400
      END TYPE
      TYPE ACL
        AclRevision AS BYTE
        Sbz1 AS BYTE
        AclSize AS WORD
        AceCount AS WORD
        Sbz2 AS WORD
      END TYPE
      
      TYPE SECURITY_DESCRIPTOR
        Revision AS BYTE
        Sbz1 AS BYTE
        nControl AS WORD
        Owner AS LONG
        Group AS LONG
        Sacl AS ACL PTR
        Dacl AS ACL PTR
      END TYPE
      
      TYPE SYSTEMTIME
        wYear AS INTEGER
        wMonth AS INTEGER
        wDayOfWeek AS INTEGER
        wDay AS INTEGER
        wHour AS INTEGER
        wMinute AS INTEGER
        wSecond AS INTEGER
        wMilliseconds AS INTEGER
      END TYPE
      
      TYPE JOB_INFO_2
        JobId AS DWORD
        pPrinterName AS ASCIIZ PTR
        pMachineName AS ASCIIZ PTR
        pUserName AS ASCIIZ PTR
        pDocument AS ASCIIZ PTR
        pNotifyName AS ASCIIZ PTR
        pDatatype AS ASCIIZ PTR
        pPrintProcessor AS ASCIIZ PTR
        pParameters AS ASCIIZ PTR
        pDriverName AS ASCIIZ PTR
        pDevMode AS DEVMODE PTR
        pStatus AS ASCIIZ PTR
        pSecurityDescriptor AS SECURITY_DESCRIPTOR PTR
        STATUS AS DWORD
        Priority AS DWORD
        Position AS DWORD
        StartTime AS DWORD
        UntilTime AS DWORD
        TotalPages AS DWORD
        nSize AS DWORD
        Submitted AS SYSTEMTIME
        time AS DWORD
        PagesPrinted AS DWORD
      END TYPE
      TYPE PRINTER_DEFAULTS
        pDatatype AS ASCIIZ PTR
        pDevMode AS DEVMODE PTR
        DesiredAccess AS DWORD
      END TYPE
      
      DECLARE FUNCTION OpenPrinter LIB "WINSPOOL.DRV" ALIAS "OpenPrinterA" _
                       (pPrinterName AS ASCIIZ, _
                       phPrinter AS LONG,       _
                       pDefault AS PRINTER_DEFAULTS) AS LONG
      DECLARE FUNCTION SetPrinter LIB "WINSPOOL.DRV" ALIAS "SetPrinterA" _
                       (BYVAL hPrinter AS LONG, _
                       BYVAL Level AS LONG, _
                       pPrinter AS BYTE, _
                       BYVAL Command AS LONG) AS LONG
      DECLARE FUNCTION ClosePrinter LIB "WINSPOOL.DRV" ALIAS "ClosePrinter" _
                       (BYVAL hPrinter AS LONG) AS LONG
      FUNCTION PBMAIN AS LONG
           CALL DeletePrinterJob
      END FUNCTION
      
      SUB DeletePrinterJob()     'does printer name need to be passed here?
        DIM Command_Purge&
        Command_Purge& = 3 '
        DIM pPrinterName AS ASCIIZ * 64
        DIM ret&
        DIM phPrinter AS LONG              'Does this need PTR?
        DIM Level AS LONG
        DIM hPrinter AS LONG
        DIM pDefaults AS PRINTER_DEFAULTS
        
        ret = OpenPrinter(pPrinterName,  _
                          phPrinter,     _   'should this be a pointer?
                          pDefaults)
                          
        ret = SetPrinter(hPrinter&,      _
                         Level&,         _
                         %Null,          _
                         Command_PURGE&)
        ret = ClosePrinter(hPrinter&)   'does this come from setprinter?
      END SUB
      ------------------
      How long is an idea? Write it down.

      Comment


      • #4
        Mike --
        I tested Win32.Hlp (which you can download from http://www.powerbasic.com/files/pub/mstools/ ) and MSDN.
        OpenPrinter/SetPrinter/ClosePrinter are described very detail.


        ------------------

        Comment


        • #5
          Code:
          The definition in win32api.hlp.
          LPTSTR pPrinterName  //address of printer or server name
          Points to a null-terminated string
          Points to a variable that receives the handle
          Points to a Printer_Defaults
          Doesn't this mean pointers?
          
          Declarations in win32api.inc:
            pPrinterName AS ASCIIZ, _              'this is not a pointer
            phPrinter AS LONG,       _             'where is the pointer?
            pDefault AS PRINTER_DEFAULTS) AS LONG 
          
          Where are the pointers defined in the declaration file?
          This is why I have trouble using the .HLP file.
          When it uses points to doesn't mean pointer?
          ------------------
          How long is an idea? Write it down.

          Comment


          • #6
            Mike --
            This code works fine on my PC under Windows-98 (hope that under 95 also). About NT - not sure.

            Code:
                 #Compile Exe
                 #Register None
                 #Dim All
                 #Include "Win32Api.Inc"
            
                 Function PbMain
                    Dim PrinterName As Asciiz * 256, hPrinter As Long
                    GetProfileString "WINDOWS", "DEVICE", ",,,", PrinterName, SizeOf(PrinterName)
                    PrinterName = Left$(PrinterName$, Instr(PrinterName, ",") - 1)
                    OpenPrinter PrinterName, hPrinter, ByVal 0
                    SetPrinter hPrinter, 0, ByVal 0, %PRINTER_CONTROL_PURGE
                    ClosePrinter hPrinter
                 End Function

            ------------------

            Comment


            • #7
              Tried your code, it works great.
              Thank you!

              ------------------
              How long is an idea? Write it down.

              Comment


              • #8
                Mike..

                Hopefully to uncloud this for you.
                Code:
                BOOL OpenPrinter(
                
                    LPTSTR  pPrinterName,	// address of printer or server name 
                    LPHANDLE  phPrinter,	// address of printer or server handle 
                    LPPRINTER_DEFAULTS  pDefault 	// address of printer defaults structure  
                   );
                LPTSTR pPrinterName is asking for the ADDRESS of the variable holding the printer or server name.
                In the WIN32API that is declared as pPrinterName AS ASCIIZ which does pass the ADDRESS of the variable.
                When a variable is passed BYREF (i.e. the default) in PB you are passing the 4 byte address of the
                variable. If you pass it BYVAL you are passing a copy of the value of the variable not the address
                of the variable. The ADDRESS does POINT to the data held in the variable and as such is a pointer.
                It seems that you are confusing a PTR Data type with a pointer to data.. which is confusing.
                Think of this possibly to help..
                Code:
                DIM myString as ASCIIZ * 120
                DIM myPTR as LONG
                DIM myStringPtr as ASCIIZ PTR
                
                myString = "MIKE"
                myPTR = VARPTR(myString)
                You obviously know that myString holds "MIKE" and that myPTR holds the address or pointer to myString..
                
                PRINT myString prints MIKE
                PRINT myPTR prints some numerical number (i.e. the address)
                
                myStringPtr = VARPTR(myString)
                PRINT @myStringPtr prints MIKE
                PRINT myStringPtr prints the SAME numerial number as myPTR above
                (i.e. the address of myString)
                The code above is funtionally the same but it is easier for us Basic programs not to have to deal
                directly with pointers. For example if you passes a PTR BYREF to a function you are actually passing
                the ADDRESS of the PTR type which can really get confusing.

                Regarding the LPHANDLE phPrinter. It is common knowledge and can be found in the help files that
                a HANDLE is a long in current day "methodology" and the LP indicated a pointer, hence in
                the Win32API it is declared phPrinter AS LONG. Notice it is NOT declared BYVAL so it is being passed
                BYREF (again the default in PB) so it is passing the ADDRESS (i.e. pointer) to the variable phPrinter..

                I don't know if this is more confusing or helps.. Hopefully it helps...


                ------------------
                Jim..
                [email protected]


                [This message has been edited by Jim Huguley (edited April 28, 2000).]
                Jim..

                Comment


                • #9
                  Jim,
                  I forgot that byref is the default. This will
                  definitely help me with other routines!
                  Thank you,
                  Mike



                  ------------------
                  How long is an idea? Write it down.

                  Comment


                  • #10
                    Mike..

                    My pleasure..


                    ------------------
                    Jim..
                    [email protected]
                    Jim..

                    Comment


                    • #11
                      Code:
                      'The code below works fine as long as #DEBUG ERROR ON
                      'is used.  Anyone know why it is needed?
                      'Otherwise I sometimes receive a GPF in
                      'Kernel32 017f;bff719fb
                      
                      #DEBUG ERROR ON
                      #COMPILE EXE
                      #REGISTER NONE
                      #DIM ALL
                      #INCLUDE "Win32Api.Inc"
                      FUNCTION PBMAIN
                         CALL CancelPrintJob
                      END FUNCTION
                      SUB CancelPrintJob
                        DIM LineNumber AS LONG
                        ON ERROR GOTO CancelPrintJobError
                      LineNumber = 10
                      DIM PrinterName AS ASCIIZ * 256, hPrinter AS LONG
                      LineNumber = 20
                      GetProfileString "WINDOWS", "DEVICE", ",,,", PrinterName, SIZEOF(PrinterName)
                      LineNumber = 30
                      PrinterName = LEFT$(PrinterName$, INSTR(PrinterName, ",") - 1)
                      LineNumber = 40
                      OpenPrinter PrinterName, hPrinter, BYVAL 0
                      LineNumber = 50
                      SetPrinter hPrinter, 0, BYVAL 0, %PRINTER_CONTROL_PURGE
                      ExitCancelPrintJob:
                      LineNumber = 60
                      ClosePrinter hPrinter
                      EXIT SUB
                      CancelPrintJobError:
                        MSGBOX "Error number" + STR$(ERR)+ " in Doty - CancelPrintJob at line "+STR$(ERR)
                        RESUME ExitCancelPrintJob
                      END SUB
                      ------------------
                      How long is an idea? Write it down.

                      Comment


                      • #12
                        Mike..

                        This is interesting.. From Win Help the third parameter of
                        SetPrinter is described as "LPBYTE pPrinter".. and it is defined
                        in the Win32API.Inc as "pPrinter AS BYTE".. LPBYTE is a pointer
                        to pPrinter(BYTE) which would be a LONG not a BYTE. I would
                        change the Declaration in the Win32API.Inc to "pPrinter AS LONG"
                        and see if the error goes away. As far as I know all pointers
                        are 4 bytes in width. Even the pointer to a BYTE. The interesting
                        point is that it is declared as BYREF by default which means
                        is should already be passing a pointer/address (i.e. 4 bytes)..
                        So I don't really know if this will make any difference... I may
                        just be howling at the moon..

                        p.s. You might also declare a BYTE.. set it to Zero and pass it
                        which, would probably be best anyway. That way you are passing
                        what it is asking for.



                        [This message has been edited by Jim Huguley (edited April 28, 2000).]
                        Jim..

                        Comment


                        • #13
                          You are "howling at the moon" (your words!)

                          As this parameter is being passed BYREF, you are passing a 32-bit pointer
                          (containing the address of) to the data that is expected at the address.
                          In other words, you are just passing a pointer to an arbitary memory location.

                          It is defined as a byte pointer in the API definition and the WIN32API.INC
                          file because this pointer's target data can be of varying length depending on
                          other parameters passed to SetPrinter. MS chose the byte type as it infers
                          that you are referring to the address of a byte-array - in reality, it
                          could be the address of any data as long as it is in the format expected by
                          the function.

                          The correct way to specify the 3rd parameter would be to pass the pointer
                          address BYVAL, and use the existing declaration, hence:
                          Code:
                          Call SetPrinter(hPrinter&, 5, BYVAL VARPTR(1stElementOfAnArrayOfPrinterInfo5structures(0), PrinterState&)
                          If the 3rd parameter is 'not required', then substitute BYVAL %NULL or use
                          BYVAL 0&. This ensures that you are passing a null-pointer and SetPrinter()
                          knows how to handle a null-pointer without causing a GPF.

                          ------------------
                          Lance
                          PowerBASIC Support
                          mailto:[email protected][email protected]</A>
                          Lance
                          mailto:[email protected]

                          Comment


                          • #14
                            Lance...

                            After all, it is Friday night here.... Don't guess you have any of those chocolate covered strawberries left


                            ------------------
                            Jim..
                            [email protected]
                            Jim..

                            Comment


                            • #15
                              Code:
                              'Lance,
                              ' Rewrote the thing and it no longer abends.
                              ' Problem is, it now doesn't do anything.
                              ' Also tried AbortPrinter(hPrinter) unsuccessfully.
                              '                         Help
                              
                              
                              #DEBUG ERROR ON
                              #COMPILE EXE
                              #REGISTER NONE
                              #DIM ALL
                              #INCLUDE "Win32Api.Inc"
                              TYPE PRINTER_INFO_5
                                pPrinterName AS ASCIIZ PTR
                                pPortName AS ASCIIZ PTR
                                Attributes AS DWORD
                                DeviceNotSelected AS DWORD
                                TransmissionRetryTimeout AS DWORD
                              END TYPE
                              
                              FUNCTION IsWin95() EXPORT AS LONG
                                LOCAL vi AS OSVERSIONINFO
                                vi.dwOsVersionInfoSize = SIZEOF(vi)
                                GetVersionEx vi
                                FUNCTION = (vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS)
                              END FUNCTION
                              
                              FUNCTION PBMAIN
                                 CALL CancelPrintJob
                              END FUNCTION
                              SUB CancelPrintJob
                                DIM ret AS LONG
                                DIM Level AS LONG
                                DIM Needed AS LONG
                                DIM Returned AS LONG
                                DIM hPrinter AS LONG
                                IF IsWin95 THEN Level = 5 ELSE Level = 4  'Printer structure to use
                              
                                IF Level = 5 THEN
                                   'First call to see how big WINDOWS 95 printer_info_5 structure
                                   CALL EnumPrinters(%PRINTER_ENUM_LOCAL, _
                                            BYVAL 0, _
                                            BYVAL Level, _
                                            BYVAL %NULL, _
                                            BYVAL 0, _
                                            needed&, _       'Size of structure in bytes
                                            returned&)
                                   DIM PI5(0) AS PRINTER_INFO_5
                                   REDIM PI5(needed& \ SIZEOF(PI5(0)))
                                   CALL EnumPrinters(%PRINTER_ENUM_LOCAL, _
                                            BYVAL 0, _
                                            BYVAL Level, _
                                            BYVAL VARPTR(PI5(0)), _
                                            needed&, _
                                            needed&, _
                                            returned&)                    'Number of printers
                                  'FOR Element = 0 TO Returned& - 1
                                  '    EntireString = EntireString + PI5(Element)[email protected]+","
                                  'NEXT
                                ELSE  '                      Windows NT
                                  'First call to see how big WINDOWS NT printer_info_4 structure
                                  CALL EnumPrinters(%PRINTER_ENUM_CONNECTIONS, _
                                          BYVAL 0, _
                                          BYVAL Level, _
                                          BYVAL %NULL, _
                                          BYVAL 0, _
                                          needed&, _  'Size of structure returned in needed&
                                          returned&)
                              
                                  DIM PI4(0) AS PRINTER_INFO_4
                                  REDIM PI4(needed& \ SIZEOF(PI4(0)))
                                  CALL EnumPrinters(%PRINTER_ENUM_CONNECTIONS, _ 'Use CONNECTIONS with NT
                                          BYVAL 0, _
                                          BYVAL Level, _
                                          BYVAL VARPTR(PI4(0)), _
                                          needed&, _
                                          needed&, _
                                          returned&)                      'Number of printers
                              
                                  'FOR Element = 0 TO Returned& - 1
                                  '  EntireString = EntireString + PI4(Element)[email protected]+","
                                  'NEXT
                                END IF
                                'GetPrinterNames = LEFT$(EntireString,LEN(EntireString)-1)
                              
                                'DIM PrinterArray(1) AS Printer_INFO_5   'Lance, is this correct?
                              
                                DIM LineNumber AS LONG
                                ON ERROR GOTO CancelPrintJobError
                              LineNumber = 10
                              'DIM PrinterName AS ASCIIZ * 256, hPrinter AS LONG
                              'LineNumber = 20
                              
                              'GetProfileString "WINDOWS", "DEVICE", ",,,", PrinterName, SIZEOF(PrinterName)
                              
                              'LineNumber = 30
                              'PrinterName = LEFT$(PrinterName$, INSTR(PrinterName, ",") - 1)
                              'LineNumber = 40
                              
                              IF Level = 5 THEN
                                MSGBOX (PI5(0)[email protected])  'Printer_info5
                                ret = OpenPrinter (PI5(0)[email protected], hPrinter, BYVAL %NULL)
                                MSGBOX "Open printer "+STR$(ret) + "hPrinter = "+ STR$(hPrinter)
                                CALL AbortPrinter(hPrinter)
                                'CALL SetPrinter (hPrinter&,  _
                                '                 Level, _
                                '                 BYVAL VARPTR(PI5(0)), _   'Lance is this correct?
                                '                 %PRINTER_CONTROL_PURGE)
                                '                'BYVAL VARPTR(1stElementOfAnArrayOfPrinterInfo5structures(0), _
                              ELSE
                                MSGBOX (Pi4(0)[email protected])
                                ret = OpenPrinter (PI4(0)[email protected], hPrinter, BYVAL %NULL)    'Printer_Info4
                                MSGBOX "OpenPrinter "+STR$(ret)+ " hPrinter ="+STR$(hPrinter)
                                CALL AbortPrinter(hPrinter)
                                'CALL SetPrinter (hPrinter&,  _
                                '                 Level, _
                                '                 BYVAL VARPTR(PI4(0)), _   'Lance is this correct?
                                '                 %PRINTER_CONTROL_PURGE)
                                '                 'BYVAL VARPTR(1stElementOfAnArrayOfPrinterInfo5structures(0), _
                              END IF
                              ExitCancelPrintJob:
                              ClosePrinter hPrinter
                              EXIT SUB
                              CancelPrintJobError:
                                MSGBOX "Error number" + STR$(ERR)+ " in Doty - CancelPrintJob at line "+STR$(ERR)
                                RESUME ExitCancelPrintJob
                              END SUB
                              ------------------
                              How long is an idea? Write it down.

                              Comment


                              • #16
                                Originally posted by Mike Doty:
                                [code]
                                'The code below works fine as long as #DEBUG ERROR ON
                                'is used. Anyone know why it is needed?
                                'Otherwise I sometimes receive a GPF in
                                'Kernel32 017f;bff719fb
                                [/b]
                                Mike --
                                1) Which OS do you use ?
                                2) You receive GPF in debugger or during ordinary start ?
                                If second, I can't understand effect of #DEBUG ERROR ON, which compiler should ignore.



                                ------------------

                                Comment


                                • #17
                                  The problem (at least for Windows NT and 2000) is that to Use SetPrinter(), you must have opened the printer with administration rights.

                                  I've posted some working (Win2000) code into the source code forum - it uses PRINTER_INFO_2 so it should work on all platforms.

                                  It loops through all local & network printers and deletes all print jobs that are not currently printing.

                                  If this code does not enumerate the printers in Win95/98, change the calls to EnumPrinters() to use just %PRINTER_ENUM_LOCAL, but it should work ok.

                                  I hope this helps.


                                  ------------------
                                  Lance
                                  PowerBASIC Support
                                  mailto:[email protected][email protected]</A>
                                  Lance
                                  mailto:[email protected]

                                  Comment


                                  • #18
                                    Lance,
                                    Tested it with Windows 98 SE and it works great.
                                    It is a very valuable routine for me.
                                    Thank you, sir!
                                    Mike

                                    ------------------
                                    How long is an idea? Write it down.

                                    Comment

                                    Working...
                                    X