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;
Printers是专门用来控制打印机的,可是在没有安装打印机时,却会提示I/O错误,所以必须有一个检测是否存在打印机的方法,我试过很多方法,可是I/O错误总是比我的判断早出现,所以采用以下的烂招来检测打印机。首先在uses增加Printers,再准备一个列表框ComboBox1,其属性Visible设为FALSE,然后在打印之前执行下列语句,那么就可以检测到是否存在打印机了:procedure TForm1.ButtonClick(Sender: Tobject); begin ComboBox1.Clear; ComboBox1.Items.Assign(Printer.Printers); if ComboBox1.Items.CommaText='' then Messagedlg('你需要安装打印机才能打印!',mtError,[mbOk],0); else Form1.Print; end;这个方法有点烂,不过简单,比上一种。
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;
begin
ComboBox1.Clear;
ComboBox1.Items.Assign(Printer.Printers);
if ComboBox1.Items.CommaText='' then
Messagedlg('你需要安装打印机才能打印!',mtError,[mbOk],0);
else
Form1.Print;
end;这个方法有点烂,不过简单,比上一种。