标题:抛砖引玉-如何在程序中绘制条码
只看楼主
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
结帖率:99.55%
 问题点数:0 回复次数:12 
抛砖引玉-如何在程序中绘制条码
    条码是常用的数据表示方式之一,生成条码的方式有很多,例如条码字符、条码控件、纯代码方式等等,这些方式各有优点。这里介绍一个纯代码方式,可以简便地应用到你的程序中去。这个方式是借鉴了FoxBarCode的算法,先将要生成条码的内容转换成特定的字符串,然后根据这个字符串去绘制条码图片,就可以在程序中应用这个图片来显示条码,也可以在报表中打印这个条码图片。需要说明的是,这个程序的功能比较单一,生成的条码图片大小、条码的宽窄比例等都需要在程序中事先确定,当然你也可以根据需要逐步扩展功能。程序是从我的一个商品化软件中截取出来的,供各位参考,也欢迎拍砖。
搜索更多相关主题的帖子: 字符串 图片 如何 条码 
2017-03-11 09:33
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
第一步:条码计算部分
这个程序是39码的算法,如果你需要使用其他类型的条码,可参考FoxBarCode程序中的相关部分内容。我这里的校验码功能未使用。

**********************************************************
* 39码 Generate Code_39                                  *
* 39码可以表示0-9、A-Z、+-.$/%等字符,并以“*”开始和结束*
**********************************************************
* 进入参数:                                             *
*cbValue  C 条码值                                       *
*lbCheck  L 是否含校验码                                 *
**********************************************************
* 返回参数:                                             *
* 条码内部码(仅为一位字符0则表示条码值不符合要求)      *
**********************************************************

PARAMETERS cbValue,lbCheck
LOCAL cbCode,nbLen,nbi,nbj,cbtext

cbValue=UPPER(cbValue)            &&转换成大写字母

cbtext="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"
IF !CHRTRAN(cbValue,CHRTRAN(cbValue,cbtext,""),"")==cbValue
    RETURN "E"                    &&查找条码值中有无除数字外的其他字符,如有则返回出错信息
ENDIF

IF lbCheck                        &&调用计算校验位过程
*    cbValue=bccheck(cbValue)
ENDIF

nbLen=LEN(cbValue)                &&计算条码值的位数(长度)

LOCAL ARRAY acode[43]
acode[1]="101SB0B010"             && 0              
acode[2]="B01S1010B0"             && 1
acode[3]="10BS1010B0"             && 2
acode[4]="B0BS101010"             && 3
acode[5]="101SB010B0"             && 4
acode[6]="B01SB01010"             && 5
acode[7]="10BSB01010"             && 6
acode[8]="101S10B0B0"             && 7
acode[9]="B01S10B010"             && 8
acode[10]="10BS10B010"            && 9
acode[11]="B0101S10B0"            && A
acode[12]="10B01S10B0"            && B
acode[13]="B0B01S1010"            && C
acode[14]="1010BS10B0"            && D
acode[15]="B010BS1010"            && E
acode[16]="10B0BS1010"            && F
acode[17]="10101SB0B0"            && G
acode[18]="B0101SB010"            && H
acode[19]="10B01SB010"            && I
acode[20]="1010BSB010"            && J
acode[21]="B010101SB0"            && K
acode[22]="10B0101SB0"            && L
acode[23]="B0B0101S10"            && M
acode[24]="1010B01SB0"            && N
acode[25]="B010B01S10"            && O
acode[26]="10B0B01S10"            && P
acode[27]="101010BSB0"            && Q
acode[28]="B01010BS10"            && R
acode[29]="10B010BS10"            && S
acode[30]="1010B0BS10"            && T
acode[31]="BS101010B0"            && U
acode[32]="1SB01010B0"            && V
acode[33]="BSB0101010"            && W
acode[34]="1S10B010B0"            && X
acode[35]="BS10B01010"            && Y
acode[36]="1SB0B01010"            && Z
acode[37]="1S1010B0B0"            && -
acode[38]="BS1010B010"            && .
acode[39]="1SB010B010"            && SPACE
acode[40]="1S1S1S1010"            && $
acode[41]="1S1S101S10"            && /
acode[42]="1S101S1S10"            && +
acode[43]="101S1S1S10"            && %

cbCode="1S10B0B010"               && 开始符号*

FOR nbi = 1 TO nbLen              &&逐步处理条码值
    cbCode=cbCode+acode(AT(SUBSTR(cbValue,nbi,1),cbtext))
ENDFOR
*WAIT cbCode+"1S10B0B01" WINDOW
RETURN cbCode+"1S10B0B01"         &&加*号代码后返回(末尾的0忽略)

活到老,学到老! http://www. E-mail:hu-jj@
2017-03-11 09:36
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
第二步:绘制条码图片

