Solved

function to resume all paused print jobs + delphi

Posted on 2006-06-29
6
809 Views
Last Modified: 2010-08-05
hi there!!!!!

i need a function in delphi that will resume all paused print jobs that are currently in the print job queue of the printer.

i have some code that resumes the printer but not the jobs. hope it helps. i need some urgent help.


***************************
procedure ResumePrinter;
var
  hPrinter : THandle;
  PrinterName : PChar;
  PrinterDefaults : TPrinterDefaultsA;
  DevMode : PDeviceModeA;
  Needed : integer;
  handle:thandle;
  begin
  try
    PrinterName := PChar(Printer.Printers[Printer.PrinterIndex]);
    WinSpool.OpenPrinter(PrinterName,hPrinter,nil);
    Needed := WinSpool.DocumentProperties(Handle,hPrinter,PrinterName,DevMode^,DevMode^,0);
      if Needed < 0 then
        begin
          exit;
        end;
  GetMem(DevMode,Needed);
  WinSpool.DocumentProperties(Handle,hPrinter,PrinterName,DevMode^,DevMode^,DM_COPY);
  PrinterDefaults.pDatatype := nil;
  PrinterDefaults.pDevMode := @DevMode^;
  PrinterDefaults.DesiredAccess := PRINTER_ALL_ACCESS;
  ClosePrinter(hPrinter);
  if OpenPrinter(PrinterName,hPrinter,@PrinterDefaults) then
    begin
      if WinSpool.SetPrinter(hPrinter,0,nil,PRINTER_CONTROL_RESUME) then
        begin
          ClosePrinter(hPrinter);
        end
    end;
  ClosePrinter(hPrinter);
  FreeMem(DevMode);
  except
  on e: exception do HandleException(e, 'ResumePrinter2000');
  end;
  end;
******************************



thanks a lot

0
Comment
Question by:nikolaosk
  • 2
  • 2
  • 2
6 Comments
 
LVL 26

Accepted Solution

by:
Russell Libby earned 350 total points
ID: 17010332

Below is an example of what you asking for. Please be aware though, that to be able to successfully call SetPrinter with a pause/resume command requires admin privs for the printer. Let me know if there are questions or problems.

Regards,
Russell



type
  PJob1Array        =  ^TJob1Array;
  TJob1Array        =  Array [0..1023] of TJobInfo1;

procedure ResumePrinterJobs;
var  lpJobs:        PJob1Array;
     lpDefaults:    TPrinterDefaults;
     hPrinter:      THandle;
     dwAlloced:     DWORD;
     dwNeeded:      DWORD;
     dwCount:       DWORD;
     dwIndex:       DWORD;
begin

  // Clear printer defaults
  FillChar(lpDefaults, SizeOf(TPrinterDefaults), 0);

  // This access is REQUIRED in order to pause / resume the printer itself
  lpDefaults.DesiredAccess:=PRINTER_ACCESS_ADMINISTER;

  // Open the default printer
  if OpenPrinter(PChar(Printer.Printers[Printer.PrinterIndex]), hPrinter, @lpDefaults) then
  begin
     // Resource protection
     try
        // Resume the printer
        if SetPrinter(hPrinter, 0, nil, PRINTER_CONTROL_RESUME) then
        begin
           // Enum the printer jobs
           if not(EnumJobs(hPrinter, 0, High(TJob1Array), 1, lpJobs, 0, dwNeeded, dwCount)) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
           begin
              // Set alloc size
              dwAlloced:=dwNeeded;
              // Allocate memory to get jobs
              lpJobs:=AllocMem(dwAlloced);
              // Resource protection
              try
                 // Enum the printer jobs
                 if EnumJobs(hPrinter, 0, High(TJob1Array), 1, lpJobs, dwAlloced, dwNeeded, dwCount) then
                 begin
                    // Iterate the job array
                    for dwIndex:=0 to Pred(dwCount) do
                    begin
                       // Check the job status
                       if ((lpJobs^[dwIndex].Status and JOB_STATUS_PAUSED) = JOB_STATUS_PAUSED) then
                       begin
                          // Resume the job
                          Win32Check(SetJob(hPrinter, lpJobs^[dwIndex].JobId, 0, nil, JOB_CONTROL_RESUME));
                       end;
                    end;
                 end
                 else
                    // Raise last win32 error
                    RaiseLastWin32Error;
              finally
                 // Free memory
                 FreeMem(lpJobs);
              end;
           end;
        end
        else
           // Raise last win32 error
           RaiseLastWin32Error;
     finally
        // Close the printer handle
        ClosePrinter(hPrinter);
     end;
  end
  else
     // Raise last win32 error
     RaiseLastWin32Error;

