发送打印机特定命令

时间:2012-03-21 20:23:42

标签: delphi binary-data magnetic-cards

我有一个问题,我正在尝试将磁条数据编码到Fargo DTC400打印机,在规格中我说我需要从示例记事本,wordpad等发送以下字符串命令:

~1%TRACK NUMBER ONE?
~2;123456789?
~3;123456789?

此示例对第一个轨道中的字符串进行编码,并在轨道2和3中对数字123456789进行编码。这可以从Notepad.exe中进行。

修改 我使用的当前delphi代码适用于另一台打印机:

procedure SendQuote(MyCommand : AnsiString);
var
  PTBlock       : TPassThrough;

begin
  PTBlock.nLen := Length(MyCommand);
  StrPCopy(@PTBlock.SData, MyCommand);
  Escape(printer.handle, PASSTHROUGH, 0, @PTBlock, nil);
end;

当我尝试从我自己的应用程序编码此字符串时,我遇到麻烦,似乎打印机完全无视我的命令,当我选择打印到文件时,我可以读取二进制数据并在打印文件中查看我的字符串,当我尝试从示例notepad.exe打印到文件时,我得到的只是rubish二进制数据,根本找不到我的字符串......

所以我想知道记事本发送的这个字符串命令是什么,我不这样做?

希望有人能够阐明这一点,因为我一直渴望在我的申请中实施远程支持更长时间。

感谢

更新 下面的代码很古老,但是它可以完成这项工作,但是我可以用另一种方法将它与上面的Passthrough代码一起使用吗?

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 个答案:

答案 0 :(得分:4)

TPassThrough应该像这样声明:

type 
  TPassThrough = packed record 
    nLen  : SmallInt; 
    SData : Array[0..255] of AnsiChar; 
  end; 

您可能正在使用现代Delphi(2009或更新版本)或忘记了打包指令。

另请参阅此问题correct-way-to-send-commands-directly-to-printer

Torry's,有一个示例代码段(由FatihÖlçer编写): 备注:修改后也用于Unicode Delphi版本。

{
  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;