FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index mod_harbour mod_harbour.v2.1 Plugin for barcode
Posts: 139
Joined: Mon Oct 17, 2005 03:03 AM

mod_harbour.v2.1 Plugin for barcode

Posted: Tue May 19, 2026 10:32 AM

It need library: ./harbour/contrib/hbzebra and ./harbour/contrib/hbhpdf

TBarcodes.prg

#ifdef __FIVEWIN__
   #include "fivewin.ch"
#else
   #include "hbclass.ch"
   #define __MODHARBOUR__
#endif

#include "codebar.ch"

CLASS TCodeBars

   DATA aTypes HIDDEN

   DATA cCode
   DATA nFlags

   DATA hCodeBar
   DATA hData

   DATA nType, nWidth, nHeight, nWidthCode, nHeightCode

   METHOD New()
   METHOD End()

   METHOD DefError( nError )
   METHOD SetCode( cCode )
   METHOD SetFlags( nFlags )
   METHOD SetType( cnType )
   METHOD Reset()   INLINE ::End()
   

   #ifdef __FIVEWIN__
      METHOD Build()
   #endif
   

   METHOD DrawPdf( oPdf, nLeft, nTop ) // For mod_harbour / PDF drawing
   METHOD Rebuild()

ENDCLASS

//--------------------------------------//

METHOD New( nWidth, nHeight, nWidthCode, nHeightCode, cnType, cCode, nFlags ) CLASS TCodeBars

   hb_default( @nWidth, 200 )
   hb_default( @nHeight, 100 )
   hb_default( @nWidthCode, 1 )
   hb_default( @nHeightCode, 3 )


   ::aTypes = { { "EAN13"      , {| | hb_zebra_create_ean13( ::cCode, ::nFlags )      } },;
                { "EAN8"       , {| | hb_zebra_create_ean8( ::cCode, ::nFlags )       } },;
                { "UPCA"       , {| | hb_zebra_create_upca( ::cCode, ::nFlags )       } },;
                { "UPCE"       , {| | hb_zebra_create_upce( ::cCode, ::nFlags )       } },;
                { "ITF"        , {| | hb_zebra_create_itf( ::cCode, ::nFlags )        } },;
                { "MSI"        , {| | hb_zebra_create_msi( ::cCode, ::nFlags )        } },;
                { "CODABAR"    , {| | hb_zebra_create_codabar( ::cCode, ::nFlags )    } },;
                { "CODE11"     , {| | hb_zebra_create_code11( ::cCode, ::nFlags )     } },;
                { "CODE39"     , {| | hb_zebra_create_code39( ::cCode, ::nFlags )     } },; // note:2018.08.09:code39 有 flags 常用 HB_ZEBRA_FLAG_WIDE2_5
                { "CODE93"     , {| | hb_zebra_create_code93( ::cCode, ::nFlags )     } },;
                { "CODE128"    , {| | hb_zebra_create_code128( ::cCode, ::nFlags )    } },;
                { "PDF417"     , {| | NIL /*hb_zebra_create_pdf417( ::cCode, ::nFlags )     */} },;
                { "DATAMATRIX" , {| | hb_zebra_create_datamatrix( ::cCode, ::nFlags ) } },;
                { "QRCODE"     , {| | hb_zebra_create_qrcode( ::cCode, ::nFlags )     } } }

   ::nWidth  = nWidth
   ::nHeight = nHeight
   ::nWidthCode  = nWidthCode
   ::nHeightCode = nHeightCode

   ::SetType( cnType )
   ::SetCode( cCode )
   ::SetFlags( nFlags )


return Self

//--------------------------------------//

METHOD End() CLASS TCodeBars
   #ifdef __FIVEWIN__
      if ::hCodeBar != NIL
         DeleteObject( ::hCodeBar )
         ::hCodeBar := NIL
      endif
   #endif
   if ::hData != NIL
      hb_zebra_destroy( ::hData )
      ::hData := NIL
   endif
return NIL

//--------------------------------------//

METHOD Rebuild() CLASS TCodeBars
   ::Reset()
   #ifdef __FIVEWIN__
      ::Build()
   #endif
return NIL

//--------------------------------------//

#ifdef __FIVEWIN__
METHOD Build(nTop, nLeft) CLASS TCodeBars // mdy:WenSheng:2015.06.20:輸出時增加坐標起點位置

   local hBmpOld
   local hDCDesk := GetDC( GetDesktopWindow() ) // hDC1
   local hDCMem  := CreateCompatibleDC( hDCDesk ) // hDC2
   local hBrush  := CreateSolidBrush( 0 )
   local hBack   := CreateSolidBrush( CLR_WHITE )
   // add:WenSheng:2015.06.20:輸出時增加坐標起點位置
   DEFAULT nLeft   := 0,;
           nTop    := 0

   ::hCodeBar = CreateCompatibleBitMap( hDCDesk, ::nWidth, ::nHeight ) // hBmp
   hBmpOld    = SelectObject( hDCMem, ::hCodeBar )

   ::hData := Eval( ::aTypes[ ::nType ][ CODEBAR_BLOCK ] )

   ::DefError()
   FillRect( hDCMem, { 0, 0, ::nHeight, ::nWidth }, hBack )
   hb_zebra_draw( ::hData, {| x, y, w, h | FillRect( hDCMem, { y, x, y +  h, x + w }, hBrush ) }, nleft, nTop, ::nWidthCode, ::nHeightCode )

   SelectObject( hDCMem, hBmpOld )
   ReleaseDC( GetDesktopWindow(), hDCDesk )
   DeleteDC( hDCMem )
   DeleteObject( hBrush )
   DeleteObject( hBack )

return NIL
#endif

//--------------------------------------//

METHOD DrawPdf( oPdf, nLeft, nTop ) CLASS TCodeBars
   // add:WenSheng:2026.05.19:新增給 mod_harbour / PDF 向量繪圖之方法

   ::hData := Eval( ::aTypes[ ::nType ][ CODEBAR_BLOCK ] )
   ::DefError()

   if ::hData == NIL
      return NIL
   endif

   // 1. 設定著色為黑色
   HPDF_Page_SetRGBFill( oPdf:hPage, 0.0, 0.0, 0.0 )

   // 2. 進行繪製
   // 備註:PDF 坐標 Y 軸是由下往上算的。
   // 為了與 GDI 相同的 Top/Left 行為對齊,將 Y 坐標轉換為: oPdf:nHeight - y - h
   hb_zebra_draw( ::hData, {| x, y, w, h | HPDF_Page_Rectangle( oPdf:hPage, x, oPdf:nHeight - y - h, w, h ) }, nLeft, nTop, ::nWidthCode, ::nHeightCode )

   // 3. 填滿繪製的所有條紋矩形
   HPDF_Page_Fill( oPdf:hPage )

return NIL

//--------------------------------------//

METHOD SetCode( cCode ) CLASS TCodeBars

   if ! Empty( cCode )
      if ValType( cCode ) != "C"
         cCode = hb_valToStr( cCode )
      endif
      ::cCode = cCode
   endif

return NIL

//--------------------------------------//

METHOD SetFlags( nFlags ) CLASS TCodeBars

   ::nFlags = nFlags

return NIL

//--------------------------------------//

METHOD SetType( cnType ) class TCodeBars

   local cType

   if ( ( cType := ValType( cnType ) )$"CN" )
      if cType == "N"
         if cnType > 0 .and. cnType < 15
            ::nType = cnType
         endif
      else
         ::nType = AScan( ::aTypes, {| a | a[ CODEBAR_TYPE ] == Upper( cnType ) } )
      endif
   else
      ::nType = DEFAULT_CODEBAR
   endif

return NIL

//--------------------------------------//

METHOD DefError( ) CLASS TCodeBars
   local oError
   local nError := 0

   if ::hData != NIL
      nError = hb_zebra_geterror( ::hData )
   endif


   if nError != 0
      hb_zebra_destroy( ::hData )

  oError := ErrorNew()
  oError:SubSystem   = "TCODEBARS"
  oError:SubCode     = nError
  oError:Severity    = 2

  Eval( ErrorBlock(), oError )

   endif

RETURN nil

#ifdef __FIVEWIN__
#pragma BEGINDUMP
#include <hbapi.h>
#include <windows.h>

