我有一台HP收据打印机A799,它连接并控制一个抽屉 如果有任何打印信号发送到打印机,打印机将发送信号打开抽屉。 有两个问题。
第一个问题:
如果我在程序中添加了Printer.BeginDoc和Printer.EndDoc,我可以成功向打印机发送命令。(我尝试向打印机发送测试打印请求,这是成功的)
但问题是当我尝试发送查询命令,例如询问打印机将抽屉状态发送给我时,它还会将纸张送到一行并打开抽屉。
此操作的原因是Printer.BeginDoc和Printer.EndDoc?我尝试将它们从我的代码中删除,但是当我现在向打印机发送任何命令时,打印机和抽屉都不会做任何事情。
第二个问题:
ExtEscape(Printer.Handle, PASSTHROUGH, SizeOf(BufferIN), @BufferIn, 4, @BufferOut)
BufferIn和BufferOut也是PChar 我使用此功能带到打印机,我已经尝试此功能是工作(尝试测试打印)
我尝试将查询命令发送到打印机,但在此之后BufferOut没有得到任何返回,它仍然是一个空的PChar。
有没有人有任何解决方案?
答案 0 :(得分:2)
我会回答你的第一个问题 - 第二个问题应该转到这里的另一个帖子,并作为一个单独的问题提出。
您可以直接使用Print Spooler API(来自WinSpool.pas设备),在不使用BeginDoc / EndDoc的情况下向打印机发送内容。这是一个将文件直接打印到打印机的示例(几年前由TeamB的Peter Below发布在旧的Borland / CodeGear Delphi论坛之一):
uses
WinSpool;
procedure PrintFile(const sFileName: string);
const
BufSize = 16384;
var
Count, BytesWritten: integer;
hPrinter: THandle;
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port : array[0..255] of char;
hDeviceMode: THandle;
DocInfo: TDoc_Info_1;
f: file;
Buffer: Pointer;
begin
Printer.PrinterIndex := -1;
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
if not WinSpool.OpenPrinter(@Device, hPrinter, nil) then exit;
DocInfo.pDocName := 'MyDocument';
DocInfo.pOutputFile := nil;
DocInfo.pDatatype := 'RAW';
if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
begin
WinSpool.ClosePrinter(hPrinter);
exit;
end;
if not StartPagePrinter(hPrinter) then
begin
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
exit;
end;
System.Assign(f, sFileName);
try
Reset(f, 1);
GetMem(Buffer, BufSize);
while not eof(f) do
begin
Blockread(f, Buffer^, BufSize, Count);
if Count > 0 then
begin
if not WritePrinter(hPrinter, Buffer, Count, BytesWritten) then
begin
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
FreeMem(Buffer, BufSize);
exit;
end;
end;
end;
FreeMem(Buffer, BufSize);
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
finally
System.Closefile( f );
end;
end;
这是一个读取我发现的打印机状态的示例(再次由TeamB的Peter下载) - 它在Delphi 2007中进行了测试,因此可能需要对Delphi的更高版本的某些类型进行一些小的调整:
Uses WinSpool;
function GetCurrentPrinterStatus: DWORD;
var
hPrinter: THandle;
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port : array[0..255] of char;
hDeviceMode: THandle;
bytesNeeded, bytesWritten: Cardinal;
pPI: PPrinterInfo2;
Defaults: TPrinterDefaults;
begin
Assert( Printer.PrinterIndex >= 0 );
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
FillChar( Defaults, Sizeof(Defaults), 0 );
Defaults.DesiredAccess:=
PRINTER_ACCESS_ADMINISTER or PRINTER_ACCESS_USE;
Win32Check(WinSpool.OpenPrinter(@Device, hPrinter, @Defaults ));
try
WinSpool.GetPrinter(
hPrinter,
2,
Nil, 0, @bytesNeeded );
GetMem( pPI, bytesNeeded );
try
Win32Check(WinSpool.GetPrinter(
hPrinter, 2,
pPI, bytesNeeded, @bytesNeeded ));
Result := pPI^.Status;
finally
FreeMem( pPI );
end;
finally
WinSpool.ClosePrinter( hPrinter );
end;
end;
API文档为您提供有关PRINTER_INFO_2及其返回的标志的更多信息。您可以使用以下内容检查特定标志:
if (Status and PRINTER_STATUS_ERROR) <> 0 then
// Printer is in error status