2

好的,这是我的做法:

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
  ...

但是,由于某些命令(转义序列)无法按预期工作,因此出现了问题!

4

3 回答 3

6

您使用了错误的功能。使用Escape,将 PASSTHROUGH 标志作为第二个参数传递。这会将原始的、未处理的转义码直接发送到打印机。

Joe Hecht(以前的 Borland)已经多次发布了一个单元,这使得这更容易。我在这里找到了单位 PrtRaw

于 2011-05-09T13:18:26.607 回答
3

由于 Ansi 和 Unicode 字符之间的变化,您当前的代码以错误的格式向打印机发送数据。您使用的打印机显然能够容忍一些错误,这就是您的某些命令有效的原因,但有一个限制。

在您的 Delphi 版本中,Char等效于WideChar,因此请更改您的Char代码以使用AnsiChar,这样您就可以发送一个字节的字符,正如打印机所期望的那样。你的PrintRawData功能以前很好。你的改变是错误的。打印机不希望收到两字节的 Unicode 字符,但这就是您的更改。

恢复原始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当函数已经完成时,不需要显式声明。
于 2011-05-09T15:49:53.110 回答
0
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')
于 2015-05-11T11:23:55.097 回答