Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

I need a little description about EnumJobs API..

Posted on 2002-07-13
12
Medium Priority
?
339 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 135 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
Independent Software Vendors: 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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

721 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