************************************************
* 绘制条码图片(BMP)                          *
************************************************
* 进入参数:                                   *
* 条码代码(由10BS四个字符的代码组成           *
* 可视字符                                     *
* 图片文件名                                   *
************************************************
* 返回参数(无)                               *
************************************************

PARAMETERS cgcode,cgtext,cgfile

cgcode=STRTRAN(cgcode,"B",REPLICATE("1",3))        && 将代码串中的“B”用3个“1”替换
cgcode=STRTRAN(cgcode,"S",REPLICATE("0",3))        && 将代码串中的“S”用3个“0”替换

nglen=LEN(cgcode)                                  && 计算代码位数

ogBitmap=NEWOBJECT("gpBitmap", "_GDIplus.vcx")     && 建立绘图板对象
WITH ogBitmap
    .Create(nglen+4,40)                            && 设定绘图板宽度和高度
    .SetResolution(100,100)                        && 設定分辨率(x,y 的 DPI 値)
ENDWITH

ogColor = NEWOBJECT("gpColor", "_GDIplus.vcx")     && 建立颜色对象
ogPen = NEWOBJECT("gpPen", "_GDIplus.vcx")         && 建立画笔对象
ogFont = NEWOBJECT("gpFont", "_GDIplus.vcx")       && 建立字体对象
ogStringFormat = NEWOBJECT("gpStringFormat", "_GDIplus.vcx")
ogTextBrush = NEWOBJECT("gpSolidBrush", "_GDIplus.vcx")
ogPoint = NEWOBJECT("gpPoint", "_GDIplus.vcx")
ogGraphics = NEWOBJECT("gpGraphics", "_GDIplus.vcx")&& 建立图形对象
WITH ogGraphics
    .CreateFromImage(ogBitmap)                     && 指定图形对象的设备,此处指向已建立的ogBitmap绘图板对象
    ogColor.Set(255,255,255)                       && 设定颜色(设定为白色)
    .Clear(ogColor)                                && 用役定的颜色填充整个图形,可用于背景颜色
   
    ** 绘制条码
    ogColor.Set(0,0,0)                             && 改变颜色(设定为黑色)
    ogPen.Create(ogColor,1)                        && 將指定的赋予画笔,并指定画笔宽度
    FOR ngi=1 TO nglen                             && 开始循环绘制条码
        IF SUBSTR(cgcode,ngi,1)="1"                && 逐个取出字符代码
            ngt=ngi*1+1                            && 计算当前的X座标
            .DrawLine(ogPen,ngt,1,ngt,24)          && 用设定的画笔绘制条码
        ENDIF
    ENDFOR
   
    ** 打印可视字符
    ogFont.Create("Arial", 9, 0, 3)                && 设置文本字体
    ogTextBrush.Create(ogColor)                    && 设定文本颜色
    ngstat=(nglen-LEN(cgtext)*8)/2+2
    ogPoint.Create(ngstat, 26)                     && 设定文本左上角位置
    .DrawStringA(cgText, ogFont, ogPoint, ogStringFormat, ogTextBrush)
ENDWITH
ogBitmap.SaveToFile(cgfile,"image/bmp")            && 将绘图板保存为指定的文件
RELEASE ALL LIKE og*                               && 删除所有绘图对象
RETURN

活到老,学到老! http://www. E-mail:hu-jj@
2017-03-11 09:38
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
第三步:应用条码

这一步就更简单了,在表单或报表中添加指定的图片文件,生成条码图片后再对表单的图片控件刷新就行。在报表打印前先生成条码图片,就可以顺利地打印出条码。

活到老,学到老! http://www. E-mail:hu-jj@
2017-03-11 09:41
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
以下是引用hu9jj在2017-3-11 09:41:08的发言:

第三步:应用条码
 
这一步就更简单了,在表单或报表中添加指定的图片文件,生成条码图片后再对表单的图片控件刷新就行。在报表打印前先生成条码图片,就可以顺利地打印出条码。
比喻:数据表有
物料名称,条码,  数量
薯条    ,100001,10
花生    ,200001,10
等等,100条数据,你是不是先用循环的方法,生成100个对应的条码图片?然后,报表中用图形控件?

 
2017-03-11 10:37
hyswcyh
Rank: 8Rank: 8
等 级:贵宾
威 望:20
帖 子:391
专家分:896
注 册:2004-11-23
得分:0 
先生成条码图片和后生成条码图片都一样,同样都可以打印出来,只是这个条码图片是否需要保存下来决定的。
当然,打印时的代码就小有差别了。
2017-03-11 12:19
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
以下是引用mywisdom88在2017-3-11 10:37:59的发言:

比喻:数据表有
物料名称,条码,  数量
薯条    ,100001,10
花生    ,200001,10
等等,100条数据,你是不是先用循环的方法,生成100个对应的条码图片?然后,报表中用图形控件?

 

因为在报表的打印中途不方便动态生成图片,所以连续打印时应事先生成图片才行。

[此贴子已经被作者于2017-3-11 19:43编辑过]


活到老,学到老! http://www. E-mail:hu-jj@
2017-03-11 19:38
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
这可以用一个字符字段来保存图片文件名,事先就将条码图片保存在专门的文件夹中。

活到老,学到老! http://www. E-mail:hu-jj@
2017-03-11 19:42
asdf_123000
Rank: 4
等 级:业余侠客
威 望:1
帖 子:262
专家分:203
注 册:2012-12-20
得分:0 
学习
2017-03-12 09:32
qingfameng
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:35
帖 子:964
专家分:3019
注 册:2010-2-6
得分:0 
支持hu9jj版主的分享!!
2017-03-12 10:49



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-474954-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014176 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved