【VB开源代码栏目提醒】:网学会员在VB开源代码频道为大家收集整理了“VB应用程序中打印条形码的两种方法 - 计算机教材“提供大家参考,希望对大家有所帮助!
VB应用程序中打印条形码的两种方法 条形码作为一种机器可识别的图形它能快速、准确地标识某种产品或商品在许多数据库应用中起作很重要的作用如超市收银、车站售票等场合。
当某件物品上带有的条形码被条码扫描器正确解读后将会得到该物品的唯一标识字符串通过检索数据库我们就可以很容易知道它的一些其它属性并作相应处理。
虽然在Internet上能找到许多免费和不
免费的条形码打印控件但是这些控件除了使用不方便外还有一个最大的缺点它们的打印输出不能和我们的程序共存在一个打印页面上比如说在一个过程中我们先向系统 Printer 中输出一些内容然后再调用控件的条形码打印方法最后打印的结果为两页如果现在我 们要处理一张车票上面不仅要打印条形码还要有终点站和票价等信息那么控件就变得不可用。
对程序员来说可能还是希望能了解条形码打印的原理本文提出两种打印方法与同行们探讨。
一、直接利用有条形码打印功能的打印机 有许多打印机能够直接打印条形码但在
VB 中我们在时代熟悉的LPRINT语句已经不能再使用了打印操作被Windows的Spool系统完全接管输出是以页为单位所有的打印输出都被Windows转换为图形发送给打印驱动
程序。
而要使打印机打印条形码就必须将对应的ESC序列直接发送给它因此我们就要想办法避开Windows的Spool
系统也就是说再程序中不能使用Printer对象和Printers集合处理打印输出在
VB中要将ESC指令直接发送给打印机至少有三种方法前两种方法是调用Windows API 函数Escape和SpoolFile第三种是最容易的方法打开打印机端口进行二进制存取我们主要考虑这种方法。
即使在Windows时代LPT1:和PRN仍然是可用的下面我们先作一个试验打开一个DOS窗口在提示符下输入COPY CON LPT1:回车然后随便输入一些字符最后按F6键打印机就开始
工作了它将打印出你输入的那些字符下面的
代码演示了直接将指令和字符发送给打印机 Private Sub Command1_Click Dim strOut As String StrOut 这是直接发送到打印机端口的字符串 打开打印机端口其中的LPT1:可能需要根据你的打印机设置而改变 Open LPT1: For Binary Access Write As 1 发送给打印机注意语句的最后一个参数必须是变量 Put 1 strOut 关闭打印机端口 Close 1 End Sub 各种打印机打印条形码的指令可能不同比如将上面的变量 strOut赋值为 strOut Chr28 P Chr5 Chr2 Chr3 Chr3 Chr6 012345 将在 AR2400 打印机上打印出内容为012345的 CODE39 格式的条形码。
具体的打印控制指令请参考打印机手册。
用这种方法的缺点一是过份依赖打印机本身而有条形码打印功能的打印机通常要比普通打印机昂贵这会使构造应用系统不够
经济二是所有的打印输出都必须你自己处理比如打印定位就很浪费时间。
二、利用画图方式输出到普通打印机 条形码的编码规则不外乎是通过线条和线条间间隙的宽窄不同来表示二进制的和只要我们了解了条形码的编码规则完全可以用画图的方式在普通打印机上得到可以接受的效果。
下面我们就使用最普遍的CODE39码进行讨论。
CODE39码的编码规则是 每五条线表示一个字符 粗线表示细线表示 线条间的间隙宽的表示窄的表示 五条线加上它们之间的四条间隙就是九位二进制编码而且这九位中必定有三位是1所以称为39码 条形码的首尾各一个标识开始和结束 在我们的程序中给
常用的字符都进行编码解读时先取线条粗细再取间隙宽窄如 上图中的字符就可以解读为 001101000字符解读为 110000100 下面就是我们给出的子过程 将字符串 strBarCode 对应的条形码输出到缺省打印机 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 _ 参数说明: strBarCode - 要打印的条形码字符串 intXPos intYPos - 打印条形码的左上角坐标缺省为00坐标刻度为:毫米 intHeight - 打印高度缺省为一厘米坐标刻度为:毫米 bolPrintText - 是否打印人工识别字符缺省为true 0-9A-Z-和 的条码编码格式总共 40 个字符 Static strBarTable39 As String 初始化条码编码格式表 strBarTable0 001100100 0 strBarTable1 100010100 1 strBarTable2 010010100 2 strBarTable3 110000100 3 strBarTable4 001010100 4 strBarTable5 101000100 5 strBarTable6 011000100 6 strBarTable7 000110100 7 strBarTable8 100100100 8 strBarTable9 010100100 9 strBarTable10 100010010 A strBarTable11 010010010 B strBarTable12 110000010 C strBarTable13 001010010 D strBarTable14 101000010 E strBarTable15 011000010 F strBarTable16 000110010 G strBarTable17 100100010 H strBarTable18 010100010 I strBarTable19 001100010 J strBarTable20 100010001 K strBarTable21 010010001 L strBarTable22 110000001 M strBarTable23 001010001 N strBarTable24 101000001 O strBarTable25 011000001 P strBarTable26 000110001 Q strBarTable27 100100001 R strBarTable28 010100001 S strBarTable29 001100001 T strBarTable30 100011000 U strBarTable31 010011000 V strBarTable32 110001000 W strBarTable33 001011000 X strBarTable34 101001000 Y strBarTable35 011001000 Z strBarTable36 000111000 - strBarTable37 100101000 strBarTable38 010101000 strBarTable39 001101000 If strBarCode Then Exit Sub 不打印空串 保存打印机 ScaleMode Dim intOldScaleMode As ScaleModeConstants intOldScaleMode Printer.ScaleMode 保存打印机 DrawWidth Dim intOldDrawWidth As Integer intOldDrawWidth Printer.DrawWidth 保存打印机 Font Dim fntOldFont As StdFont Set fntOldFont Printer.Font Printer.ScaleMode vbTwips 设置打印用的坐标刻度为缇twip1 Printer.DrawWidth 1 线宽为 1 Printer.FontName 宋体 打印在条码下方字符的字体和大小 Printer.FontSize 10 Dim strBC As String 要打印的条码字符串 strBC UcasestrBarCode 将以毫米表示的 X 坐标转换为以缇表示 Dim x As Integer x Printer.ScaleXintXPos vbMillimeters vbTwips 将以毫米表示的 Y 坐标转换为以缇表示 Dim y As Integer y Printer.ScaleYintYPos vbMillimeters vbTwips 将以毫米表示的高度转换为以缇表示 Dim intHeight As Integer intHeight Printer.ScaleY intPrintHeight vbMillimeters vbTwips 是否在条形码下方打印人工识别字符 If bolPrintText True Then 条码打印高度要减去下面的字符显示高度 intHeight intHeight - Printer.TextHeightstrBC End If Const intWidthCU As Integer 30 粗线和宽间隙宽度 Const intWidthXI As Integer 10 细线和窄间隙宽度 Dim intIndex As Integer 当前处理的字符串索引 Dim i As Integer j As Integer k As Integer 循环控制变量 添加起始字符 If LeftstrBC 1 Then strBC strBC End If 添加结束字符 If RightstrBC 1 Then strBC strBC End If 循环处理每个要显示的条码字符 For i 1 To LenstrBC 确定当前字符在 strBarTable 中的索引 Select Case MidstrBC i 1 Case intIndex 39 Case intIndex 38 Case intIndex 37 Case - intIndex 36 Case 0 To 9 intIndex CIntMidstrBC i 1 Case A To Z intIndex AscMidstrBC i 1 - AscA 10 Case Else MsgBox 要打印的条形码字符串中包含无效字符当前版本只支持字符0-9A-Z-和 End Select 是否在条形码下方打印人工识别字符 If bolPrintText True Then Printer.CurrentX x Printer.CurrentY y intHeight Printer.Print MidstrBC i 1 End If For j 1 To 5 画细线 If MidstrBarTableintIndex j 1 0 Then For k 0 To intWidthXI - 1 Printer.Line x k y - Step0 intHeight Next k x x intWidthXI 画宽线 Else For k 0 To intWidthCU - 1 Printer.Line x k y - Step0 intHeight Next k x x intWidthCU End If 每个字符条码之间为窄间隙 If j 5 Then x x intWidthXI 3 Exit For End If 窄间隙 If MidstrBarTableintIndex j 5 1 0 Then x x intWidthXI 3 宽间隙 Else x x intWidthCU 2 End If Next j Next i 恢复打印机 ScaleMode Printer.ScaleMode intOldScaleMode 恢复打印机 DrawWidth Printer.DrawWidth intOldDrawWidth 恢复打印机 Font Set Printer.Font fntOldFont End Sub 最理想的情况是将它做成一个控件在控件中提供一个打印方法该方法实现与上面那个过程大致相同只是不能在控件中直接使用
VB的Printer对象否则
VB会将你在控件中的打印输出处理为一个单独的页面而是应该将Printer.hDc传给它通过调用那些需要指定 HDC 的Windows API函数实现与容器的打印输出在一个页面上比如我们可以这样定义这个控件的打印方法 PrintIt 方法将对应的条形码输出到缺省打印机 Public Sub PrintItByVal 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函数 移动画笔的位置 Private Declare Function MoveToEx Lib gdi32 ByVal hdc As Long ByVal x As Long ByVal y As Long lpPoint As POINTAPI As Long 从画笔的当前位置到xy画一条线 Private Declare Function LineTo Lib gdi32 ByVal hdc As Long ByVal x As Long ByVal y As Long As Long 在xy处输出一个字符串 Private Declare Function TextOut Lib gdi32 Alias TextOutA ByVal hdc As Long ByVal x As Long ByVal y As Long ByVal lpString As StringByVal nCount As Long As Long MoveToEx 函数需要的参数 Private Type POINTAPI xp As Long yp As Long End Type Dim papi As POINTAPI 画线操作为原来的Printer.Line函数 MoveToEx PrintDC x k y papi LineTo PrintDC x k y intHeight 1 打印字符为原来的Printer.Print函数 TextOut PrintDC x y intHeight MidstrBC i 1 1 1