Od jakiegoś czasu bezskutecznie szukałem sposobu wydruku komend w języku EPL na drukarkę Zebra 2824 podłączoną do portu USB.
Kilka dni temu trafiłem na komponent SvRawPrinter, który pozwala na wysyłanie surowych danych na drukarkę.
Zainstalowałem, przetestowałem komponent i można powiedzieć, że połowicznie sprawa jest rozwiązana.
Chodzi o to, że ów komponent pozwala zarówno na wydruk pliku SvRawPrinter1.FilePrint(const FileName:TFileName) oraz wydruk samej komendy SvRawPrinter1.Print(const s: string).
Plik tekstowy w języku epl:
.
N
q812
S2
A50,300,0,3,2,2,R,"Example 6 0123456789"
LO25,600,750,20
B50,800,0,3,3,7,200,B,"998152-001"
P1
.
Wydruk powyższego pliku przebiega prawidłowo.
Problem pojawia się gdy chcę wydrukować kod z poziomu komendy Print
Próbowałem w ten sposób:
SvRawPrinter1.Print('.' +
'N' +
'q812' +
'S2' +
'A50,300,0,3,2,2,R,"Example 6 0123456789"' +
'LO25,600,750,20' +
'B50,800,0,3,3,7,200,B,"998152-001"' +
'P1' +
'.');
Drukarka ani drgnie.
Pomyślałem, że może chodzi o sposób zapisu więc wrzuciłem na formatkę RichEdit'a. Wkleiłem zawartość pliku i próbowałem drukować
SvRawPrinter1.Print(RichEdit1.Text) ale również nic z tego.
Komponent został napisany 2001 roku i nie ma kontaktu z autorem.
Poniżej załączam plik .pas oraz paczkę z całym komponentem
unit SvRawPrinter;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TSvCustomRawPrinter = class(TComponent)
private
{ Private declarations }
FPrinterName: string;
FJobTitle: string;
Handle: THandle;
function GetPrinterName: string;
procedure SetPrinterName(const APrinterName: string);
protected
{ Protected declarations }
property PrinterName: string read GetPrinterName write SetPrinterName;
property JobTitle: string read FJobTitle write FJobTitle;
public
{ Public declarations }
procedure Open;
procedure Close;
procedure Print(const S: String);
procedure FilePrint(const FileName: TFileName);
published
{ Published declarations }
end;
TSvRawPrinter = class(TSvCustomRawPrinter)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
property PrinterName;
property JobTitle;
end;
procedure Register;
implementation
uses WinSpool;
{$R *.dcr}
function TSvCustomRawPrinter.GetPrinterName: string;
begin
Result:=FPrinterName;
end;
procedure TSvCustomRawPrinter.SetPrinterName(const APrinterName: string);
var
P: integer;
begin
FPrinterName:=APrinterName;
P:= Pos(' on ', FPrinterName);
if P > 0
then
FPrinterName:= Copy(FPrinterName, 1, P - 1);
end;
procedure TSvCustomRawPrinter.Open;
var
DocInfo1: TDocInfo1;
begin
if not OpenPrinter(PChar(FPrinterName), Handle, nil)
then
case GetLastError of
87: Exception.create('Printer name does not exist');
else
Exception.create('Error ' + IntToStr(GetLastError));
end
else
begin
with DocInfo1 do
begin
pDocName:= PChar(FJobTitle);
pOutputFile:=nil;
pDataType:= 'RAW';
end;
StartDocPrinter(Handle, 1, @DocInfo1);
StartPagePrinter(Handle);
end;
end;
procedure TSvCustomRawPrinter.Close;
begin
EndPagePrinter(Handle);
EndDocPrinter(Handle);
ClosePrinter(Handle);
end;
procedure TSvCustomRawPrinter.Print(const S: String);
var
N: DWord;
begin
WritePrinter(Handle, PChar(S), Length(S), N);
if DWord(Length(S)) <> N
then
Exception.create('Error writing to printer');
end;
procedure TSvCustomRawPrinter.FilePrint(const FileName: TFileName);
var
FromF: File;
NumRead: Integer;
Buf: array[1..2048] of Char;
SBuf: string;
begin
AssignFile(FromF, FileName);
Reset(FromF, 1); { Record size = 1 }
try
Open;
try
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
while (NumRead > 0 ) do
begin
SBuf:= Buf;
SetLength(SBuf, NumRead);
Print(SBuf);
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
end
finally
Close;
end;
finally
CloseFile(FromF);
end;
end;
procedure Register;
begin
RegisterComponents('Sv', [TSvRawPrinter]);
end;
end.