專注企業(yè)數(shù)據(jù)標(biāo)識 提升條碼集成價值

我們專注于智能數(shù)字化信息化解決方案,提供專業(yè)的條碼、IC卡、RFID射頻、視覺智能管理系統(tǒng)成套產(chǎn)品和解決方案,
20+年專業(yè)經(jīng)驗(yàn),專業(yè)定制適合企業(yè)自己的全套的自動識別方案,簡單、高效、低投入。


      首頁  條形碼新聞知識  條形碼新聞

VB應(yīng)用程序中打印條形碼的兩種方法



推薦:codesoft codesoft labelview codesoft中國總代理 labelmatrix CODESOFT2022 CODESOFT 行業(yè)應(yīng)用 teklynx codesoft CODESOFT條碼標(biāo)簽打印軟件 CODESOFT標(biāo)簽管理軟件 codesoft2024 codesoft TEKLYNX Software Development Kit (SDK) BACKTRACK 資產(chǎn)跟蹤解決方案 LABEL ARCHIVE 標(biāo)簽安全性與可跟蹤性軟件 SENTINEL 標(biāo)簽打印自動化軟件 TEKLYNX CENTRAL CFR-FDA 21 CFR Part 11 合規(guī)性標(biāo)簽軟件 TEKLYNX CENTRAL 一體化標(biāo)簽解決方案 TEKLYNX CENTRAL GHS 標(biāo)簽的合規(guī)性軟件 codesoft 條碼 條碼 條碼 廣州條碼打印機(jī) 條碼軟件 條碼打印機(jī) 條碼耗材 條碼槍 條碼 條碼

文:bitian   發(fā)表時間:2024-12-26 15:36:50

 產(chǎn)品咨詢:13928851814 黃'R

VB應(yīng)用程序中打印條形碼的兩種方法

  條形碼作為一種機(jī)器可識別的圖形,它能快速、準(zhǔn)確地標(biāo)識某種產(chǎn)品或商品,在許多數(shù)據(jù)庫應(yīng)用中起作很重要的作用,如超市收銀、車站售票等場合。當(dāng)某件物品上帶有的條形碼被條碼掃描器正確解讀后,將會得到該物品的唯一標(biāo)識字符串,通過檢索數(shù)據(jù)庫我們就可以很容易知道它的一些其它屬性并作相應(yīng)處理。雖然在Internet上能找到許多免費(fèi)和不免費(fèi)的條形碼打印控件,但是這些控件除了使用不方便外,還有一個最大的缺點(diǎn):它們的打印輸出不能和我們的程序共存在一個打印頁面上,比如說在一個過程中,我們先向系統(tǒng) Printer 中輸出一些內(nèi)容,然后再調(diào)用控件的條形碼打印方法,最后打印的結(jié)果為兩頁!,如果現(xiàn)在我們要處理一張車票,上面不僅要打印條形碼,還要有終點(diǎn)站和票價等信息,那么控件就變得不可用。對程序員來說,可能還是希望能了解條形碼打印的原理,本文提出兩種打印方法與同行們探討。

一、直接利用有條形碼打印功能的打印機(jī)

  有許多打印機(jī)能夠直接打印條形碼,但在 VB 中,我們在DOS時代熟悉的LPRINT語句已經(jīng)不能再使用了,打印操作被Windows的Spool系統(tǒng)完全接管,輸出是以“頁”為單位,所有的打印輸出都被Windows轉(zhuǎn)換為圖形發(fā)送給打印驅(qū)動程序。而要使打印機(jī)打印條形碼就必須將對應(yīng)的ESC序列直接發(fā)送給它,因此我們就要想辦法避開Windows的Spool系統(tǒng),也就是說再程序中不能使用Printer對象和Printers集合處理打印輸出,在VB中要將ESC指令直接發(fā)送給打印機(jī)至少有三種方法,前兩種方法是調(diào)用Windows API 函數(shù):Escape()和SpoolFile(),第三種是最容易的方法:打開打印機(jī)端口進(jìn)行二進(jìn)制存取,我們主要考慮這種方法。

  即使在Windows時代,”LPT1:”和”PRN”仍然是可用的,下面我們先作一個試驗(yàn):打開一個DOS窗口,在提示符下輸入COPY CON LPT1:回車,然后隨便輸入一些字符,最后按F6鍵,打印機(jī)就開始工作了,它將打印出你輸入的那些字符!下面的代碼演示了直接將指令和字符發(fā)送給打印機(jī):

