65.9K
CodeProject 正在变化。 阅读更多。
Home

高级条形码生成系统,符合 Code 39 标准

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (11投票s)

2009年3月20日

Ms-PL

2分钟阅读

viewsIcon

75348

downloadIcon

12457

轻松开发软件,为在 Avery 8167 标签(文档和盒子标签,或更多基于定制)上打印完全自定义的 Code 39 条形码。

引言

ITS, LLC 条形码生成系统生成 C39 条形码标签,用于打印在 Avery 8167 标签上。该软件的开发是为了打印用于文档箱和文档(实际文档和监管链日志)的标签,以便使用箱子等跟踪文档。

该软件允许在标签创建和配置时进行以下操作

  • 盒子标签打印(每页 80 个唯一标签)
  • 文档夹标签打印(每页 40 个唯一标签,CCT 双重输入)
  • 自动扫描盒子条形码标签以生成文档标签
  • 条形码绘图样式的进阶配置
  • 打印选项的配置,用于条形码页面生成的物理交付

背景

关于该软件的背景信息;该软件设计用于打印在 Avery 8167 标签上,每页有 80 个标签——然而,通过一些配置,您也可以用它打印在其他样式的标签上。

该软件基于 Microsoft .NET Framework 开发,并大量使用 Microsoft .NET GDI+ 系统来绘制条形码。它**不**使用字体来写入条形码。

Using the Code

代码相当简单明了,并且注释非常完善。但与往常一样,如果您有任何问题或评论,请随时与我联系,或在 CodeProject 页面上留下评论/问题。

有一些直接摘录;实际上,它几乎是来自下面主要的条形码工作区的完整代码。

这是主要的条形码生成系统,允许生成每个条形码图像

Public Class mainBarcodeWorkspace
    Private _encoding As Hashtable = New Hashtable
    Private Const _wideBarWidth As Short = 2
    Private Const _narrowBarWidth As Short = 1
    Private Const _barHeight As Short = 31

    'Here we define the page counters -- this comes into play later!
    Public totalPages As Integer = 1
    Public curPage As Integer = 0

    'Create a new box scan form
    Public boxScanFrm As boxScan = New boxScan

    'Declare the return timer countdown (seconds before return to the box scanner)
    Public returnTimer As Integer = 15

    'Define the main barcode canvas used for the master page
    Dim barcodeCanvas As Bitmap

    'Declare the printing object 
    '(used later for sending the barcode canvas to a printer)
    Private WithEvents m_PrintDocument As Printing.PrintDocument

