• Welcome to PlanetSquires Forums.
 

Barcode DLL (zint 32-bit 64-bit)

Started by Johan Klassen, November 06, 2022, 07:42:29 AM

Previous topic - Next topic

Petrus Vorster

Incredible.

It scans perfectly, even from the screen using a Zebra DS22.
It defaults to my Adobe printer and the barcode works.

Next step is that label printer!

Great stuff.

-Peter
-Regards
Peter

Paul Squires

Hi Peter,

Here is modified code of Jose's bitmap printing routine that now allows you to specify the printer (wszPrinterName) and output location of the bitmap (xpos, ypos).

It seems to work okay with my virtual PDF printer. Hopefully it will work okay with your actual label printer.

#include "zint.bi"

#include once "Afx/AfxGdiplus.inc"
#include once "Afx/CMemBmp.inc"

' ========================================================================================
' Retrieves the name of the default printer.
' ========================================================================================
function GetDefaultPrinterName() AS CWSTR
   dim buffer as wstring * MAX_PATH
   GetProfileStringW "WINDOWS", "DEVICE", "", buffer, sizeof(buffer)
   return AfxStrParse(buffer, 1, ",")
end function
' ========================================================================================

' ========================================================================================
' Print the label to the specified printer and location.
' ========================================================================================
function PrintLabel( _
      byval hbmp as HBITMAP, _
      byval xpos as single, _
      byval ypos as single, _
      byref wszPrinterName as wstring _
      ) as boolean

   ' // Initialize Gdiplus
   dim token as ULONG_PTR = AfxGdipInit
   if token = null then exit function
   dim hPrinter as HANDLE
   dim pbufferDoc as ubyte ptr
   dim pBitmap as GpBitmap ptr
   dim pGraphics as GpGraphics ptr

   if wszPrinterName = "" then exit function

   ' // Note: Using a DO... LOOP, with an EXIT DO before LOOP, to avoid the use of GOTO.
   do
      ' // Open the printer
      if OpenPrinterW(wszPrinterName, @hPrinter, null) = 0 then exit do

      ' // Allocate a buffer of the correct size
      dim dwNeeded as DWORD = DocumentPropertiesW(null, hPrinter, wszPrinterName, null, null, 0)
      pbufferDoc = CAllocate(1, dwNeeded)

      ' // Retrieve the printer configuration data
      dim nRet as long = DocumentPropertiesW(null, hPrinter, wszPrinterName, cast(PDEVMODEW, pbufferDoc), null, DM_OUT_BUFFER)
      if nRet <> IDOK then exit do

      ' // cast it to a DEVMODEW structure
      dim pDevMode as DEVMODEW ptr = cast(DEVMODEW ptr, pbufferDoc)

      ' // Create a device context for the printer
      dim hDC as .HDC = CreateDCW(wszPrinterName, wszPrinterName, null, pDevMode)
      if hDC = null then exit do

      ' // Create a graphics object from the printer DC
      GdipCreateFromHDC(hDC, @pGraphics)
      if pGraphics = null then exit do

      ' // Create a Bitmap object from an HBITMAP
      GdipCreateBitmapFromHBITMAP(hbmp, null, @pBitmap)
      if pBitmap = null then exit do
     
      ' // Print the bitmap
      dim di as DOCINFOW
      dim wszDocName as wstring * 260 = "Printing bitmap"
      di.cbSize = sizeof(DOCINFOW)
      di.lpszDocName = @wszDocName
     
      dim hr as long = StartDocW(hDC, @di)
      if hr <= 0 then exit do

      if StartPage(hDC) then
         ' // Draw the image
         GdipDrawImage(pGraphics, cast(GpImage ptr, pBitmap), xPos, yPos)
         EndPage(hDC)
      end if
      EndDoc(hDC)

      function = true
      exit do
   loop

   if pBitmap then GdipDisposeImage(cast(GpImage ptr, pBitmap))
   if pGraphics then GdipDeleteGraphics(pGraphics)

   ' // Finished with the printer
   if hPrinter then ClosePrinter(hPrinter)

   ' // Cleanup
   if pbufferDoc then Delete(pbufferDoc)

   ' // Shutdown Gdiplus
   GdiplusShutdown token

end function



'' ************************
'' MAIN ENTRY POINT
'' ************************

dim as zint_symbol ptr pSymbol = ZBarcode_Create()
pSymbol->symbology = BARCODE_QRCODE
pSymbol->scale = 8

