How can I print a QR code or barcode on TMSFNCPrinter?

I'm taking control of the printing so I need to print barcode labels and QR code labels. I just don't know how to print directly using the TMSFNCPrinter

Hi William,
i had the same problem with barcode (not QR, but coul be solved in the same way).
First my need ...
I nedd to print to an Epson TM 30 printer (receipt printer) only one or more barcode created from a stringlist ean 13 (or 8) code.

Here my solution (geve me in this forum):
In a form, i have

1 x TImage
1 x TTMSFNCWXBarcode
1 x Var Bmp : TTMSFNCBitmap (in a printer button onclick event)

here the code:

    TMSFNCPrinter.OnDrawContent :=
    procedure
    var I   : Integer;
        Qta : Integer;
        S   : String;
    begin
      PT.X := X + 170;
      Y:=Y + 20;
      PT.Y := Y + 35;
      for I := 1 to Sg1.LastRow do
      begin
        Qta:=Qta + SG1.Ints[ColQta,I];
        TMSFNCPrinter.Graphics.Fill.Color := gcRed;
        bmp := BarCode2.GetBarcode(SG1.Cells[ColAic, I]);
        Image1.Picture.Assign(bmp);
        TMSFNCPrinter.Graphics.DrawBitmap(X, Y, 200, Y + 80, Image1.Picture, True, True, True, False);
        if SG1.Ints[ColQta,I] > 1 then
            TMSFNCPrinter.Graphics.DrawText(PT, 'X' + #32 +#32 + SG1.Cells[ColQta,I]);
        Y:=Y + 80 + 10;
        PT.Y := Y + 35;
        FreeAndNil(Bmp);

      end;
    end;

  TMSFNCPrinter.BeginDoc;

This is only as starting point in order to resolve your printing problem.
In my case the resolution of generated barcode is not very very hight but is enougth for my need. Next step (for my project) is show a barcode for each row grid (that is TmsStringGrid) in a close code cell but at the moment my time is for other poject .

Best regard
Daniele

Hi,

You can do this the same way you'd use TMSFNCPrinter to print a TTMSFNCBitmap. From the OnGetQRCode and OnGetBarcode events you have access to the resulting TTMSFNCBitmap.

For example, to print a sheet of business cards:

procedure TForm2.TMSFNCWXQRCode1GetQRCode(Sender: TObject;
  ABitmap: TTMSFNCBitmap);
var
  PDF: TTMSFNCPDFLib;
  I: Integer;
begin
  PDF := TTMSFNCPDFLib.Create;
  try
    PDF.BeginDocument('sample.pdf');
    PDF.PageSize := psA4;
    PDF.Header := '';
    PDF.Footer := '';
    PDF.NewPage;
    PDF.Graphics.Font.Name := 'Roboto';
    PDF.Graphics.Font.Color := gcBlack;
    PDF.Graphics.Font.Style := [];
    for I := 0 to 4 do
    begin
      DrawBusinessCard(PDF, 25, 40 + 150 * I, 300, 190 + 150 * I, ABitmap);
      DrawBusinessCard(PDF, 300, 40 + 150 * I, 575, 190 + 150 * I, ABitmap);
    end;
    PDF.EndDocument(True);
  finally
    PDF.Free;
  end;
end;

procedure TForm2.DrawBusinessCard(APDF: TTMSFNCPDFLib; ALeft, ATop, ARight, ABottom: Integer; AQR: TTMSFNCBitmap);
begin
  APDF.Graphics.DrawRectangle(RectF(ALeft, ATop, ARight, ABottom));
  APDF.Graphics.Font.SizeNoScale := 14;
  APDF.Graphics.DrawText('Name', PointF(ALeft + 25, ATop + 20));
  APDF.Graphics.DrawLine(PointF(ALeft + 15, ATop + 45), PointF(ARight - 15, ATop + 45));
  APDF.Graphics.Font.SizeNoScale := 12;
  APDF.Graphics.DrawText('Company', PointF(ALeft + 25, ABottom - 90));
  APDF.Graphics.Font.SizeNoScale := 10;
  APDF.Graphics.DrawText('Address line 1', PointF(ALeft + 25, ABottom - 70));
  APDF.Graphics.DrawText('Address line 2', PointF(ALeft + 25, ABottom - 60));
  APDF.Graphics.DrawText('Website', PointF(ALeft + 25, ABottom - 45));
  APDF.Graphics.Font.SizeNoScale := 5;
  APDF.Graphics.DrawText('Created from FMX client application', PointF(ALeft + 25, ABottom - 25));
  APDF.Graphics.DrawImage(AQR, RectF(ARight - 95, ABottom - 90, ARight - 25, ABottom - 20));
end;

The OnGetQRCode and OnGetBarcode events trigger when the application starts because the initial qr code/barcode is generated and shown in the control. You might want to programmatically assign the events to avoid generating a PDF on program start.

Good morning Tunde,
to be honest ... i miss this event !!!
Even the job is done very well with the code in my answer, i prefer work with component event.

Thank's

Best regards
Daniele

Hi,

The code you posted is also a good and valid approach but unfortunately it can only apply to TTMSFNCWXBarcode as the QR code generation is completely asynchronous. Because of this, we could not create a synchronous GetQRCode method and we must rely on the OnGetQRCode event. The TTMSFNCWXBarcode component comes with an OnGetBarcode event but the sync GetBarcode method is also there for convenience (on non-mobile platforms).

Do you mean the OnBarcode event is not there for you?

Hi Tunde,
no, no ...
The event is present ........ i mean who i don't see it !! :sob: :sob:

Daniele

Thanks for all the input. I figured out a solution for this.
I declared a bmp (TBitmap) within the class/form. When the GetQRCode is called, I assign the new bitmap to my bitmap and print it when I send to my label. I can easily iterate through a database and set the QR code to the new value which creates a new bitmap to be assigned each time before it prints.

procedure TForm5.qrCode1GetQRCode(Sender: TObject; ABitmap: TTMSFNCBitmap);
begin
bmp.Assign(abitmap);
end;

procedure TForm5.TMSFNCButton2Click(Sender: TObject);
var
h,w : integer;
txt : string;
begin
txt := 'Bill was Here';

TMSFNCPrinter.OnDrawContent :=
procedure
begin
tmsfncprinter.Graphics.Font.Size := 20;
tmsfncPrinter.Graphics.DrawText(0,10,tmsfncprinter.PageWidth, 10, txt, false, gtaCenter, gtaCenter);
TMSFNCPrinter.Graphics.DrawBitmap(0, 30, tmsfncprinter.PageWidth, 80, bmp, True, True, True, False);
tmsfncprinter.EndDoc;
end;

TMSFNCPrinter.BeginDoc;

end;

procedure TForm5.FormCreate(Sender: TObject);
begin
bmp := Tbitmap.Create;
end;

procedure TForm5.FormDestroy(Sender: TObject);
begin
bmp.free;
end;