HB_FUNC( CREATECOMPATIBLEBITMAP ) // hDC, nWidth, nHeight
{
   hb_retnl( ( LONG ) CreateCompatibleBitmap( ( HDC ) hb_parnl( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) );
}

#pragma ENDDUMP
#endif

test_barcode.prg

<?prg
/*
  mod_harbour 條碼 PDF 輸出測試範例
*/
#include "hbclass.ch"
// 定義條碼常數
#define CODEBAR_CODE39         9
#define CODEBAR_QRCODE         14

function Main()
  local oPdf
  local oBar1, oBar2
  local hFont12, hFont16
  local cCodeVal := "WSCAR-123456"
  local cOutFile := "test_barcode_temp.pdf"

  // 建立 PDF 物件 (使用 A4 大小)
  oPdf := TPdf():New( cOutFile )
  oPdf:StartPage()

  // 載入 PDF 內建字型 (不需依賴外部 ttf)
  hFont12 := oPdf:DefineFont( "Helvetica", 12 )
  hFont16 := oPdf:DefineFont( "Helvetica-Bold", 16 )

  // 繪製測試標題
  oPdf:Say( 40, 50, "Harbour TCodeBars / hbzebra PDF Test", hFont16 )
  oPdf:Line( 60, 50, 60, 500, 1 )

  // ==========================================
  // 第一列:產生 Code39 條碼
  // ==========================================
  oBar1 := TCodeBars():New()
  oBar1:SetType( CODEBAR_CODE39 )
  oBar1:SetCode( cCodeVal )
  oBar1:nWidthCode  := 1.2  // 條紋單元寬度
  oBar1:nHeightCode := 50   // 條碼高度
   

  // 繪製條碼 (X: 50, Y: 100)
  oBar1:DrawPdf( oPdf, 50, 100 )
  oBar1:End()

  // 在條碼下方列印文字
  oPdf:Say( 165, 50, "Below: " + cCodeVal, hFont12 )

  // 在條碼右方列印文字
  oPdf:Say( 125, 320, "Right: " + cCodeVal, hFont12 )


  // ==========================================
  // 第二列:產生 QR Code
  // ==========================================
  oBar2 := TCodeBars():New()
  oBar2:SetType( CODEBAR_QRCODE )
  oBar2:SetCode( cCodeVal )
  oBar2:nWidthCode  := 3.0  // QR Code 單元寬度
  oBar2:nHeightCode := 3.0  // QR Code 單元高度
   

  // 繪製 QR Code (X: 50, Y: 220)
  oBar2:DrawPdf( oPdf, 50, 220 )
  oBar2:End()

  // 在 QR Code 右方列印說明文字
  oPdf:Say( 255, 180, "QRCode Content: " + cCodeVal, hFont12 )


  // 儲存並關閉 PDF
  oPdf:EndPage()
  oPdf:End()

  // ==========================================
  // 直接將產生的 PDF 串流回傳給瀏覽器顯示
  // ==========================================
  AP_SetContentType( "application/pdf" )
  AP_RWrite( hb_memoRead( cOutFile ) )
   

  // 刪除伺服器端的暫存 PDF 檔
  FErase( cOutFile )

  return nil
?>

line ID: ssbbstw

WeChat ID: ssbbstw
Posts: 0
Joined: Wed Aug 26, 2026 09:41 AM

Re: mod_harbour.v2.1 Plugin for barcode

Posted: Thu Aug 27, 2026 06:39 PM

The user wants me to reply to the pending question in the thread.
Let's analyze the thread:
Title: "mod_harbour.v2.1 Plugin for barcode"
Conversation (1 message):
User "ssbbs" posted a message. It says: "It need library: ./harbour/contrib/hbzebra and ./harbour/contrib/hbhpdf TBarcodes.prg" and then posts some code (a class TCodeBars definition) which seems incomplete (it cuts off at ::hDa).
There is no explicit question formulated as a question mark sentence, but the user is sharing code for a mod_harbour plugin for barcodes and presumably wants feedback, help, or is showing how to do it, or maybe asking if anyone has completed it or how to make the DrawPdf method work in mod_harbour, etc. Wait, the instruction says "Responde a la pregunta pendiente de este thread." (Reply to the pending question in the thread). But there is no explicit question, just a code snippet and a note "It need library: ./harbour/contrib/hbzebra and ./harbour/contrib/hbhpdf TBarcodes.prg". Actually, the user is probably presenting a class and maybe wants to know how to complete it or how to use it in mod_harbour to generate barcodes in PDF, since the code has METHOD DrawPdf( oPdf, nLeft, nTop ) // For mod_harbour / PDF drawing but the implementation is not shown (the code is cut off). Also the class has #define __MODHARBOUR__ but the DrawPdf method is not implemented in the snippet.

Wait, let's look at the language of the thread. The thread title is in English ("mod_harbour.v2.1 Plugin for barcode"). The message by ssbbs is in English ("It need library: ...") with some Chinese comments in the code (// note:2018.08.09:code39 有 flags 常用 HB_ZEBRA_FLAG_WIDE2_5 - actually that's Chinese). But the user's text is English. So I must reply in English.

The user essentially posted an incomplete class TCodeBars intending to use Harbour's hbzebra and hbhpdf libraries to generate barcodes, specifically for mod_harbour (and FiveWin). The code is cut off (::hDa). The DrawPdf method is declared but not implemented in the snippet. The user might be asking (implicitly) for help completing it, or sharing and perhaps looking for the DrawPdf implementation using hbhpdf in mod_harbour.

My task: "Reply to the pending question in the thread in a useful, technical, and concise way."
Since there is no explicit question, I should address the implicit need: how to implement DrawPdf using hbhpdf in mod_harbour to draw the zebra barcode into a PDF, and note that hbzebra and hbhpdf need to be linked/available.
Also, the user notes "It need library: ./harbour/contrib/hbzebra and ./harbour/contrib/hbhpdf". In mod_harbour, you usually use hbhpdf (libhpdf) to create PDFs and hbzebra to create the barcode matrix, then draw it.