Private Sub Command1_Click()

  Dim strOut As String

  StrOut = “這是直接發(fā)送到打印機(jī)端口的字符串”

  ‘ 打開打印機(jī)端口,其中的”LPT1:”可能需要根據(jù)你的打印機(jī)設(shè)置而改變

  Open “LPT1:” For Binary Access Write As #1

  ‘ 發(fā)送給打印機(jī),注意語句的最后一個參數(shù)必須是變量

    Put #1, ,strOut

    ‘ 關(guān)閉打印機(jī)端口

    Close #1

End Sub

  各種打印機(jī)打印條形碼的指令可能不同,比如將上面的變量 strOut賦值為:

  strOut = Chr(28) & “P” & Chr(5) & Chr(2) & Chr(3) & Chr(3) & Chr(6) & “012345”

  將在 AR2400 打印機(jī)上打印出內(nèi)容為”012345”的 CODE39 格式的條形碼。具體的打印控制指令請參考打印機(jī)手冊。

  用這種方法的缺點(diǎn):一是過份依賴打印機(jī)本身,而有條形碼打印功能的打印機(jī)通常要比普通打印機(jī)昂貴,這會使構(gòu)造應(yīng)用系統(tǒng)不夠經(jīng)濟(jì);二是所有的打印輸出都必須你自己處理,比如打印定位就很浪費(fèi)時間。

二、利用畫圖方式輸出到普通打印機(jī)

  條形碼的編碼規(guī)則不外乎是通過線條和線條間間隙的寬窄不同來表示二進(jìn)制的1和0,只要我們了解了條形碼的編碼規(guī)則,完全可以用畫圖的方式在普通打印機(jī)上得到可以接受的效果。下面我們就使用最普遍的CODE39碼進(jìn)行討論。

  CODE39碼的編碼規(guī)則是:

1、 每五條線表示一個字符;

2、 粗線表示1,細(xì)線表示0;

3、 線條間的間隙寬的表示1,窄的表示0;

4、 五條線加上它們之間的四條間隙就是九位二進(jìn)制編碼,而且這九位中必定有三位是1,所以稱為39碼;

5、 條形碼的首尾各一個*標(biāo)識開始和結(jié)束

  在我們的程序中,給常用的字符都進(jìn)行編碼,解讀時先取線條粗細(xì),再取間隙寬窄,如:

  上圖中的字符*就可以解讀為 001101000,字符3解讀為 110000100

  下面就是我們給出的子過程:

' 將字符串 strBarCode 對應(yīng)的條形碼輸出到缺省打印機(jī)

Private Sub PrintBarCode( _

  ByVal strBarCode As String, _

  Optional ByVal intXPos As Integer = 0, _

  Optional ByVal intYPos As Integer = 0, _

  Optional ByVal intPrintHeight As Integer = 10, _

  Optional ByVal bolPrintText As Boolean = True _

)

' 參數(shù)說明:

' strBarCode    - 要打印的條形碼字符串

' intXPos, intYPos - 打印條形碼的左上角坐標(biāo)(缺省為(0,0),坐標(biāo)刻度為:毫米)

' intHeight     - 打印高度(缺省為一厘米,坐標(biāo)刻度為:毫米)

' bolPrintText   - 是否打印人工識別字符(缺省為true)

' "0"-"9","A-Z","-","%","$"和"*" 的條碼編碼格式,總共 40 個字符

Static strBarTable(39) As String

