一、 条码[条形码]数据采集
如前面章节所述,通用的条码[条形码]采集设备主要是CCD扫描器和镭射扫描器,此类设备与电脑的接口主要有两种:PS/2与RS232:
1、.标准PS/2接口,这是市场的主流,采用这种接口,用户可以扫描器作为键盘来使用,并可与电脑上原有键盘一起使用,因此,在程序设计上不需要任何特殊的处理,凡是可以接收标准键盘输入的地方(如各种程序开发平台中的文本框控件,Windowsr中的记事本等),均可以无缝的接收扫描器采集的数据;
2、标准RS232接口,在程序设计中必须加入与COM口通信的模块,实时接收扫描器传送到端口的数据,可采用的方式:COM通信控件或通过WIN API函数访问COM。RS232编程本书不作详述,请参考相关书籍(如:)
二、 条码[条形码]打印
欲将软件系统中的数据资料以条码[条形码]为载体打印出来,在硬体设备方面一般采用专业的标签条码[条形码]打印机,其程序设计,不外乎两种:
1、 基于WINDOWS驱动程序的条码[条形码]打印机程序设计
WINDOWS操作系统的打印机制如示: 应用程序--系统GDI模块---打印机驱动程序--打印机
? a.首先,应用程序应先获得指向打印机设备描述表的一个句柄,使得打印机驱动程序被加载到内存,并进行打印机的初始化;
? b.其次,应用程序程序调用GDI函数进行绘图(画出条码[条形码]),GDI模块一般将这些绘图调用存储在元文件中;
? c.打印机驱动程序将元文件中的各种绘图指令翻译成打印机能够识别的指令集, 打印机进行打印
在这个打印机的流程当中,不难看出,在应用程序当中我们要作的就是绘图,其余的工作就交给操作系统以及打印机驱动程序去做(这就是WINDOWS所谓的设备无关性!)。对于我们要进行的条码[条形码]打印来说,关键就集中于如何绘制条码[条形码],下面之例子即为CODE39之绘制程序,读者了解后不难举一反三:
//此程序是基于C++BUILDER5.0之语法;已在此环境下编译通过
//此程序仅实现绘制CODE39的最原始/最基本的功能
//读者在编写程序前应先了解条所要绘制之条码[条形码]的详规格;
//CODE39之规格详见前面之章节;
{
............
TPrinter *printer;
printer=Printer(); //得到一个操纵打印机类的实例,
String print_code;
print_code=return_logicCODE(*); //code39的起始符及终止符均为"*";
for (int i=1;i<=MaskEdit1->Text.Length();i++)
{
char *code;
String temp;
temp=MaskEdit1->Text.SubString(i,1);
code=temp.c_str();
print_code+="0"; //CODE39的每个数据用一条空来分隔
temp=return_logicCODE(*code);//得到每一个数据的在CODE39中逻
//辑码
if (temp=="0") return;
print_code+=temp;
}
print_code+="0";
print_code+=return_logicCODE(*);
printer->BeginDoc();
printer->Canvas->Pen->Width=2; //CODE39每一个逻辑位元的宽度,此处设为2个//像素
printer->Canvas->MoveTo(100,60);
int x;
x=100;
for (int k=0;k {
if (print_code.SubString(k+1,1)=="0" )
{
printer->Canvas->Pen->Color=clWhite; //如果逻辑位元为"0"画条白线
}
else
{
printer->Canvas->Pen->Color=clBlack; //如果逻辑位元为"1"画条黑线
}
printer->Canvas->LineTo(x,120);
x=x+printer->Canvas->Pen->Width;
printer->Canvas->MoveTo(x,60);
}
printer->EndDoc();
}
String return_logicCODE(char code) //将每个数据转换为CODE39的逻辑码,若不
//再CODE39字符集内的数据则返回"0"
{
switch(code)
{
case 0: return "101001101101"; //code--0
case 1: return "110100101011"; //code--1
case 2: return "101100101011"; //code--2
case 3: return "110110010101"; //code--3
case 4: return "101001101011"; //code--4
case 5: return "110100110101"; //code--5
case 6: return "101100110101"; //code--6
case 7: return "101001011011"; //code--7
case 8: return "110100101101"; //code--8
case 9: return "101100101101"; //code--9
case +: return "100101001001"; //code--+
case -: return "100101011011"; //code---
case *: return "100101101101"; //code--*
case /: return "100100101001"; //code--/
case %: return "101001001001"; //code--%
case $: return "100100100101"; //code--$
case .: return "110010101101"; //code--.
case : return "100110101101"; //code--空白
case A: return "110101001011"; //code--A
case B: return "101101001011"; //code--B
case C: return "110110100101"; //code--C
case D: return "101011001011"; //code--D
case E: return "110101100101"; //code--E
case F: return "101101100101"; //code--F
case G: return "101010011011"; //code--G
case H: return "110101001101"; //code--H
case I: return "101101001101"; //code--I
case J: return "101011001101"; //code--J
case K: return "110101010011"; //code--K
case L: return "101101010011"; //code--L
case M: return "110110101001"; //code--M
case N: return "101011010011"; //code--N
case O: return "110101101001"; //code--O
case P: return "101101101001"; //code--P
case Q: return "101010110011"; //code--Q
case R: return "110101011001"; //code--R
case S: return "101101011001"; //code--S
case T: return "101011011001"; //code--T
case U: return "110010101011"; //code--U
case V: return "100110101011"; //code--V
case W: return "110011010101"; //code--W
case X: return "100101101011"; //code--X
case Y: return "110010110101"; //code--Y
case Z: return "100110110101"; //code--Z
default: return "0";
}
..........
}
2、 用条码[条形码]打印机的指令集生成与打印条码[条形码]标签
通常电脑周边设备都内建有指令集,例如:打印机、数据机等,不需驱动程式就可以直接控制,例如:HP雷射印表机使用PCL语言,EPSON点阵印表机使用ESC/P2语言,这里所指的语言就是指令集;与此相类似,条码[条形码]打印机也有它们的指令集,即所谓的打印机语言,它的特性是:将条码[条形码]生成算法内建在机器的BIOS之中,面向用户的介面是一个条码[条形码]打印指令。普通打印机的用户,因为没有什么特殊的要求,一般都是在驱动程序介面上使用,基本上用户不需要了解机器指令。对于条码[条形码]打印机用户,基于、高效的条码[条形码]打印的要求,就需要了解其指令,并通过指令集来直接控制打印机,以充分利用条码[条形码]打印机的特性。下面,我们就以当前市场上的条码[条形码]打印机语言(ARGOX公司的PPLA)为例简要的介绍打印机的指令集的使用:
PPLA语言是ARGOX公司自主开发的,使用于该公司生产的各款商业型条码[条形码]打印机之中。
2. 0 PPLA指令集简介
? 系统设置指令
?KI7n Set Transfer Type n=0 for Direct Thermal
?KI8 & KI9 Set Baud rate for RS232
?KI? 交互指令
?# Reset the printer
?A & F Sent the printer status (printer to host)
?B Toggle PAUSE condition
? 系统标准指令
?cxxxx Set continuous paper type
?F Feed a label
?fxxx Back feed from stop positon
?Oxxx Set start print position
?Q clear memory
?Sn Set label feed rate
? 标签格式指令
?L START
?E END
?:xxxx Set cut every xxxx labels(same as
the cxx)
?^xx Set count amount
?Hxx Heat value
?Qxxxx Set copy count
2.1 指令结构
交互指令
系统指令
字型下载
图档下载 (以上几种指令可能混合交错出现或不出现)
L ------- start
标签格式指令
...
标签格式指令
E ------- end
例子—在打印机上打印一个CODE39码:
条码[条形码]打印指令其含义如下:
条码[条形码]高度
orientation, 1 for portrait
1A5200001000200CODE 3 OF 9
y coord. x coord. data
narrow bar width
wide bar width
bar code type
2.2在应用程序中将上述之指令送至打印机,如下:
#include
#include
void main()
{
FILE *fprn;
Fprn=fopen("LPT1.prn","w+b");
if (fprn=NULL) { printf("Cannot open LPT1);return;}
fwrite("\x02L\r\n",sizeof(char),4,fprn);
fwrite("A2\r\n",sizeof(char),4,fprn);
fwrite("D11\r\n",sizeof(char),5,fprn);
fwrite("1A5200001000200CODE 3 OF 9\r\n",sizeof(char),28,fprn);
fwrite("Q0001\r\n",sizeof(char),7,fprn);
fwrite("E\r\n",sizeof(char),3,fprn);
fcloseall();
}
3、 两种方式之比较
基于WINDOWS驱动之方式,其优点是可移植性强,缺点是需编写绘制条码[条形码]的算法,且所有内容均转换为图档处理,与打印机的通讯数据量大,效率较低;基于标签条码[条形码]打印机之指令进行控制,利用了条码[条形码]机内置的条码[条形码]图档,优点是高效、准确、简洁,缺点是各家的打印机指令集不同,移植性较差。