Правильный способ отправки команд прямо на принтер! - PullRequest
2 голосов
/ 09 мая 2011

Хорошо, вот как я это делаю:

procedure TMainWindow.btnRawPrintClick(Sender: TObject);
begin
  BeginPrint;
  SendStr(#27#69);
  SendStr('MyData');
  SendStr(#10);
  EndPrint;
end;

procedure TMainWindow.SendStr(Text: String);
var
  i: Integer;
  data : Array of Char;
begin
  for i := 1 to Length(Text) do
  begin
    SetLength(data,i);
    data[Pred(i)] := Text[i];
  end;

  if (PrintRawData(printHandle,
                   data,
                   Length(data)) < 0) then begin
    ShowMessage('PrintRawData Failed');
    EndRawPrintPage(printHandle);
    EndRawPrintJob(printHandle);
    exit;
  end;
end;

procedure TMainWindow.BeginPrint;
begin
  printHandle := StartRawPrintJob('EPSON TM-T70 Receipt','ESDPRT001','Test Document');

  if printHandle < 0 then
  begin
    ShowMessage('StartRawPrintJob Failed!');
    exit;
  end;

  if (StartRawPrintPage(printHandle) < 0) then begin
    ShowMessage('StartRawPrintPage Failed!');
    EndRawPrintJob(printHandle);
    exit;
  end;
end;

procedure TMainWindow.EndPrint;
begin
  if (EndRawPrintPage(printHandle) < 0) then begin
    ShowMessage('EndRawPrintPage Failed');
    EndRawPrintJob(printHandle);
    exit;
  end;

  if (EndRawPrintJob(printHandle) < 0) then begin
    ShowMessage('EndRawPrintJob Failed');
    exit;
  end;
end;

Также я изменил небольшой код, который я взял из здесь :

function PrintRawData(hPrn : THandle;
                      Buffer : pointer;
                      NumBytes : SpoolInt) : integer;
{$IFDEF WIN32}
var
  BytesWritten : DWORD;
 {$ENDIF}
begin
  NumBytes := NumBytes * 2;    //<-- I added this line
  ...

Однако,что-то не так, поскольку некоторые команды (escape-последовательности) не работают должным образом!

Ответы [ 3 ]

6 голосов
/ 09 мая 2011

Вы используете неправильную функцию. Используйте Escape , передавая флаг PASSTHROUGH в качестве второго параметра. Это отправляет необработанные необработанные управляющие коды на принтер напрямую.

Джо Хехт (ранее из Borland) несколько раз выкладывал юнит, что облегчает эту задачу. Я нашел единицу PrtRaw здесь.

3 голосов
/ 09 мая 2011

Ваш текущий код отправляет данные на принтер в неправильном формате из-за изменений между символами Ansi и Unicode. Принтер, который вы используете, очевидно, способен допускать некоторое количество ошибок, поэтому некоторые ваши команды работали, но есть ограничение.

В вашей версии Delphi Char эквивалентно WideChar, поэтому измените код Char, чтобы вместо него использовать AnsiChar, чтобы вы могли отправлять однобайтовые символы, как того ожидает принтер. Ваша PrintRawData функция была в порядке раньше. Ваше изменение неверно. Принтер не ожидает получения двухбайтовых символов Юникода, но это то, что составляет ваше изменение.

После восстановления исходного кода PrintRawData измените функцию SendStr на:

procedure TMainWindow.SendStr(const Text: string);
var
  data: AnsiString;
begin
  data := Text;

  if (PrintRawData(printHandle,
                   PAnsiChar(data),
                   Length(data)) < 0) then begin
    ShowMessage('PrintRawData Failed');
    EndRawPrintPage(printHandle);
    EndRawPrintJob(printHandle);
  end;
end;

Я внес следующие изменения в код:

  1. Заменить массив Char на AnsiString.
  2. Вместо того, чтобы увеличивать массив данных по одному символу за раз с помощью цикла, выполните преобразование Unicode-в-Ansi с помощью одного оператора присваивания и позвольте RTL позаботиться о преобразовании.
  3. Введите строку данных в PAnsiChar для передачи в PrintRawData.
  4. Передайте строковые параметры как const, если вам не нужно изменять их содержимое.
  5. Нет необходимости в явном выражении exit, когда функция уже завершена.
0 голосов
/ 11 мая 2015
Procedure StrLstYazdir(pYazilacakListe: TStringList; pYazici: String);
var
  hPrn: THandle;
  yazilacakVeri: AnsiString;
  intA: Integer;
begin
  hPrn := StartRawPrintJob(PChar(pYazici), '', 'Varakim');
  if (Integer(hPrn) < 0) then
  Begin
    ShowMessage('StartRawPrintJob Hatalı');
    Exit;
  End;

  if (StartRawPrintPage(hPrn) < 0) then
  Begin
    ShowMessage('StartRawPrintPage Hatalı');
    EndRawPrintJob(hPrn);
    Exit;
  end;

  For intA := 0 to pYazilacakListe.Count - 1 do
  Begin
    yazilacakVeri := pYazilacakListe[intA] + #13 + #10;

    if (PrintRawData(hPrn, PAnsiChar(yazilacakVeri), Length(yazilacakVeri)) < 0)
    then
    begin
      ShowMessage('PrintRawData Hatalı');
      EndRawPrintPage(hPrn);
      EndRawPrintJob(hPrn);
      Exit;
    End;
  End;
  if (EndRawPrintPage(hPrn) < 0) then
  begin
    ShowMessage('EndRawPrintPage Hatalı');
    EndRawPrintJob(hPrn);
    Exit;
  End;

  if (EndRawPrintJob(hPrn) < 0) then
  begin
    ShowMessage('EndRawPrintJob Hatalı');
    Exit;
  End;
End;

Использование:

StrLstYazdir(Memo1.Lines ,'Lexmark Forms Printer 2491')
...