?
Solved

function to resume all paused print jobs + delphi

Posted on 2006-06-29
6
Medium Priority
?
891 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 1400 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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 600 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
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…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month9 days, 7 hours left to enroll

762 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