Отправка специальных команд принтера - PullRequest
1 голос
/ 22 марта 2012

У меня возникла проблема: я пытаюсь закодировать данные магнитной полосы на принтер Fargo DTC400, в спецификациях которого указано, что мне нужно отправить следующие строковые команды из примера блокнота, WordPad и т. Д. И т. Д .:*

в этом примере кодируется строка на первой дорожке, а номера 123456789 на дорожках 2 и 3 ... это работает из Notepad.exe.

РЕДАКТИРОВАТЬ: Текущий код Delphi IИспользование работает на другом принтере:

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, я получаю только бинарные двоичные данные и вообще не могу найти свои строки ...

, поэтому мне интересночто делает блокнот, чтобы отправить эту строковую команду, которую я не делаю?

надеюсь, что кто-то может пролить свет на это, потому что я очень хотел реализовать Fargo SuppoРТ в моем заявлении в течение более длительного периода времени.

спасибо

Обновление. следующий код является древним, но он выполняет свою работу, однако есть ли другой способ, которым я могу использовать это с кодом 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 Ответ

4 голосов
/ 22 марта 2012

TPassThrough должен быть объявлен следующим образом:

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

Возможно, вы используете современный Delphi (2009 или новее) или забыли упакованную директиву.

См. Также этот вопрос SO для правильный способ отправки команд напрямую на принтер .

На У Торри есть примерный фрагмент (написанный Фатихом Ольсером): Примечание:Модифицировано для использования с версиями 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;
...