Solved

Info on WINSPOOL.PAS

Posted on 1998-09-18
6
1,357 Views
Last Modified: 2009-07-31
I need to count the pages printed from a PC. Printing is done from delphi applications I wrote, so I have control of th e print button.  The problem is that some of the printing is done from a WebBrowser component for which I only call a method Print. In other words I can code that runs when the user clicks on the print button. It looks like there is enough functionality in WINSPOOL.PAS to do this querying info from Print MAnager.  Does anybody know how to do this ?  I am thinkg of a function that would read info from print manager right after the print button is clicked. Events would be even better.

Thank you.
0
Comment
Question by:gilles2
  • 3
  • 3
6 Comments
 
LVL 5

Expert Comment

by:inter
ID: 1340103
Yes your are right, the info can be retreived using the

BOOL GetJob(
    HANDLE hPrinter,      // handle of printer
    DWORD JobId,      // job identifier value
    DWORD Level,      // data-structure level
    LPBYTE pJob,      // address of data-structure array
    DWORD cbBuf,      // count of bytes in array
    LPDWORD pcbNeeded );

before you should open the printer with OpenPrinter and havi the hPrinter handle. If I have a printer at hand I can test this. Anyway after succesfully opening the printer you call
var
  JobInfo :TJobInfo1;
  needed : DWORD;
begin
  OpenPrinter('Hp1',hPrinter,nil);
  if hPrinter <> 0 then
  begin
    GetJob(hPrinter, 1, 1, JobInfo, Sizeof(JobInfo), needed);
  end;
  ClosePrinter(hPrinter);
end;

upon return JobInfo has the following info init:
  TJobInfo1A = record
   JobId: DWORD;
   pPrinterName: PAnsiChar;
   pMachineName: PAnsiChar;
   pUserName: PAnsiChar;
   pDocument: PAnsiChar;
   pDatatype: PAnsiChar;
   pStatus: PAnsiChar;
   Status: DWORD;
   Priority: DWORD;
   Position: DWORD;
   TotalPages: DWORD;  <- What you want
   PagesPrinted: DWORD;
   Submitted: TSystemTime;
  end;
But we should have some delay if you can print in background...
regards, igor
0
 

Author Comment

by:gilles2
ID: 1340104
Thank you. That's exacly what I am looking for. I am having problems with


    GetJob(hPrinter, 1, 1, JobInfo, Sizeof(JobInfo), needed);

It expects a pointer for JobInfo. I tried just putting @ in front of it. It then compiles but crashes at runtime. Any suggestion ?

0
 
LVL 5

Accepted Solution

by:
inter earned 200 total points
ID: 1340105
Hi friend, I have able to makeout the following code work. To test
include printers.pas in uses together with winspool.pas. Add a list box to your for called LB and make the following a procedure(bind to a button or what ever)


var
  JobInfo: PJobInfo1;
  hPrinter: integer;
  returned, needed: DWORD;
begin
  lb.clear;
  getmem(JobInfo, 1000);
  try
    if OpenPrinter(PChar(printer.printers[0]), hPrinter, nil) then
    begin
      if EnumJobs(hPrinter, 0, 1, 1, JobInfo, 1000, needed, returned) then
      begin
        with JobInfo^ do
        begin
          lb.items.add('JobId: ' + IntToStr(JobId));
          lb.items.add(pPrinterName);
          lb.items.add(pMachineName);
          lb.items.add(pUserName);
          lb.items.add(pDocument);
          lb.items.add(pDatatype);
          lb.items.add(pStatus);
          lb.items.add('Status: ' + IntToStr(Status));
          lb.items.add('Priority:' + IntToStr(Priority));
          lb.items.add('Position:' + IntToStr(Position));
          lb.items.add('TotalPages: ' + IntToStr(TotalPages));
          lb.items.add('PagesPrinted:' + IntToStr(PagesPrinted));
//         Submitted: TSystemTime;
        end;
      end;
      ClosePrinter(hPrinter);
    end;
  finally
    freemem(JobInfo, 1000);
  end;
end;

regards, igor
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:gilles2
ID: 1340106
Thank you. It works. My only problem now is that I have to capture the info at the right time. Some jobs are in and out in no time. The option I am looking at right now is to use the message WM_SpoolerStatus(var Msg: TWMSPOOLERSTATUS); message WM_SPOOLERSTATUS;

This is called when jobs are added or removed from the queue. If the idle state of the printer is 'Paused' then I can print, the method WM_SpoolerStatus gets called when the job is added to the spooler, I get the job info, restart the printer. The job then prints. When it is finished printing (WM_SpoolerStatus is called again and I can see that Msg.JobsLeft has decreased) then I pause the printer again.

Does it make sense to you ?

Of course the problem now is how do I pause and restart the printer.

Thank you.
0
 

Author Comment

by:gilles2
ID: 1340107
Thank you. I got everything working now. Using the pausing seems to work.
0
 
LVL 5

Expert Comment

by:inter
ID: 1340108
Hi,
Sorry friend I was out at weekend. Thanks, now here for antthing...
regards, igor
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
loading dll from external path 1 210
problem when i try to pack my dll file with upx 9 71
Sending Gmail through Delphi 3 91
Mydac connection data base issue 3 139
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…
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…
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

910 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now