' 初始化條碼編碼格式表

  strBarTable(0) = "001100100"   ' 0

  strBarTable(1) = "100010100"   ' 1

  strBarTable(2) = "010010100"   ' 2

  strBarTable(3) = "110000100"   ' 3

  strBarTable(4) = "001010100"   ' 4

  strBarTable(5) = "101000100"   ' 5

  strBarTable(6) = "011000100"   ' 6

  strBarTable(7) = "000110100"   ' 7

  strBarTable(8) = "100100100"   ' 8

  strBarTable(9) = "010100100"   ' 9

  strBarTable(10) = "100010010"  ' A

  strBarTable(11) = "010010010"  ' B

  strBarTable(12) = "110000010"  ' C

  strBarTable(13) = "001010010"  ' D

  strBarTable(14) = "101000010"  ' E

  strBarTable(15) = "011000010"  ' F

  strBarTable(16) = "000110010"  ' G

  strBarTable(17) = "100100010"  ' H

  strBarTable(18) = "010100010"  ' I

  strBarTable(19) = "001100010"  ' J

  strBarTable(20) = "100010001"  ' K

  strBarTable(21) = "010010001"  ' L

  strBarTable(22) = "110000001"  ' M

  strBarTable(23) = "001010001"  ' N

  strBarTable(24) = "101000001"  ' O

  strBarTable(25) = "011000001"  ' P

  strBarTable(26) = "000110001"  ' Q

  strBarTable(27) = "100100001"  ' R

  strBarTable(28) = "010100001"  ' S

  strBarTable(29) = "001100001"  ' T

  strBarTable(30) = "100011000"  ' U

  strBarTable(31) = "010011000"  ' V

  strBarTable(32) = "110001000"  ' W

  strBarTable(33) = "001011000"  ' X

  strBarTable(34) = "101001000"  ' Y

  strBarTable(35) = "011001000"  ' Z

  strBarTable(36) = "000111000"  ' -

  strBarTable(37) = "100101000"  ' %

  strBarTable(38) = "010101000"  ' $

  strBarTable(39) = "001101000"  ' *

  If strBarCode = "" Then Exit Sub ' 不打印空串

  ' 保存打印機(jī) ScaleMode

  Dim intOldScaleMode As ScaleModeConstants

  intOldScaleMode = Printer.ScaleMode

  ' 保存打印機(jī) DrawWidth

  Dim intOldDrawWidth As Integer

  intOldDrawWidth = Printer.DrawWidth

  ' 保存打印機(jī) Font

  Dim fntOldFont As StdFont

  Set fntOldFont = Printer.Font

  Printer.ScaleMode = vbTwips ' 設(shè)置打印用的坐標(biāo)刻度為緹(twip=1)

  Printer.DrawWidth = 1   ' 線寬為 1

  Printer.FontName = "宋體" ' 打印在條碼下方字符的字體和大小

  Printer.FontSize = 10

  Dim strBC As String     ' 要打印的條碼字符串

  strBC = Ucase(strBarCode)

  ' 將以毫米表示的 X 坐標(biāo)轉(zhuǎn)換為以緹表示

  Dim x As Integer

  x = Printer.ScaleX(intXPos, vbMillimeters, vbTwips)

  ' 將以毫米表示的 Y 坐標(biāo)轉(zhuǎn)換為以緹表示

  Dim y As Integer

  y = Printer.ScaleY(intYPos, vbMillimeters, vbTwips)

  ' 將以毫米表示的高度轉(zhuǎn)換為以緹表示

  Dim intHeight As Integer

  intHeight = Printer.ScaleY(intPrintHeight, vbMillimeters, vbTwips)

  ' 是否在條形碼下方打印人工識別字符

  If bolPrintText = True Then

    ' 條碼打印高度要減去下面的字符顯示高度

    intHeight = intHeight - Printer.TextHeight(strBC)

  End If

  Const intWidthCU As Integer = 30 ' 粗線和寬間隙寬度

  Const intWidthXI As Integer = 10 ' 細(xì)線和窄間隙寬度

  Dim intIndex As Integer      ' 當(dāng)前處理的字符串索引

  Dim i As Integer, j As Integer, k As Integer  ' 循環(huán)控制變量

  ' 添加起始字符

  If Left(strBC, 1) <> "*" Then

    strBC = "*" & strBC

  End If

  ' 添加結(jié)束字符

  If Right(strBC, 1) <> "*" Then

    strBC = strBC & "*"

  End If

  ' 循環(huán)處理每個要顯示的條碼字符

  For i = 1 To Len(strBC)

    ' 確定當(dāng)前字符在 strBarTable 中的索引

    Select Case Mid(strBC, i, 1)

    Case "*"

      intIndex = 39

    Case "$"

      intIndex = 38

    Case "%"

      intIndex = 37

    Case "-"

      intIndex = 36

    Case "0" To "9"

      intIndex = CInt(Mid(strBC, i, 1))

    Case "A" To "Z"

      intIndex = Asc(Mid(strBC, i, 1)) - Asc("A") + 10

    Case Else

      MsgBox "要打印的條形碼字符串中包含無效字符!當(dāng)前版本只支持字符 '0'-'9','A'-'Z','-','%','$'和'*'"

    End Select

    ' 是否在條形碼下方打印人工識別字符

    If bolPrintText = True Then

      Printer.CurrentX = x

      Printer.CurrentY = y + intHeight

      Printer.Print Mid(strBC, i, 1)

    End If

    For j = 1 To 5

      ' 畫細(xì)線

      If Mid(strBarTable(intIndex), j, 1) = "0" Then

        For k = 0 To intWidthXI - 1

          Printer.Line (x + k, y)-Step(0, intHeight)

        Next k

        x = x + intWidthXI

      ' 畫寬線

      Else

        For k = 0 To intWidthCU - 1

          Printer.Line (x + k, y)-Step(0, intHeight)

        Next k

        x = x + intWidthCU

      End If

      ' 每個字符條碼之間為窄間隙

      If j = 5 Then

        x = x + intWidthXI * 3

        Exit For

      End If

      ' 窄間隙

      If Mid(strBarTable(intIndex), j + 5, 1) = "0" Then

        x = x + intWidthXI * 3

      ' 寬間隙

      Else

        x = x + intWidthCU * 2

      End If

    Next j

  Next i

  ' 恢復(fù)打印機(jī) ScaleMode

  Printer.ScaleMode = intOldScaleMode

  ' 恢復(fù)打印機(jī) DrawWidth

  Printer.DrawWidth = intOldDrawWidth

  ' 恢復(fù)打印機(jī) Font

  Set Printer.Font = fntOldFont

