From: Peter Below (TeamB) <100113.1101@compuXXserve.com>
Subject: Re: **Checking if Printer is attached to PC
Date: 13 Jan 2000 00:00:00 GMT
Message-ID:
Content-Transfer-Encoding: 8bit
References: <387D25F4.EC231252@sprintmail.com>
Content-Type: text/plain; charset=iso-8859-1
Organization: TeamB
Mime-Version: 1.0
Reply-To: 100113.1101@compuXXserve.com
Newsgroups: borland.public.delphi.winapi
In article <387D25F4.EC231252@sprintmail.com>, Jose wrote:
> I am trying to determine if I have a printer connected to my PC.
> The problem is that our laptops have the network printer installed
> (Program Settings) but sometimes the laptop is not connected to
> the network. When this happens, print jobs end up in the
> laptop's spooler but never get printed. When Windows is shut
> down it displays a warning saying that there's a print job not
> finished and that it will be lost if the computer is turned off.
> I know Windows has a setting to spool print jobs or to send them
> directly to the network but we don't want to change all our laptops.
>
> It looks like something like WM_SPOOLERSTATUS could do the job.
Perhaps. Add a message handler for it to your main form, private section:
procedure WMSpoolerstatus( var msg: TWMSpoolerstatus );
message WM_SPOOLERSTATUS;
Hit Shift-Ctrl-C to make the IDE add a implementation for the method.
Add an inherited statement. msg.JobStatus will be 0 if the spooler thinks
it is healthy and < 0 if it has an error. From the list of error codes
found in Windows.PAS (above PR_JOBSTATUS) a missing network printer may not
be seen as an error, so look at msg.JobsLeft. If this never decreases in
the messages you see the spooler cannot get rid of the jobs. Of course it is
hard to tell when enough time has passed so you might become suspicious.
You can try to use the WinSpool.EnumJobs API to query the spooler directly.
Example below. See the diverse JOB_STATUS* codes given in the help topic for
JOB_INFO_1 in win32.hlp. Note that the Status field is a bitset, it can contain
more than one of the status codes. Use expressions like
if (Status and JOB_STATUS_OFFLINE) <> 0 Then
... printer offline
uses Winspool, Printers;
function GetCurrentPrinterHandle: THandle;
var
Device, Driver, Port : array[0..255] of char;
hDeviceMode: THandle;
begin
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
if not OpenPrinter(@Device, Result, nil) then
RaiseLastWin32Error;
end;
Function SavePChar( 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;
PJobs = ^TJobs;
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('No jobs in queue')
else
For i:= 0 to Pred(numJobs) Do
memo1.lines.add( Format(
'Job %s, Status (%d): %s',
[SavePChar(pJ^[i].pDocument), pJ^[i].Status, SavePChar(pJ^[i].pStatus)] ));
finally
ClosePrinter( hPrinter );
end;
end;
Peter Below (TeamB) 100113.1101@compuserve.com)
No replies in private e-mail, please, unless explicitly requested!
Sent using Virtual Access 5.00 - download your freeware copy now
http://www.atlantic-coast.com/downloads/vasetup.exe