#Region "Barcode Generation System"
    'This adds keys to the encoding hashtable, 
    'which tells us exactly what we need to draw later in GDI
    'But more or less, these are the encoding bits 
    'for each of the Code39 allowable characters
    Sub ITS_BarcodeC39()
        _encoding.Add("*", "bWbwBwBwb")
        _encoding.Add("-", "bWbwbwBwB")
        _encoding.Add("$", "bWbWbWbwb")
        _encoding.Add("%", "bwbWbWbWb")
        _encoding.Add(" ", "bWBwbwBwb")
        _encoding.Add(".", "BWbwbwBwb")
        _encoding.Add("/", "bWbWbwbWb")
        _encoding.Add("+", "bWbwbWbWb")
        _encoding.Add("0", "bwbWBwBwb")
        _encoding.Add("1", "BwbWbwbwB")
        _encoding.Add("2", "bwBWbwbwB")
        _encoding.Add("3", "BwBWbwbwb")
        _encoding.Add("4", "bwbWBwbwB")
        _encoding.Add("5", "BwbWBwbwb")
        _encoding.Add("6", "bwBWBwbwb")
        _encoding.Add("7", "bwbWbwBwB")
        _encoding.Add("8", "BwbWbwBwb")
        _encoding.Add("9", "bwBWbwBwb")
        _encoding.Add("A", "BwbwbWbwB")
        _encoding.Add("B", "bwBwbWbwB")
        _encoding.Add("C", "BwBwbWbwb")
        _encoding.Add("D", "bwbwBWbwB")
        _encoding.Add("E", "BwbwBWbwb")
        _encoding.Add("F", "bwBwBWbwb")
        _encoding.Add("G", "bwbwbWBwB")
        _encoding.Add("H", "BwbwbWBwb")
        _encoding.Add("I", "bwBwbWBwb")
        _encoding.Add("J", "bwbwBWBwb")
        _encoding.Add("K", "BwbwbwbWB")
        _encoding.Add("L", "bwBwbwbWB")
        _encoding.Add("M", "BwBwbwbWb")
        _encoding.Add("N", "bwbwBwbWB")
        _encoding.Add("O", "BwbwBwbWb")
        _encoding.Add("P", "bwBwBwbWb")
        _encoding.Add("Q", "bwbwbwBWB")
        _encoding.Add("R", "BwbwbwBWb")
        _encoding.Add("S", "bwBwbwBWb")
        _encoding.Add("T", "bwbwBwBWb")
        _encoding.Add("U", "BWbwbwbwB")
        _encoding.Add("V", "bWBwbwbwB")
        _encoding.Add("W", "BWBwbwbwb")
        _encoding.Add("X", "bWbwBwbwB")
        _encoding.Add("Y", "BWbwBwbwb")
        _encoding.Add("Z", "bWBwBwbwb")
    End Sub

    'This returns a color associated with the current line drawing 
    'in GDI, since it's a barcode we primarly want a contrasting
    'color and a light background color, so depending on what 
    'the character is (whether it's a char or white space) we add color
    Protected Function getBCSymbolColor(ByVal symbol As String) _
                       As System.Drawing.Brush
        getBCSymbolColor = Brushes.Black
        If symbol = "W" Or symbol = "w" Then

            getBCSymbolColor = Brushes.White
        End If
    End Function

    'Now we determine whether or not we are going to be drawing 
    'a small or large BC bar on this character code
    Protected Function getBCSymbolWidth(ByVal symbol As String) As Short
        getBCSymbolWidth = _narrowBarWidth
        If symbol = "B" Or symbol = "W" Then
            getBCSymbolWidth = _wideBarWidth
        End If
    End Function

    'Now the fun part, this function is called to generate the actual barcode
    Protected Overridable Function GenerateBarcodeImage(ByVal imageWidth As Short, _
              ByVal imageHeight As Short, ByVal Code As String) As IO.MemoryStream
        'Declare a new bitmap canvas to store our new barcode 
        '(well, it will be new -- we will make it soon)!
        Dim b As New Bitmap(imageWidth, imageHeight, _
                     Imaging.PixelFormat.Format32bppArgb)

        'Create the actualy canvas associated with the barcode drawing       
        Dim canvas As New Rectangle(0, 0, imageWidth, imageHeight)

        'Create our graphics object from our barcode canvas
        Dim g As Graphics = Graphics.FromImage(b)

        'Fill the drawing with a white background
        g.FillRectangle(Brushes.White, 0, 0, imageWidth, imageHeight)

        'Draw the "eye candy" items on the barcode canvas
        'Here we are drawing the gradient directly behind the barcode are at the top
        g.FillRectangle(New Drawing2D.LinearGradientBrush(_
           New Drawing.RectangleF(1, 1, 169, 30), Color.White, _
           Color.LightGray, Drawing2D.LinearGradientMode.Vertical), 1, 1, 169, 30)

        'Now we draw the seperation line (under barcode) 
        'and the liner gradient background
        g.FillRectangle(New Drawing2D.LinearGradientBrush(_
          New Drawing.RectangleF(1, 34, 169, 15), Color.LightGray, _
          Color.White, Drawing2D.LinearGradientMode.Vertical), 1, 34, 169, 15)
        g.FillRectangle(New SolidBrush(Color.Black), 1, 33, 169, 1)

        'Now that we have the "fine art" drawn, 
        'let's switch over to high-quality rendering for our text and images
        'However, we are using SingleBitPerPixel because when 
        'printed it appears sharper as opposed to anti-aliased
        g.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
        g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
        g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality

        'If we are printing a box label then we need to add a side image 
        'and a "BOX" announcment on the right.
        If boxNumber.Enabled = False Then
            g.DrawImage(My.Resources.Shipping, 10, 2, 23, 23)
            g.DrawString("BOX", New Font("Tahoma", 10, _
                         FontStyle.Bold), New SolidBrush(Color.Silver), 129, 7)

            'Write out the original barcode ID, and preceed it with "BOX"
            g.DrawString("Box " & Code, New Font("Tahoma", _
                         8, FontStyle.Bold), New SolidBrush(Color.Black), 3, 34)
        Else
            'Write out the original barcode ID
            g.DrawString(Code, New Font("Tahoma", 8, FontStyle.Bold), _
                               New SolidBrush(Color.Black), 3, 34)
        End If

        'Write out a lighter barcode generation script version 
        'on the right (again, eye candy)
        g.DrawString("ITS v2.0", New Font("Tahoma", 8, _
                     FontStyle.Bold), New SolidBrush(Color.Gray), 113, 34)

        'Now that we are done with the high quality rendering, we are going 
        'to draw the barcode lines -- which needs to be very straight, and not blended
        'Else it may blur and cause complications with the barcode 
        'reading device -- so we won't take any chances.
        g.TextRenderingHint = Drawing.Text.TextRenderingHint.SystemDefault
        g.SmoothingMode = Drawing2D.SmoothingMode.None
        g.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor
        g.CompositingQuality = Drawing2D.CompositingQuality.Default

        'Code has to be surrounded by asterisks to make it a valid C39 barcode, 
        'so add "*" to the front and read of the barcode
        Dim UseCode As String = String.Format("{0}{1}{0}", "*", Code)

        'Define a starting X and Y position for the barcode
        Dim XPosition As Short = 1
        Dim YPosition As Short = 1

        'Initialize our IC marker, and give a default of false
        'This is used to track what?  Incorrectly assigned 
        'characters for the barcode (ones that won't match
        'C39 standards) So we don't use them, and mark it as invalid.
        Dim invalidCharacter As Boolean = False

        'Declare our current character string holding variable
        Dim CurrentSymbol As String = String.Empty

        'THIS PART IS *ONLY* FOR CALCULATING THE WIDTH OF THE BARCODE TO CENTER IT!
        'Begin at the starting area of our FINAL rendered barcode value
        For j As Short = 0 To CShort(UseCode.Length - 1)
            'Set our current character to the character space of the barcode
            CurrentSymbol = UseCode.Substring(j, 1)

            'Check to ensure that it's a valid character 
            'per our encoding hashtable we defined earlier
            If Not IsNothing(_encoding(CurrentSymbol)) Then
                'Create a new rendered version of the character per our 
                'hashtable with valid values (don't read it, 
                'it will be encoded -- look above at the HT)
                Dim EncodedSymbol As String = _encoding(CurrentSymbol).ToString

                'Progress throughout the entire encoding value of this character
                For i As Short = 0 To CShort(EncodedSymbol.Length - 1)
                    'Extract the current encoded character value from 
                    'the complete rendering of this character (it's getting deep, right?)
                    Dim CurrentCode As String = EncodedSymbol.Substring(i, 1)

                    'Change our coordinates for drawing to match the next 
                    'position (current position plus the char. bar width)
                    XPosition = XPosition + getBCSymbolWidth(CurrentCode)
                Next

                'Now we need to "create" a whitespace as needed, and get the width
                XPosition = XPosition + getBCSymbolWidth("w")
            End If
        Next

        'Now the nice trick of division helps with centering the barcode on the canvas
        XPosition = (imageWidth / 2) - (XPosition / 2)

        'NOW WE GO LIVE!  THIS IS WHERE WE ACTUALLY DRAW THE BARCODE BARS
        'Begin at the starting area of our FINAL rendered barcode value
        For j As Short = 0 To CShort(UseCode.Length - 1)
            'Set our current character to the character space of the barcode
            CurrentSymbol = UseCode.Substring(j, 1)

            'Check to ensure that it's a valid character per our encoding 
            'hashtable we defined earlier                  
            If Not IsNothing(_encoding(CurrentSymbol)) Then
                'Create a new rendered version of the character per our 
                'hashtable with valid values (don't read it, 
                'it will be encoded -- look above at the HT)
                Dim EncodedSymbol As String = _encoding(CurrentSymbol).ToString

                'Progress throughout the entire encoding value of this character
                For i As Short = 0 To CShort(EncodedSymbol.Length - 1)
                    'Extract the current encoded character value from 
                    'the complete rendering of this character (it's getting deep, right?)
                    Dim CurrentCode As String = EncodedSymbol.Substring(i, 1)

                    'Use our drawing graphics object on the canvase to create 
                    'a bar with out position and values based
                    'on the current character encoding value
                    g.FillRectangle(getBCSymbolColor(CurrentCode), XPosition, _
                                    YPosition, getBCSymbolWidth(CurrentCode), _barHeight)
                    'Lets disect this a little to see how it actually works, want to?
                    '   getBCSymbolColor(CurrentCode)
                    '       We already know, but this gets the color of the bar,
                    '       either white or colorized (in this case, black)
                    '   XPosition, YPosition
                    '       Again, we already know -- but this is the coordinates
                    '       to draw the bar based on previous locations
                    '   getBCSymbolWidth(CurrentCode)
                    '       This is the important part, we get the correct width 
                    '       (either narrow or wide) for this character (post encoding)
                    '   _barHeight
                    '       This is static as defined earlier, it doesn't much 
                    '       matter but it also depends on your Barcode reader

                    'Change our coordinates for drawing to match the next position 
                    '(current position plus the char. bar width)
                    XPosition = XPosition + getBCSymbolWidth(CurrentCode)
                Next

                'Now we need to "ACTUALLY" create 
                'a whitespace as needed, and get the width
                g.FillRectangle(getBCSymbolColor("w"), XPosition, _
                                YPosition, getBCSymbolWidth("w"), _barHeight)

                'Change our coordinates for drawing to match the next position 
                '(current position plus the char. bar width)
                XPosition = XPosition + getBCSymbolWidth("w")
            Else
                'This is our fallback, if it's not a valid 
                'character per our hashtable in C39, discard!
                invalidCharacter = True
            End If
        Next

        'As we set it above (if needed) for an invalid character 
        '(not allowed by the C39 guide), then we handle it here  
        If invalidCharacter Then
            'Just fill the whole canvas white
            g.FillRectangle(Brushes.White, 0, 0, imageWidth, imageHeight)

            'What's the deal?  Tell them!  It's not right, so we can't do it -- here is why.
            g.DrawString("Invalid Charachers Detected", _
                         New Font("Tahoma", 8), New SolidBrush(Color.Red), 0, 0)
            g.DrawString("- Barcode Not Generated -", _
                         New Font("Tahoma", 8), New SolidBrush(Color.Black), 0, 10)
            g.DrawString(Code, New Font("Tahoma", 8, FontStyle.Italic), _
                         New SolidBrush(Color.Black), 0, 30)
        End If

        'Create a new memorystream to use with our function return
        Dim ms As New IO.MemoryStream

        'Setup the encoding quality of the final barcode rendered image
        Dim encodingParams As New EncoderParameters
        encodingParams.Param(0) = New EncoderParameter(Encoder.Quality, 100)

        'Define the encoding details of "how" for the image
        'We will use PNG because, well it's got the best image quality for it's footprint
        Dim encodingInfo As ImageCodecInfo = FindCodecInfo("PNG")

        'Save the drawing directly into the stream
        b.Save(ms, encodingInfo, encodingParams)

        'Clean-up!  Nobody likes a possible memory leaking application!
        g.Dispose()
        b.Dispose()

        'Finally, return the image via the memorystream
        Return ms
    End Function

