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フラグを2番目のパラメーターとして渡します。これにより、未処理の未処理のエスケープコードがプリンタに直接送信されます。

Joe Hecht(以前のBorland)は、これを簡単にするユニットを数回投稿しています。ここでユニットPrtRawを見つけました。

于 2011-05-09T13:18:26.607 に答える
3

現在のコードは、Ansi文字とUnicode文字の間の変更により、間違った形式でデータをプリンタに送信しています。使用しているプリンタは、明らかにある程度のエラーに耐えることができます。そのため、一部のコマンドは機能しましたが、制限があります。

お使いのバージョンのDelphiは、Charと同等であるため、代わりに使用するようにコードをWideChar変更して、プリンタが期待するとおりに1バイト文字を送信できるようにします。あなたの機能は以前は大丈夫でした。あなたの変更は間違っています。プリンタは2バイトのUnicode文字を受け取ることを期待していませんが、それが変更に相当します。CharAnsiCharPrintRawData

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. ループで一度に1文字ずつデータ配列を拡張する代わりに、単一の代入ステートメントで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 に答える