Solved

function to resume all paused print jobs + delphi

Posted on 2006-06-29
6
844 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Enroll in June's Course of the Month

June's Course of the Month is now available! Every 10 seconds, a consumer gets hit with ransomware. Refresh your knowledge of ransomware best practices by enrolling in this month's complimentary course for Premium Members, Team Accounts, and Qualified Experts.

Question has a verified solution.

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

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Come and listen to Percona CEO Peter Zaitsev discuss what’s new in Percona open source software, including Percona Server for MySQL (https://www.percona.com/software/mysql-database/percona-server) and MongoDB (https://www.percona.com/software/mongo-…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

695 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