这是我们在将图像发送到返回的内存流之前设置图像编码的地方

    'Find the encoding method in the codec list 
    'on the computer based on the known-name (PNG, JPEG, etc)
    Protected Overridable Function FindCodecInfo(ByVal codec As String) As ImageCodecInfo
        Dim encoders As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders
        For Each e As ImageCodecInfo In encoders
            If e.FormatDescription.Equals(codec) Then Return e
        Next
        Return Nothing
    End Function
#End Region

现在,我们开始实际打印条形码,包括物理打印和屏幕打印...

#Region "Printing Methods (Physical Printing and On-Screen Printing)"
    'PHYSICAL PRINTING
    'This is a method that just basically sends the current barcode 
    'renderings to the printer under the printing options
    Public Sub doPrintActive()
        m_PrintDocument = New Printing.PrintDocument
        m_PrintDocument.PrinterSettings = PrintDialog1.PrinterSettings
        m_PrintDocument.DefaultPageSettings.Color = False
        m_PrintDocument.DefaultPageSettings.Margins = _
                New System.Drawing.Printing.Margins(8.5, 8.5, 35, 35)
        m_PrintDocument.Print()
    End Sub
    Private Sub m_PrintDocument_PrintPage(ByVal sender As Object, _
            ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
            Handles m_PrintDocument.PrintPage
        'Dim x As Integer = e.MarginBounds.X + _
        '     (e.MarginBounds.Width - barcodeCanvas.Width) \ 2
        'Dim y As Integer = e.MarginBounds.Y + _
        '     (e.MarginBounds.Height - barcodeCanvas.Height) \ 2

        Dim x As Integer = e.MarginBounds.X
        Dim y As Integer = e.MarginBounds.Y
        e.Graphics.DrawImage(barcodeCanvas, x, y)
        e.HasMorePages = False
    End Sub


    'LOGICAL/ON-SCREEN PRINTING
    'This is an extended method that we call when we want 
    'to generate the barcodes and display them, or print them
    Public Sub doPrintNow()
        'Set our current page counter and determine the total pages to be printed
        curPage = 0

        'This depends on whether we are printing a box label or a document label because...
        '   BOX Labels
        '       We only need one label, so we can print the whole sheet with unique labels
        '       The Avery 8167 labels have 80 labels per sheet
        '   DOC Labels
        '       We need TWO labels per document (one for the document,
        '       and one for the chain-of-custody log)
        '       Since the Avery 8167 paper has 80 labels, we want
        '       to print one unique label per two items horizontal
        '           This means that we will print like this... 
        '                   |LABEL 1| |LABEL 1| |LABEL 21| |LABEL 21|
        '                   |LABEL 2| |LABEL 2| |LABEL 22| |LABEL 22|
        If boxNumber.Enabled = True Then
            totalPages = (CInt(bcEnd.Text) - (CInt(bcStart.Text) + 1)) / 40
        Else
            totalPages = (CInt(bcEnd.Text) - (CInt(bcStart.Text) + 1)) / 80
        End If

        'Set our toolstrip status text
        ToolStrip_StatusLabel.Text = "Generating barcodes..."

        'If it appears this printing session will not be effecient, 
        'alert the user before we just "continue"
        If NotEffecientLabel.Visible Then
            Dim surePrint As MsgBoxResult = _
              MsgBox("It appears this label printing session isn't effecient!" & _
              Chr(13) & Chr(13) & "Are you sure you would like to continue?", _
              MsgBoxStyle.Information + MsgBoxStyle.YesNo, Me.Text)

            If surePrint = MsgBoxResult.No Then
                Exit Sub
            End If
        End If

        'Declare the current barcode holding variable 
        'and the current barcode render object
        Dim barcode As String
        Dim thisBarCode As Bitmap

        'Define a new barcode canvas drawing object with a 8.5" x 11" 
        'A4 paper (around there -- we add padding later)
        'barcodeCanvas = New Bitmap(1275, 1650)
        barcodeCanvas = New Bitmap(766, 960)

        'Create our trusty graphics object for this canvas
        Dim dc As Graphics = Graphics.FromImage(barcodeCanvas)

        'Make it white! (the background of the canvas)
        dc.Clear(Color.White)

        'Declare our placeholders for coordinates used on drawing the barcode object
        Dim pgX As Integer = 0
        Dim pgXc As Integer = 0

        Dim pgY As Integer = 0

        'Declare our counter so we can apply various actions at different levels
        Dim newColCounter As Integer = 1
        Dim i As Integer

        'Remember, if "BoxNumber" is enabled, 
        'then we are printing a DOCUMENT label, if not -- it's a BOX
        If boxNumber.Enabled = True Then
            'IT IS A DOCUMENT LABEL
            'Loop through however many labels the user requested
            For i = CInt(bcStart.Text) To CInt(bcEnd.Text)
                'Set our status label again with the "status" and the completion progress
                ToolStrip_StatusLabel.Text = "Generating Barcodes " & i & _
                     " (" & Math.Round((i / CInt(bcEnd.Text)) * 100, 0) & "%)..."

                'Define a variable to hold our box number, and our page number
                Dim bid As String = "0"
                Dim pid As String = "0"

                'Determine the boxnumber and preceed it with zeros 
                'if needed, we want it to occupy 4 spaces so
                'We will always have a consistent width on the barcode 
                '(just, I don't know (desire for perfection maybe?) -- you will see)
                If Len(boxNumber.Text) < 4 Then
                    Select Case 4 - Len(boxNumber.Text)
                        Case 1
                            bid = "0" & boxNumber.Text
                        Case 2
                            bid = "00" & boxNumber.Text
                        Case 3
                            bid = "000" & boxNumber.Text
                    End Select
                Else
                    bid = boxNumber.Text
                End If

                'Do the same thing for the page number 
                '(well, techically not page number -- but document ID)
                If Len(CStr(i)) < 4 Then
                    Select Case 4 - Len(CStr(i))
                        Case 1
                            pid = "0" & CStr(i)
                        Case 2
                            pid = "00" & CStr(i)
                        Case 3
                            pid = "000" & CStr(i)
                    End Select
                Else
                    pid = CStr(i)
                End If

                'Set the barcode "code" with what we created
                barcode = bid & "-" & pid

                'Request that the barcode be rendered and exported
                'via memorystream into our new barcode holder
                thisBarCode = New Bitmap(GenerateBarcodeImage(169, 48, barcode))

                'Draw the barcode onto the barcode printing page canvas
                dc.DrawImage(thisBarCode, New PointF(pgX, pgY))

                'Increase our X coordinates, since we need 
                'to draw another EXACT label to the right
                pgX = pgX + (169 + 30)

                'Draw it again at the new position
                dc.DrawImage(thisBarCode, New PointF(pgX, pgY))

                'Reset the X position and drop down a single label instance
                pgY = pgY + 48
                pgX = pgXc

                'If we have filled a column of the label page, we need to...
                If newColCounter = 20 Then
                    'Move to the third column (because we occupy 2 columns with DOC labels)
                    pgXc = (165 * 2) + (32.5 * 2)

                    'Reset the Y position and save the X constant variable
                    pgY = 0
                    pgX = pgXc
                End If

                'Update our current view within the application with what we have so far
                PictureBox1.Image = barcodeCanvas

                'If we have filled the entire page and there *ARE* more 
                'labels that need to be drawn, we need to make a new page... but not before
                'Printing this current page (if the user has requested it), 
                'else we will lose what we just did!
                If newColCounter = 40 And CInt(bcEnd.Text) > i Then
                    'Update the current page counter
                    curPage = curPage + 1

                    'Update the progress bar
                    printingProgressBar.Visible = True
                    printingProgressBar.Maximum = totalPages
                    printingProgressBar.Value = curPage
                    Me.Refresh()
                    Application.DoEvents()

                    'Check to see if the user wants us to print the labels or not
                    If printLabels.Checked Then
                        'Yep, they sure do!  So do it!
                        ToolStrip_StatusLabel.Text = "Printing Label Page " & _
                          curPage & " (" & _
                          Math.Round((curPage / totalPages)) * 100 & "%)..."
                        Me.Refresh()
                        Application.DoEvents()

                        doPrintActive()
                    End If

                    'Start a new page and continue on...
                    dc.Clear(Color.White)

                    'Reset the coordinates for the new page
                    pgXc = 0
                    pgY = 0
                    pgX = pgXc

                    'Reset our column counter as well
                    newColCounter = 0
                End If

                'Increase the column counter
                newColCounter = newColCounter + 1
            Next
        Else
            'IT IS A BOX LABEL
            'Just refer to the above comments, if there 
            'is anything different I will point it out here
            For i = CInt(bcStart.Text) To CInt(bcEnd.Text)
                ToolStrip_StatusLabel.Text = "Generating Barcodes " & _
                  i & " (" & Math.Round((i / CInt(bcEnd.Text)) * 100, 0) & "%)..."

                'Since this is a BOX label, we don't need to determine the document ID
                Dim pid As String = "0"
                If Len(CStr(i)) < 4 Then
                    Select Case 4 - Len(CStr(i))
                        Case 1
                            pid = "0" & CStr(i)
                        Case 2
                            pid = "00" & CStr(i)
                        Case 3
                            pid = "000" & CStr(i)
                    End Select
                Else
                    pid = CStr(i)
                End If

                'A little different code format for this one
                barcode = pid
                thisBarCode = New Bitmap(GenerateBarcodeImage(169, 48, barcode))
                dc.DrawImage(thisBarCode, New PointF(pgX, pgY))

                'You can see we aren't drawing two of them now, 
                'we are just dropping straight down and moving on
                pgY = pgY + 48
                pgX = pgXc

                'Now we have different numbers based on wheter 
                'we are on one column, two, three, or the last
                If newColCounter = 20 Then
                    pgXc = 165 + 32.5

                    pgY = 0
                    pgX = pgXc
                End If
                If newColCounter = 40 Then
                    pgXc = (165 * 2) + (32.5 * 2)

                    pgY = 0
                    pgX = pgXc
                End If
                If newColCounter = 60 Then
                    pgXc = (165 * 3) + (32.5 * 3)

                    pgY = 0
                    pgX = pgXc
                End If

                'Update the current view of the barcodes page
                PictureBox1.Image = barcodeCanvas

                'The page is full -- and we have more, 
                'if we get to this conditional and it's true
                If newColCounter = 80 And CInt(bcEnd.Text) > i Then
                    curPage = curPage + 1
                    printingProgressBar.Visible = True
                    printingProgressBar.Maximum = totalPages
                    printingProgressBar.Value = curPage
                    Me.Refresh()
                    Application.DoEvents()

                    'If we need to print, do it!
                    If printLabels.Checked Then
                        ToolStrip_StatusLabel.Text = "Printing Label Page " & _
                          curPage & " (" & _
                          Math.Round((curPage / totalPages)) * 100 & "%)..."
                        Me.Refresh()
                        Application.DoEvents()

                        doPrintActive()
                    End If

                    'Clear it and start over.
                    dc.Clear(Color.White)
                    pgXc = 0

                    pgY = 0
                    pgX = pgXc

                    newColCounter = 0
                End If

                'Increase column counter
                newColCounter = newColCounter + 1
            Next
        End If

        'Lastly, since we are on the last page -- if we need to print -- do it!
        If printLabels.Checked Then
            ToolStrip_StatusLabel.Text = "Printing Label Page " & curPage & _
              " (" & Math.Round((curPage / totalPages)) * 100 & "%)..."
            Me.Refresh()

            doPrintActive()
        End If

        'We're finished, so update the interface!
        ToolStrip_StatusLabel.Text = "Finished (idle)"
        printingProgressBar.Visible = False

        'Start the timer to return to the box scanning area
        returnToBoxScanTimer.Start()
        returnToBoxScanPanel.Visible = True
    End Sub
