Solved

I need a little description about EnumJobs API..

Posted on 2002-07-13
12
330 Views
Last Modified: 2010-08-05
Hi ,

  I have only 30 points now but i will increase available points of this qestion :)

  I want to manage printing jobs(job names,page number..etc) in shared network printer so i'm try to learn EnumJobs API but i can't understand the usage of Job_Info_1 and Job_Info_2 clearly . So i need short and clear example and explanation about how can i use Job_Info_x ?

Regards..  
0
Comment
Question by:Mozzak
[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
  • 8
  • 4
12 Comments
 

Author Comment

by:Mozzak
ID: 7151329
I had understand that Job_Info_x determines the record type which turns from EnumJobs API .  
0
 

Author Comment

by:Mozzak
ID: 7151331
I had understand that Job_Info_x determines the record type which turns from EnumJobs API .  
0
 
LVL 2

Accepted Solution

by:
mullet_attack earned 45 total points
ID: 7153729
this uses job_info_1

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winspool,
  StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button2Click(Sender: TObject);
var
  hPrinter : THandle;
  dwNeeded, dwReturned, i : DWORD;
  pJobInfo, pJob : PJobInfo1;
  MyJobInfo : TJobInfo1;
//  pJob : pointer;//pChar;
begin
  // subsitute your printer's name for mine !
  OpenPrinter('HP LaserJet III', hPrinter, nil);

   // First you call EnumJobs() to find out how much memory you need
   if not EnumJobs( hPrinter, 0, $FFFFFFFF, 1, Nil, 0, dwNeeded, dwReturned ) then
     begin
     // It should have failed, but if it failed for any reason other
     // than "not enough memory", you should bail out
       if not GetLastError = ERROR_INSUFFICIENT_BUFFER then
         begin
           ClosePrinter( hPrinter );
           exit;
         end;
     end;
   // Allocate enough memory for the JOB_INFO_1 structures plus
   // the extra data - dwNeeded from the previous call tells you
   // the total size needed
   try
     GetMem(pJobInfo,dwNeeded );
   except
     ClosePrinter( hPrinter );
     exit;
   end;

   // Call EnumJobs() again and let it fill out our structures
   if not EnumJobs(hPrinter, 0, $FFFFFFFF, 1, pJobInfo,
                   dwNeeded, dwNeeded, dwReturned ) then
     begin
       ClosePrinter( hPrinter );
       freemem( pJobInfo );
       exit;
     end;
   // You're done with the printer handle, close it
   ClosePrinter( hPrinter );

   // dwReturned tells how many jobs there are
   // Here, you'll simply display the number of jobs found
   memo1.lines.add(format('Number of jobs %d', [dwReturned]));

   // It's easy to loop through the jobs and access each one
   pJob := pointer(pChar(pJobInfo)); //twisted pointer arithmetic
   for i := 0 to dwReturned -1 do
     begin
       memo1.lines.add('');
       memo1.lines.add(format('Job Number %d', [i]));
       pJob := pointer(pChar(pJobInfo) + (Sizeof(TJobInfo1) * i));

     // so here you could do whatever you want for each job
        memo1.lines.add('Docment Name : ' + pJob^.pDocument); // get the document name
        memo1.lines.add('User Name : ' + pJob^.pUserName); // get the document name
        memo1.lines.add('Status : ' + pJob^.pStatus); // get the document name
     end;

   // Clean up
   freemem( pJobInfo );

end;

end.
0
Industry Leaders: 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!

 

Author Comment

by:Mozzak
ID: 7154082
I had try your code but It didn't work . I don't understand why everything seems ok .
0
 

Author Comment

by:Mozzak
ID: 7154086
I had try your code but It didn't work . I don't understand why everything seems ok .
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 7154146
Hmm, works fine here...

I'm using :

D5 SP2
Win2K SP2
used both local and network printer

drop a button on the form, call it Button2
deop a memo on the form, then paste the entire code into unit1.

Should work, if not, pls specify what doesn't work exactly.
0
 

Author Comment

by:Mozzak
ID: 7154208
I was open the new project then copy-paste your code to there without make any changes . Memo1 and Button2 but when i run and click the button2 and Memo1 stay the same . There was a printing jobs in queue but there wasn't anything shown in Memo1 .  

D6 SP2
Win98
Network Printer
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 7154277
when you "openPrinter" do you get a valid hPrinter?

does GetLastError = ERROR_INSUFFICIENT_BUFFER ?

does this work ? GetMem(pJobInfo,dwNeeded );
 
does the second call to enumjobs succeed?

if so, what's the value of dwReturned ?

0
 

Author Comment

by:Mozzak
ID: 7154472
I don't know but this works ;

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Printers, WinSpool, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    Function GetCurrentPrinterHandle: THandle;
    Function SafePChar( p: PChar ): PChar;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetCurrentPrinterHandle: THandle;
Const
    Defaults: TPrinterDefaults = (
      pDatatype : nil;
      pDevMode  : nil;
      DesiredAccess : PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER );
Var
    Device, Driver, Port : array[0..255] of char;
    hDeviceMode: THandle;
Begin { GetCurrentPrinterHandle }
    Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
    If not OpenPrinter(@Device, Result, @Defaults) Then
      RaiseLastWin32Error;
End; { GetCurrentPrinterHandle }

function TForm1.SafePChar(p: PChar): PChar;
const error: PChar = 'Nil';
begin
  if not assigned( p ) then
    result := error
  else
    result := p;
end;

procedure TForm1.Button2Click(Sender: TObject);
type
  TJobs = Array [0..1000] of JOB_INFO_1;    // Job_Info_1 tipinden bir array
  PJobs = ^TJobs;                           // PJobs ile TJobs array i iºaret ediyor
var
  hPrinter : THandle;
  bytesNeeded, numJobs, i: Cardinal;
  pJ: PJobs;                                
begin
  hPrinter:= GetCurrentPrinterHandle;
  try
    EnumJobs( hPrinter, 0, 1000, 1, Nil, 0, bytesNeeded,
              numJobs );
    pJ := AllocMem( bytesNeeded );
    If not EnumJobs( hPrinter, 0, 1000, 1, pJ, bytesNeeded,
                     bytesNeeded, numJobs )
    Then
      RaiseLastWin32Error;
      memo1.clear;
    if numJobs = 0 Then
      memo1.lines.add('There is not any job in queue')
    else
      For i:= 0 to Pred(numJobs) Do
        memo1.lines.add( Format('Job %s, Status (%d): %s, printer (%s), machine %s, totalpages %s, printedpage %s',[SafePChar(pJ^[i].pUserName), pJ^[i].Status, SafePChar(pJ^[i].pStatus),SafePChar(pJ^[i].pPrinterName),SafePChar(pJ^[i].pMachineName),inttostr(pJ^[i].TotalPages),inttostr(pJ^[i].PagesPrinted)]));
  finally
    ClosePrinter( hPrinter );
  end;
end;

end.
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 7154617
same thing, the only difference is you do this :

TJobs = Array [0..1000] of JOB_INFO_1;
PJobs = ^TJobs;              
var
 pJ: PJobs;                                

which makes it easier and neater to go thru the returned results. D6 probably doesn't like the PCHAR arithmetic that I did (I was in a hurry to write example).

anyway, it looks like you got what you wanted, an example of how to use jobinfo1, and you now have working code which is the desired result....

just a thought, when you cut-and-paste my code, did you re-attach the button's onclick event?
0
 

Author Comment

by:Mozzak
ID: 7154631
Yes , i have attached all the code . But i needed explanation of the enumjob code and you gave it to me . Thanks..
0
 

Author Comment

by:Mozzak
ID: 7155478
When the job start to printing , i can't take any information from the printer . I don't know why . Can you try this code for me ? What's wrong with this code ?

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Printers, WinSpool, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    Function GetCurrentPrinterHandle: THandle;
    Function SafePChar( p: PChar ): PChar;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetCurrentPrinterHandle: THandle;
Const
    Defaults: TPrinterDefaults = (
      pDatatype : nil;
      pDevMode  : nil;
      DesiredAccess : PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER );
Var
    Device, Driver, Port : array[0..255] of char;
    hDeviceMode: THandle;
Begin { GetCurrentPrinterHandle }
    Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
    If not OpenPrinter(@Device, Result, @Defaults) Then
      RaiseLastWin32Error;
End; { GetCurrentPrinterHandle }

function TForm1.SafePChar(p: PChar): PChar;
const error: PChar = 'Nil';
begin
  if not assigned( p ) then
    result := error
  else
    result := p;
end;

procedure TForm1.Button2Click(Sender: TObject);
type
  TJobs = Array [0..1000] of JOB_INFO_1;    // Job_Info_1 tipinden bir array
  PJobs = ^TJobs;                           // PJobs ile TJobs array i iºaret ediyor
var
  hPrinter : THandle;
  bytesNeeded, numJobs, i: Cardinal;
  pJ: PJobs;                                
begin
  hPrinter:= GetCurrentPrinterHandle;
  try
    EnumJobs( hPrinter, 0, 1000, 1, Nil, 0, bytesNeeded,
              numJobs );
    pJ := AllocMem( bytesNeeded );
    If not EnumJobs( hPrinter, 0, 1000, 1, pJ, bytesNeeded,
                     bytesNeeded, numJobs )
    Then
      RaiseLastWin32Error;
      memo1.clear;
    if numJobs = 0 Then
      memo1.lines.add('There is not any job in queue')
    else
      For i:= 0 to Pred(numJobs) Do
        memo1.lines.add( Format('Job %s, Status (%d): %s, printer (%s), machine %s, totalpages %s, printedpage %s',[SafePChar(pJ^[i].pUserName), pJ^[i].Status, SafePChar(pJ^[i].pStatus),SafePChar(pJ^[i].pPrinterName),SafePChar(pJ^[i].pMachineName),inttostr(pJ^[i].TotalPages),inttostr(pJ^[i].PagesPrinted)]));
  finally
    ClosePrinter( hPrinter );
  end;
end;

end.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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

Title # Comments Views Activity
Intraweb download file link ? 1 184
Delphi XE10 Round Image 2 227
Firemonkey DbLookupComboBox equivalent ? 2 78
migrate this code to work on android 1 45
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…
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…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

739 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