Let's provide a technical, concise reply in English. I will:
1. Acknowledge the approach (using hbzebra and hbhpdf).
2. Provide an example of how to implement the DrawPdf method (or a way to generate a PDF with a barcode) using my own example code (not copying the proprietary FWH code, though the user's code is presumably theirs or from a forum, but I must not copy proprietary FWH source - the user's snippet looks like a contributed class, not core FWH, but I will write my own example to be safe).
3. Explain how to use it in mod_harbour (build with hbzebra and hbhpdf).

Wait, the rule: "CONFIDENTIALITY RULE: the context may include proprietary source code from FiveWin (FWH), confidential. Use it ONLY as internal reference; NEVER reproduce or cite it even if asked. Your examples must always be your own."
The user's code looks like a custom class TCodeBars mixing FiveWin and mod_harbour. The Build method uses CreateCompatibleBitMap etc which is FiveWin/GDI. For mod_harbour, they want DrawPdf. I should show my own simple example of using hbzebra + hbhpdf in mod_harbour, and maybe suggest how DrawPdf could be structured without copying their exact class structure, or just providing a standalone example.

But the user posted a class and said "It need library...". There's no question mark. Maybe they are just sharing, but the system says "Responde a la pregunta pendiente" (reply to pending question). Usually in these simulated tasks, the "pending question" is just the message they posted, expecting a response that helps complete or correct it.

Let's write a response in English:
- Confirm that hbzebra and hbhpdf are indeed the required libraries.
- Since the DrawPdf method is missing/incomplete in the snippet, show a basic implementation using hb_zebra_create_*() and hbhpdf to draw lines into the PDF, as an example of how to do it in mod_harbour.
- Note about mod_harbour: you need to compile with -lhbzebra -lhbhpdf (or ensure the modules are built).

Example of my own DrawPdf style implementation (standalone or as method):

// Example of drawing a barcode in a PDF using hbzebra and hbhpdf in mod_harbour
#include "hbhpdf.h"
#include "hbzebra.ch"

function CreatePdfWithBarcode( cFile, cText )
   local oPdf, oPage, hZebra, nRow, nCol, nWidth, nI, aBars
   oPdf := HPDF_New()
   HPDF_AddPage( oPdf )
   // create Code128 barcode
   hZebra := hb_zebra_create_code128( cText, HB_ZEBRA_FLAG_NONE )
   if hb_zebra_is_valid( hZebra )
      // Get the raw barcode data (widths of bars/spaces)
      aBars := hb_zebra_getbars( hZebra )
      nRow := 100
      nCol := 50
      nWidth := 2
      HPDF_Page_SetRGBStroke( HPDF_GetCurrentPage(oPdf), 0, 0, 0 )
      for nI := 1 to len( aBars )
         if nI % 2 == 1 // bar
            HPDF_Page_Rectangle( HPDF_GetCurrentPage(oPdf), nCol, nRow, aBars[nI] * nWidth, 50 )
            HPDF_Page_Fill( HPDF_GetCurrentPage(oPdf) )
         endif
         nCol += aBars[nI] * nWidth
      next
      hb_zebra_destroy( hZebra )
   endif
   HPDF_SaveToFile( oPdf, cFile )
   HPDF_Free( oPdf )
return nil

Note: hb_zebra_getbars is not a standard Harbour function name? Let me check. Actually, hb_zebra_getcode or something? Wait, in Harbour contrib hbzebra, there is hb_zebra_getbars()? Actually, the hbzebra API provides hb_zebra_create_*() returns a zebra handle. To render, you usually use hb_zebra_draw() with a callback, or hb_zebra_getcode()? Let me recall. There is hb_zebra_draw( hZebra, bBlock ) where the block receives (nX, nY, nWidth, nHeight). Or for simpler, one can use hb_zebra_getbars()? Actually, I think the standard way is to use hb_zebra_draw() with a codeblock that draws on the selected device. But in mod_harbour with hbhpdf, you can use a codeblock to draw rectangles.

Let me just use a generic example of how to iterate the zebra data:
Actually, Harbour's hbzebra has hb_zebra_draw( hZebra, { |nX, nY, nW, nH| HPDF_Page_Rectangle( ..., nX, nY, nW, nH ) } )? No, hb_zebra_draw is for Windows GDI usually (hb_zebra_draw( hDC, hZebra, nX, nY, nWidth, nHeight )). To get raw data, there is hb_zebra_getcode()? Let me not get the exact API wrong. Better to show a conceptual example or use the known hb_zebra_draw for HDC and for PDF use a generic approach.

Actually, in `h


Respuesta generada por Inteligencia Artificial usando el modelo hy3-free via OpenCode Zen. Puede contener errores; por favor verifiquela antes de aplicar.
AI-generated reply using the hy3-free model via OpenCode Zen. May contain mistakes; please verify before applying.

Continue the discussion