end;

 
0
 
LVL 10

Expert Comment

by:atul_parmar
ID: 17010340
Hi, the following will resume all the paused jobs for default printer. To resume for other printer, set PrinterName to the the printer for which you want to resume all the paused jobs.

proceure ResumeAllJobs;
var
  PrinterName : string;
  hPrinter : THandle;
  NumJobs : cardinal;
  pcbNeed,pcReturned:DWord;
  i : integer;
  Buffer: Pointer;
begin
  PrinterName := Printer.Printers[Printer.PrinterIndex];
  OpenPrinter(PAnsiChar(Printername), hPrinter, nil);
  NumJobs := 10;
  EnumJobs(hPrinter, 0, NumJobs, 2, nil, 0, pcbNeed, pcReturned);
  GetMem(Buffer, pcbNeed);
  if EnumJobs(hPrinter, 0, NumJobs, 2, Buffer, pcbNeed, pcbNeed, pcReturned) then
  begin
    for i := 1 to pcReturned do
    begin
      if TArrayofJobs(buffer^)[i].Status = JOB_STATUS_PAUSED then
        SetJob(hPrinter, TArrayofJobs(buffer^)[i].JobId, 0, nil, JOB_CONTROL_RESUME);
    end;
  end;
end;
0
 

Author Comment

by:nikolaosk
ID: 17011363
atul,

hi again

i get an error code

undeclared identifier:TArrayofJobs

please advise.
thanks
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 26

Expert Comment

by:Russell Libby
ID: 17011837

If your going to use atul's code, then you will also need to add in a call to FreeMem to avoid the memory leak.

Russell
0
 
LVL 10

Assisted Solution

by:atul_parmar
atul_parmar earned 150 total points
ID: 17016065
Hi, just copy and paste the following function.

type
  TArrayofJobs = array[1..1024] of JOB_INFO_2;

procedure ResumeAllJobs;
var
  PrinterName : string;
  hPrinter : THandle;
  NumJobs : cardinal;
  pcbNeed,pcReturned:DWord;
  i : integer;
  Buffer: Pointer;
  d : PRINTER_DEFAULTS;
begin
  PrinterName := Printer.Printers[Printer.PrinterIndex];
  FillChar(d, SizeOf(PRINTER_DEFAULTS), #0);
  d.DesiredAccess := PRINTER_ALL_ACCESS;
  OpenPrinter(PAnsiChar(Printername), hPrinter, @d);
  NumJobs := 10;
  EnumJobs(hPrinter, 0, NumJobs, 2, nil, 0, pcbNeed, pcReturned);
  GetMem(Buffer, pcbNeed);
  try
    if EnumJobs(hPrinter, 0, NumJobs, 2, Buffer, pcbNeed, pcbNeed, pcReturned) then
    begin
      for i := 1 to pcReturned do
      begin
        if TArrayofJobs(buffer^)[i].Status = JOB_STATUS_PAUSED then
          SetJob(hPrinter, TArrayofJobs(buffer^)[i].JobId, 0, nil, JOB_CONTROL_RESUME);
      end;
    end;
  finally
    FreeMem(Buffer, pcbNeed);
  end;
end;
0
 

Author Comment

by:nikolaosk
ID: 17016377
hi there!!!

both solutions worked.

but i did use rllibby's first.
thanks
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

791 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question