End Sub

  最理想的情況是將它做成一個控件,在控件中提供一個打印方法,該方法實(shí)現(xiàn)與上

  那個過程大致相同,只是不能在控件中直接使用VB的Printer對象,否則VB會將你在控件中的打印輸出處理為一個單獨(dú)的頁面,而是應(yīng)該將Printer.hDc傳給它,通過調(diào)用那些需要指定 HDC 的Windows API函數(shù)實(shí)現(xiàn)與容器的打印輸出在一個頁面上,比如我們可以這樣定義這個控件的打印方法:

' PrintIt 方法將對應(yīng)的條形碼輸出到缺省打印機(jī)

Public Sub PrintIt(ByVal PrintDC As Long, _

   Optional ByVal intXPos As Integer = 0, _

  Optional ByVal intYPos As Integer = 0, _

   Optional ByVal intPrintHeight As Integer = 10)

  既然不能使用Printer對象,那么畫線和輸出文字也不能使用Printer對象的Line和Print方法,在我們的程序中至少要申明以下三個Windows API函數(shù):

‘ 移動畫筆的位置

Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long

‘ 從畫筆的當(dāng)前位置到(x,y)畫一條線

Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

‘ 在(x,y)處輸出一個字符串

Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long

‘ MoveToEx() 函數(shù)需要的參數(shù)

Private Type POINTAPI

  xp As Long

  yp As Long

End Type

Dim papi As POINTAPI

  畫線操作為(原來的Printer.Line函數(shù)):

MoveToEx PrintDC, x + k, y, papi

LineTo PrintDC, x + k, y + intHeight + 1

  打印字符為(原來的Printer.Print函數(shù)):

TextOut PrintDC, x, y + intHeight, Mid(strBC, i + 1, 1), 1

[返回主頁] [關(guān)閉窗口]
推薦:teklynx codesoft CODESOFT條碼標(biāo)簽打印軟件 CODESOFT標(biāo)簽管理軟件 codesoft2024 codesoft CODESOFT 行業(yè)應(yīng)用 codesoft 展會pda報價 圖紙條碼管理 生產(chǎn)線條碼管理 Argox a150 北洋btp2100e codesoft條碼軟件 bartender條碼軟件 條碼耗材 條碼軟件 條碼產(chǎn)品 symbol mc1000 采集器 citizen clp621 clp621 clp631 citizen clp631 廣州條碼色帶 廣州條碼碳帶 色帶 碳帶 條碼色帶 條碼碳帶 條碼標(biāo)簽 標(biāo)簽 條碼軟件 條碼軟件 廣州條碼標(biāo)簽 codesoft bartender 條形碼標(biāo)簽打印機(jī) 條碼標(biāo)簽打印機(jī) 標(biāo)簽打印軟件 Labelmatrix Labelview Intermec pd42 btp2100e Argox a-150 TSC 342 條碼 條碼 條形碼 條碼軟件 條碼打印機(jī) 條碼耗材 條碼槍 條碼
Copyright © 2004-2024 廣州比天信息科技 All rights reserved
友情鏈接:條形碼  條形碼 條碼