? ZBarcode_Encode_and_Buffer(pSymbol, @"PlanetSquires", 0, 0)
? "my_symbol->bitmap_width = "; pSymbol->bitmap_width
? "my_symbol->bitmap_height = "; pSymbol->bitmap_height

dim as CMemBmp memBMP = CMemBmp( pSymbol->bitmap_width, pSymbol->bitmap_height )

dim as byte ptr pCol = pSymbol->bitmap
dim as long i = 0
for y as long = 1 to pSymbol->bitmap_height
   for x as long = 1 to pSymbol->bitmap_width
      dim as COLORREF clr = BGR(pCol[i], pCol[i+1], pCol[i+2])
      memBMP.SetPixel(x, y, clr)
      i += 3
   next
next

dim as wstring * 260 wszPrinterName = GetDefaultPrinterName()

? PrintLabel( memBMP.GethBmp, 100, 200, wszPrinterName )

ZBarcode_Delete(pSymbol)

sleep

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Petrus Vorster

WOW

Printing in Freebasic is miles above my paygrade.
I dont even know how to add or place text here.

Xprint made life a breeze.
I assume one cannot combine this with your cprintpreview?

LOL, I cannot even see where the bitmap is being moved and placed.  :o

I will give this a shot tonight, thank you.

-Peter
-Regards
Peter

Paul Squires

Printing in FB (well, the Windows version of FB) is done using direct Win32 api calls. You can see that in the code. Basically, query the defined printer for its capabilities in order to create an off screen bitmap where you construct your text and graphics and then call api functions to actually output it to the printer.

StartDocW
StartPage
GdipDrawImage
EndPage
EndDoc

You could use any of the GDI+ functions to output to that bitmap such as GdipDrawString to include text with the label.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Quote from: Petrus Vorster on June 14, 2023, 02:34:09 AMI assume one cannot combine this with your cprintpreview?
Not sure why you'd want an additional layer of abstraction when everything can be done without it.

QuoteLOL, I cannot even see where the bitmap is being moved and placed.  :o

This is where the label bitmap is being moved into the GDI+ bitmap buffer that actually gets output to the printer:

      ' // Create a Bitmap object from an HBITMAP
      GdipCreateBitmapFromHBITMAP(hbmp, null, @pBitmap)
      if pBitmap = null then exit do


Maybe you should post some pseudo code of what it is you need to achieve and then I can write the necessary functions that will make it happen. For example, I assume that you will looping through and array of data, creating a label bitmap for each, adding additional text to the label(?), and then printing it to the physical printer.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

For anyone lurking on this thread - Peter emailed me a picture of what the barcodes and other text on the label should look like. I'm putting together a simple class to handle his needs. Hopefully it will do what is needed.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Update: I emailed the code to Peter. Waiting now for him to try it out. Attached is what the sample code I sent him generates. One large barcode and two half height barcodes with a text heading of "Insured Parcel". Created using zint dll, GDI+, and a couple of Jose's AFX classes.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Petrus Vorster

HI All

I would NEVER have managed without all the help.

The download link got blocked by the server, so I will check my home email tonight.
From this point on I just need to finish the rest of the tool to change the headers of the labels as required, and already did the tracking number & check digit creator.

Margins and so forth will be next.
If this works we could save millions. Why on earth they went with buying warehouses full of pre-printed labels are beyond me.

I will most definitely try this at home tonight!!!

-Regards, Peter
-Regards
Peter

Petrus Vorster

Hi All

Paul, what on earth would I have done without you?

You made it so simple! Classlabels.inc made it incredibly simple to use.
The label prints correctly, the barcodes scan correctly.
This is truly something everyone here that needs barcodes can use with great ease.

I am unable to express my gratitude, it is perfect.

Once I am done with the Tracking numbers loop I will post a video of it printing a number of individual labels.

Everyone here, I am in great debt with you!

-Peter
-Regards
Peter

Paul Squires

Wow!
The label looks better than I would have imagined!
So cool that everything is working well with the label and barcodes.

You are very welcome and I am happy that I was able to help you.

Many people over the years have helped me out immensely (Jose Roca, in particular), so being able to pay it forward gives me a good feeling.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Petrus Vorster

Hi All

As promised. My project is nearly done.
I recorded the basic process using all the help I got from everyone here.
Johan Klassen, Paul Squires & José Roca, without you this would never have happened.

The example is on a small label printer, but this will run on a large industrial printer with plastic coatings and hi defenition printing.
So far, everything works, and its all due to you.

Once we seriously trial runs this in the warehouse I will update this post.

Regards,

Peter
-Regards
Peter