问题
I have an issue here, which I am trying to encode magnetic stripe data to an Fargo DTC400 printer, in the specifications it says I need to send the following string commands from example notepad, wordpad etc etc :
~1%TRACK NUMBER ONE?
~2;123456789?
~3;123456789?
this example encodes the string in track one, and the numbers 123456789 in both track 2 and 3.. this works from Notepad.exe.
EDIT: Current delphi code I use works on another printer:
procedure SendQuote(MyCommand : AnsiString);
var
PTBlock : TPassThrough;
begin
PTBlock.nLen := Length(MyCommand);
StrPCopy(@PTBlock.SData, MyCommand);
Escape(printer.handle, PASSTHROUGH, 0, @PTBlock, nil);
end;
when I am trying to encode this string from my own application I get trouble, it seems the printer is totally ignoring my commands, when I choose print to file, I can read the binary data and see my string in the printed file, when I try to print to file from example notepad.exe I get just rubish binary data and cannot find my strings at all...
so I wonder what does notepad do to send this string command which I dont ?
hope someone can shed light on this because I have been eager to implement fargo support in my application for a longer period of time .
thanks
Update. the following code is ancient but it does the job, however is there another way I can use this with the Passthrough code above?
var
POutput: TextFile;
k: Integer;
begin
with TPrintDialog.Create(self) do
try
if Execute then
begin
AssignPrn(POutput);
Rewrite(POutput);
Writeln(POutput,'~1%TESTENCODER?');
Writeln(POutput,'~2;123456789?');
Writeln(POutput,'~2;987654321?');
CloseFile(POutput);
end;
finally
free;
end
end;
回答1:
TPassThrough should be declared like this :
type
TPassThrough = packed record
nLen : SmallInt;
SData : Array[0..255] of AnsiChar;
end;
You might be using a modern Delphi (2009 or newer) or forgotten the packed directive.
See also this SO question for a correct-way-to-send-commands-directly-to-printer.
At Torry's there is an example snippet (written by Fatih Ölçer): Remark : Modified for use with Unicode Delphi versions as well.
{
By using the Windows API Escape() function,
your application can pass data directly to the printer.
If the printer driver supports the PASSTHROUGH printer escape,
you can use the Escape() function and the PASSTHROUGH printer escape
to send native printer language codes to the printer driver.
If the printer driver does not support the PASSTHROUGH printer escape,
you must use the DeviceCapabilities() and ExtDevMode() functions instead.
Mit der Windows API Funktion Escape() kann man Daten direkt zum Drucker schicken.
Wenn der Drucker Treiber dies nicht unterstützt, müssen die DeviceCapabilities()
und ExtDevMode() Funktionen verwendet werden.
}
// DOS like printing using Passthrough command
// you should use "printer.begindoc" and "printer.enddoc"
type
TPrnBuffRec = packed record
bufflength: Word;
Buff_1: array[0..255] of AnsiChar;
end;
function DirectToPrinter(S: AnsiString; NextLine: Boolean): Boolean;
var
Buff: TPrnBuffRec;
TestInt: Integer;
begin
TestInt := PassThrough;
if Escape(Printer.Handle, QUERYESCSUPPORT, SizeOf(TESTINT), @testint, nil) > 0 then
begin
if NextLine then S := S + #13 + #10;
StrPCopy(Buff.Buff_1, S);
Buff.bufflength := StrLen(Buff.Buff_1);
Escape(Printer.Canvas.Handle, Passthrough, 0, @buff, nil);
Result := True;
end
else
Result := False;
end;
// this code works if the printer supports escape commands
// you can get special esc codes from printer's manual
// example:
printer.BeginDoc;
try
DirectToPrinter('This text ');
finally
printer.EndDoc;
end;
来源:https://stackoverflow.com/questions/9812264/sending-printer-specific-commands