#End Region

我们使用以下代码计算打印条形码的页面需求(标签的物理页面)。然后,我们将其写给用户审查,并在必要时发出警告。

#Region "Label Pages Requirement Calculation System"
    'This is what we call when we want to know how
    'many pages of labels it will take to print our barcodes
    Public Sub calculatePages()
        'We can't calculate if the starting and ending point is nothing usable...
        If bcStart.Text.Length < 1 Or bcStart.Text.Length < 1 Or _
              bcEnd.Text.IsNullOrEmpty(bcEnd.Text) = True Or _
              bcStart.Text.IsNullOrEmpty(bcStart.Text) = True Then
            Exit Sub
        End If

        'Determine the page allocation limit based on BOX of DOC assignment
        Dim pageAllocation As Integer = 40
        If boxNumber.Enabled = False Then
            pageAllocation = 80
        End If

        'Set the total pages initial amount to how many based on the allocation limit
        Dim tpages As Double = Math.Round((CDbl(bcEnd.Text) - _
                 CDbl(bcStart.Text) + 1) / pageAllocation, 2)
        pageUsageLabel.Text = tpages & " label pages"

        'If we are over normal pages then we need to make this a non-effecient print
        '   Yes, there are probably many other and possibly 
        'better ways to check for a remainder, but this is how I wanted to do it
        If CStr(tpages).Contains(".") Then
            'We're over our limit, but how much?
            Dim ovr As Double = CDbl(CStr(tpages).Split(".")(1))

            'Just check to make sure localization didn't 
            'add the decimal even for a non-remaining number
            If ovr > 0 Then
                'Set our non-effecient warning
                NotEffecientLabel.Visible = True
                YesEffecientLabel.Visible = False

                'Give the user more information on fixining the issue, 
                'so determine a low and high page that is effecient
                Dim useL As Integer = 0
                For useL = CDbl(bcEnd.Text) To CDbl(bcEnd.Text) + pageAllocation
                    If CStr(Math.Round((CDbl(useL) - CDbl(bcStart.Text) + 1) / _
                            pageAllocation, 2)).Split(".").Length = 1 Then
                        Exit For
                    End If
                Next

                Dim useH As Integer = 0
                For useH = CDbl(bcEnd.Text) - (pageAllocation - 1) To _
                           CDbl(bcEnd.Text) + pageAllocation
                    If CStr(Math.Round((CDbl(useH) - CDbl(bcStart.Text) + 1) / _
                              pageAllocation, 2)).Split(".").Length = 1 Then
                        Exit For
                    End If
                Next

                'Write out what they can use you have an even number of pages
                NotEffecientLabel.Text = "Not Effecient (Use " & _
                     useH & " or " & useL & " instead)"
            Else
                'We are effecient!  Great job "user"!
                NotEffecientLabel.Visible = False
                YesEffecientLabel.Visible = True
            End If
        Else
            'Yes! Yes! Yes! -- you get it.
            NotEffecientLabel.Visible = False
            YesEffecientLabel.Visible = True
        End If
    End Sub

    'Calculate the page requirements when they change counts
    Private Sub bcStart_TextChanged(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles bcStart.TextChanged
        calculatePages()
    End Sub
    Private Sub bcEnd_TextChanged(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles bcEnd.TextChanged
        calculatePages()
    End Sub
#End Region

当主窗体加载时,我们将使用编码值和其他内容加载哈希表

    'Do the pre-load events for when this form is up
    Private Sub mainBarcodeWorkspace_Load(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles MyBase.Load
        'Generate the hashtable of encoding values
        ITS_BarcodeC39()

        'Do initial calculations of pages required to print
        calculatePages()

        'Focus on the box number, it's primarly the most important in most cases
        boxNumber.Focus()

        'Set our global position in memory in our module
        mainFrm = Me

        'Show the box scanning form
        boxScanFrm.ShowDialog(Me)
    End Sub
End Class

关注点

这是一个非常有趣且引人入胜的课题。通过这个项目,我对 GDI+ 了解更多,并且对 .NET 框架有了整体了解。与每个项目一样,都会出现问题,但所有问题都可以通过清晰的头脑和思考时间来解决!

历史

  • **初始发布** - 2009 年 3 月 19 日,美国中部时间凌晨 12:40。
  • **版本 2.0 发布** - 2009 年 3 月 20 日,美国中部时间晚上 10:49。
© . All rights reserved.