如何使用 Delphi 在 ESC/POS 打印机上打印二维码?

这是在 EPSON 热敏打印机上打印的测试代码。除二维码部分外,一切正常。打印机卡住了,我需要手动重置它。

我正在关注此页面中的文档: https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=143

我正在使用德尔福 10.3。

我究竟做错了什么?

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls ,
  Vcl.Printers,
 WinProcs, WinTypes;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure setupPrinter(const printerName: string);
    procedure PrintTest;
    function DirectToPrinter(S: AnsiString; NextLine: Boolean): Boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TPrnBuffRec = packed record
  bufflength: Word;
  Buff_1: array[0..255] of AnsiChar;
end;

function tform1.DirectToPrinter(S: AnsiString; NextLine: Boolean): Boolean;
var
  Buff: TPrnBuffRec;
  TestInt: Integer;
  i: integer;
   Device: PChar;
  Driver: PChar;
  Port: PChar;
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;

Procedure tform1.PrintTest;
var
   store_len: integer;
   store_pl: Byte;
   store_ph : Byte;
   qrData: string;
Begin

        setupPrinter('EPSON TM-T88V Receipt');
        Printer.BeginDoc;
        DirectToPrinter(Chr(27)+Chr(64), false);           //init
        DirectToPrinter(Chr(27)+chr(97)+chr(49), false);
//        DirectToPrinter(Chr(27)+chr(33)+Chr(8), false);   //font select
        DirectToPrinter(Chr(27)+chr(45)+Chr(49), false);   //underline
        DirectToPrinter('Test!', true);
        DirectToPrinter(Chr(27)+chr(100)+Chr(5), false);   //feed 5 lines
        DirectToPrinter(Chr(27)+chr(45)+Chr(48), false);   //underline
        DirectToPrinter(Chr(27)+chr(97)+chr(48), false);   //align-center
        DirectToPrinter('Hello world!', true);

        DirectToPrinter(
          chr(29)+chr(72)+chr(49),
          False

        );                   //show content aboce barcode
//
        DirectToPrinter(
          chr(29)+chr(102)+chr(48),
          False

        );                 //font  A

//        DirectToPrinter(
//          chr(29)+chr(104)+chr(50),
//          False
//
//        );        //height

//        DirectToPrinter(
//          chr(29)+chr(119)+chr(50),
//          False
//
//        );        //width

        DirectToPrinter(
          chr(29)+chr(107)+chr(4)+'*0001443AB*',
          true
        );   //ean 39

        DirectToPrinter(
          chr(29)+chr(107)+chr(73)+chr(13)+chr(123)+Chr(65)+'8600123456789',
          true
        );          // ean 128

        DirectToPrinter(
          chr(29)+chr(107)+chr(67)+Chr(12)+'860012345678',
          true
        ); // ean 13

        //*************************QR CODE ****************/

        qrData := 'https://www.stackoverflow.com';
        store_len:= Length(qrData)+3;
        store_pl := store_len mod 256;
        store_ph := Trunc(store_len / 256);

        DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+char(3)+chr(0)+Chr(49)+Chr(65)+
          Chr(49)+Chr(0),false
        ); //QR Code: Select the model

        DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+chr(3)+Chr(0)+Chr(49)+Chr(67)+
          Chr(2),false
        ); //QR Code: Set the size of module

        //QR Code: Select the error correction level
        DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+chr(3)+Chr(0)+Chr(49)+Chr(69)+
          Chr(48),false
        );

        //QR Code: Store the data in the symbol storage area
        DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+
          chr(store_pl)+Chr(store_ph)+
          Chr(49)+Chr(80)+Chr(48)+qrData,
          false
        );

//        QR Code: Print the symbol data in the symbol storage area
         DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+chr(store_pl)+chr(store_ph)+Chr(49)+Chr(81)+Chr(48),true
        );

        DirectToPrinter(Chr(27)+Chr(112)+Chr(48)+Chr(60)+Chr(120), false); //drawer pulse
        Printer.EndDoc;
End;

procedure TForm1.setupPrinter(const printerName: string);
var
  Buff: TPrnBuffRec;
  TestInt: Integer;
  i: integer;
   Device: PChar;
  Driver: PChar;
  Port: PChar;
  HDeviceMode: THandle;
begin
  Printer.PrinterIndex := -1;
  GetMem(Device, 255);
  GetMem(Driver, 255);
  GetMem(Port, 255);
  for I := 0 to Printer.Printers.Count - 1 do
  begin
    if Printer.Printers[I] = printername then
    begin
      printer.PrinterIndex := I;
      printer.getprinter(Device, Driver, Port, HdeviceMode);
      StrCat(Device, ',');
      StrCat(Device, Driver);
      StrCat(Device, Port);
      WriteProfileString('windows', 'device', Device);
      StrCopy(Device, 'windows');
      SendMessage(HWND_BROADCAST, WM_WININICHANGE,
        0, Longint(@Device));
      break;
    end;
  end;
  FreeMem(Device, 255);
  FreeMem(Driver, 255);
  FreeMem(Port, 255);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  PrintTest;
end;
end.
stack overflow How to print QR Code on ESC/POS Printer by using Delphi?
原文答案

答案:

作者头像

打印二维码的命令长度指定错误。
指定了与存储 QR 码的命令相同的数据长度,即前一个命令,但这是 3 字节的固定值。

GS ( k <Function 181>

这部分:

//        QR Code: Print the symbol data in the symbol storage area
         DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+chr(store_pl)+chr(store_ph)+Chr(49)+Chr(81)+Chr(48),true
        );

请改到这里:

//        QR Code: Print the symbol data in the symbol storage area
         DirectToPrinter(
          Chr(29)+chr(40)+Chr(107)+chr(3)+chr(0)+Chr(49)+Chr(81)+Chr(48),true
        );