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