以下是一个输出条形码的程序,我想请这方面的高手指导下为什么输出的条形码,打印机识别不了?(300分)

  • 主题发起人 枕夕阳
  • 开始时间

枕夕阳

Unregistered / Unconfirmed
GUEST, unregistred user!
unit ScanCodePrintU;
interface
uses
Classes, SysUtils, Windows, Graphics, Printers;
Type
TScanCodePrint = Class
Private
//Code128Set : array[0..106] of string;
START_A : Integer;
START_B : Integer;
START_C : Integer;
STOP : Integer;
SHIFT : Integer;
CODE_A : Integer;
CODE_B : Integer;
CODE_C : Integer;
FUNC_1 : Integer;
FUNC_2 : Integer;
FUNC_3 : Integer;
Code128Set : TStringList;
Code : String;
Rato : Double; //每毫米打印的像素数
function PrinterSetup(): string;
Procedure ClearCanvas();
Procedure DrawScanCode( Canv: TCanvas;ScanCode:string );
Public
canvasDest : TCanvas;
CodeHigh : DOUBLE; //= 20.0f;
CodeWidth : DOUBLE; // 0.35f;
Constructor Create;
// int Code128AEncode(LPSTR text, LPSTR partial);
// int Code128AVerify(LPCSTR text);
// int Code128CEncode(LPSTR text, LPSTR partial);
// int Code128CVerify(LPCSTR text);
Function Code128BEncode( text : String ) : String;
Function Code128BVerify( text : String ) : Integer;
Procedure PrintScanCode( text : String );
procedure DispScanCode(text: String; Canv: TCanvas);
// CCode128();
// virtual ~CCode128();
end;
implementation
uses Types;
{ ScanCodePrint }
function TScanCodePrint.PrinterSetup(): string;
var
RetStr: string;
ADevice, ADriver, APort: array[0..255] of Char;
DeviceHandle: THandle;
DevMode: PDeviceMode;
begin
retstr := 'PrinterSetup: ';
try
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
except
RetStr := '您的计算机没有安装打印机,请您先安装打印机';
Result := '';
Exit;
end;
if( DeviceHandle = 0 ) then
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
end;
if(DeviceHandle <> 0 ) then
begin
DevMode := GlobalLock(DeviceHandle);
//======
with DevMode^ do
begin

//=====打印方向=====
dmFields:= DM_ORIENTATION;
dmOrientation := DMORIENT_LANDSCAPE;
//dmOrientation := DMORIENT_PORTRAIT;
//=====打印方向——END=====

//=====打印纸张大小=====
dmFields:= dmFields or DM_PAPERSIZE;
DevMode^.dmPaperSize := DMPAPER_A4;
//=====打印纸张大小——END=====
end;
//======
Printer.SetPrinter(ADevice,ADriver,APort,DeviceHandle);
//ShowMessage( 'PHeight:' + inttostr(GetPPageHeight) + ' ' + 'PWeight:' + inttostr(GetPPageWidth) );
end;
//RetStr := RetStr + PagePaperType[CurrentPageNum] + ':' + inttostr(allRepData[CurrentPageNum].Page_Orientation);
Result := RetStr + '<Height' + IntToStr( Printer.PageHeight ) + '><Width' + IntToStr( Printer.PageWidth ) + '>';
end;
function TScanCodePrint.Code128BEncode(text: String): String;
Var
Partial : String;
i : Integer;
Code,
CheckSum : Integer;
TextLen : Integer;
begin

//如果字符串为空,则返回
if text = '' then
begin
Result := '';
Exit;
end;

Partial := '';

checksum := 0;

//首字符为START_B(HEAD)
Partial := Partial + (code128set.Strings[START_B]);
//首字符也要加到校验和中去
checksum := CheckSum + START_B;

TextLen := length(text);
for i := 1 to TextLen do
begin

if (Ord(text) < 32) Or (Ord(text) > 127) then
begin
//如为非法字符,则返回
Result := '';
Exit;
end;

Code := Ord(text) - 32;
Partial := Partial + (code128set.Strings
代码:
);
    //校验和为:first * 1 + second * 2 + third * 3...
    CheckSum := CheckSum + code * (i+1);
  end;

  //最终校验和为除以103所得的余数
  CheckSum := CheckSum mod 103;
  //将校验和加入partial
  Partial := Partial + (code128set.Strings[checksum]);
  //加入STOP结尾字符
  Partial := Partial + (code128set.Strings[STOP]);

  Result := Partial;

end;

function TScanCodePrint.Code128BVerify(text: String): Integer;
Var
  i : Integer;
  TextLen : Integer;
begin
   TextLen := length( text );
   for i := 1 to TextLen do
   begin
     if (Ord(text[i]) < 32) Or (Ord(text[i]) > 127) then
     begin
       Result := -1;
       Exit;
     end;
   end;
   Result := 0;
end;

constructor TScanCodePrint.Create;
begin
  Code128Set := TStringList.Create;

  Code128Set.Add('212222');Code128Set.Add('222122');Code128Set.Add('222221');Code128Set.Add('121223');Code128Set.Add('121322');  //*  0 -  4 */
  Code128Set.Add('131222');Code128Set.Add('122213');Code128Set.Add('122312');Code128Set.Add('132212');Code128Set.Add('221213');
  Code128Set.Add('221312');Code128Set.Add('231212');Code128Set.Add('112232');Code128Set.Add('122132');Code128Set.Add('122231');  //* 10 - 14 */
  Code128Set.Add('113222');Code128Set.Add('123122');Code128Set.Add('123221');Code128Set.Add('223211');Code128Set.Add('221132');
  Code128Set.Add('221231');Code128Set.Add('213212');Code128Set.Add('223112');Code128Set.Add('312131');Code128Set.Add('311222');  //* 20 - 24 */
  Code128Set.Add('321122');Code128Set.Add('321221');Code128Set.Add('312212');Code128Set.Add('322112');Code128Set.Add('322211');
  Code128Set.Add('212123');Code128Set.Add('212321');Code128Set.Add('232121');Code128Set.Add('111323');Code128Set.Add('131123');  //* 30 - 34 */
  Code128Set.Add('131321');Code128Set.Add('112313');Code128Set.Add('132113');Code128Set.Add('132311');Code128Set.Add('211313');
  Code128Set.Add('231113');Code128Set.Add('231311');Code128Set.Add('112133');Code128Set.Add('112331');Code128Set.Add('132131');  //* 40 - 44 */
  Code128Set.Add('113123');Code128Set.Add('113321');Code128Set.Add('133121');Code128Set.Add('313121');Code128Set.Add('211331');
  Code128Set.Add('231131');Code128Set.Add('213113');Code128Set.Add('213311');Code128Set.Add('213131');Code128Set.Add('311123');  //* 50 - 54 */
  Code128Set.Add('311321');Code128Set.Add('331121');Code128Set.Add('312113');Code128Set.Add('312311');Code128Set.Add('332111');
  Code128Set.Add('314111');Code128Set.Add('221411');Code128Set.Add('431111');Code128Set.Add('111224');Code128Set.Add('111422');  //* 60 - 64 */
  Code128Set.Add('121124');Code128Set.Add('121421');Code128Set.Add('141122');Code128Set.Add('141221');Code128Set.Add('112214');
  Code128Set.Add('112412');Code128Set.Add('122114');Code128Set.Add('122411');Code128Set.Add('142112');Code128Set.Add('142211');  //* 70 - 74 */
  Code128Set.Add('241211');Code128Set.Add('221114');Code128Set.Add('413111');Code128Set.Add('241112');Code128Set.Add('134111');
  Code128Set.Add('111242');Code128Set.Add('121142');Code128Set.Add('121241');Code128Set.Add('114212');Code128Set.Add('124112');  //* 80 - 84 */
  Code128Set.Add('124211');Code128Set.Add('411212');Code128Set.Add('421112');Code128Set.Add('421211');Code128Set.Add('212141');
  Code128Set.Add('214121');Code128Set.Add('412121');Code128Set.Add('111143');Code128Set.Add('111341');Code128Set.Add('131141');  //* 90 - 94 */
  Code128Set.Add('114113');Code128Set.Add('114311');Code128Set.Add('411113');Code128Set.Add('411311');Code128Set.Add('113141');
  Code128Set.Add('114131');Code128Set.Add('311141');Code128Set.Add('411131');Code128Set.Add('211412');Code128Set.Add('211214');  //* 100 - 104 */
  Code128Set.Add('211232');Code128Set.Add('2331112');

  START_A := 103;
  START_B := 104;
  START_C := 105;
  STOP    := 106;
  SHIFT   := 98;  //* only A and B */
  CODE_A  := 101; //* only B and C */
  CODE_B  := 100; //* only A and C */
  CODE_C  := 99;  //* only A and B */
  FUNC_1  := 102; //* all of them */
  FUNC_2  := 97;  //* only A and B */
  FUNC_3  := 96;  //* only A and B */

  CodeHigh := 20;
  CodeWidth := 0.35;

end;

Procedure TScanCodePrint.ClearCanvas();
var
  x,y: integer;
begin
  //x := GetPageWidth+1;
  //y := GetPageHeight+1;
  x := canvasDest.ClipRect.Right - canvasDest.ClipRect.Left;
  y := canvasDest.ClipRect.Bottom - canvasDest.ClipRect.Top;
  canvasDest.Pen.Mode:=pmCopy;
  canvasDest.Pen.Color:=clWhite;
  canvasDest.Brush.Color:=clWhite;
  canvasDest.Rectangle(0,0,x,y);
end;

procedure TScanCodePrint.DispScanCode(text: String; Canv: TCanvas);
var
  PrintQuality : Integer;
  Partial : String;
begin

  PrintQuality := 72;

  if Code128BVerify( text ) = 0 then
  begin
    Partial := Code128BEncode(text);

    //每毫米打印的像素数
    Rato := printQuality/25.4;

    canvasDest := Canv;
    ClearCanvas;
    DrawScanCode( canvasDest, Partial );

  end;

end;

procedure TScanCodePrint.PrintScanCode(text: String);
var
  PrintQuality : Integer;
  Partial : String;
begin

  PrinterSetup;
  PrintQuality := GetDeviceCaps(Printer.Handle,LOGPIXELSX);

  if Code128BVerify( text ) = 0 then
  begin
    Partial := Code128BEncode(text);
    Printer.BeginDoc;   { <-- start printer job }
    //每毫米打印的像素数
    Rato := printQuality/25.4;
    Printer.PageHeight; { <-- get page height }
    Printer.PageWidth;  { <-- get page width }
    canvasDest := printer.Canvas;
    DrawScanCode( canvasDest, Partial );
    Printer.EndDoc; { <-- end job and print !! }
  end;


	// TODO: Add your control notification handler code here
//	CDC dc;
	//text=m_CodeText.GetBuffer (50);

{	int horze=dc.GetDeviceCaps (HORZRES);
	int vertical=dc.GetDeviceCaps (VERTRES);



{	dc.StartPage();

	print(partial,&dc);

	dc.EndPage();
	dc.EndDoc();
	m_CodeText.ReleaseBuffer ();
}


end;

procedure TScanCodePrint.DrawScanCode(Canv: TCanvas; ScanCode: string);
var
  High,
  ScanCodeLen,
  j,
  i : Integer;
  Str : String;
  pen,
  pOldPen : TPen;

  CPoint : TPoint;
begin
//int CBarcodeDlg::print(LPSTR text,CDC* pDC)
        Str := ScanCode;
        pen := TPen.Create;

	//设定条码左上脚初始点
	CPoint.X := 50;
        CPoint.Y := 50;

	//画笔为黑色
	pen.Style := psSolid;//(PS_SOLID,int(CodeWidth*rato),RGB(0,0,0));
        pen.Width := round(CodeWidth*rato);
        pen.Color := RGB(0,0,0);
	//将画笔选入打印设备环境
	pOldPen := Canv.Pen;
        Canv.Pen := pen;

	High := round(CodeHigh*rato);

        ScanCodeLen := length( Str );
        j := 1;
	while j <= ScanCodeLen do
        begin
          for i := 0 to Ord(str[j]) - Ord('0') do
          begin
            Canv.MoveTo(CPoint.X, CPoint.Y);
            Canv.LineTo(CPoint.X, CPoint.Y+High);
	    CPoint.X := CPoint.X + round(CodeWidth*rato);
          end;
          j := j + 1;
          CPoint.X := CPoint.X + round(CodeWidth * rato) * (Ord(str[j]) - Ord('0'));
          j := j + 1;
	end;
        Canv.Pen := pOldPen;
	FreeAndNil( pen );
end;
end.


unit UMain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScanCodePrintU, StdCtrls;
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button3: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation

{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
  SC : TScanCodePrint;
begin
  SC := TScanCodePrint.Create;
  if SC.Code128BVerify(Edit1.Text) = 0 then
  begin
    SC.PrintScanCode(Edit1.Text);
  end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage( IntToStr( trunc(10.5) ));
  ShowMessage( IntToStr( trunc(10.6) ));
end;
procedure TForm1.Button3Click(Sender: TObject);
var
  SC : TScanCodePrint;
begin
  SC := TScanCodePrint.Create;
  if SC.Code128BVerify(Edit1.Text) = 0 then
  begin
    SC.DispScanCode(Edit1.Text, Self.Canvas);
  end;
end;
end.
 
对了,我希望高手能亲自试验成功了以后在告诉我。我会直接给分的
 
我用了你的程序,打印到虚拟打印机和激光打印机都没问题啊。

楼主说的错误是什么?
 
打印很正常啊。代码运行也是对的。至于扫描枪是不是可以识别,就无法确认了。没有这样的测试环境。
 
有条形码控件
 
没仔细看楼主的代码,不过真的能实现的话,我绝对佩服,我的那个在 canves上画 条码的程序将近2000行,楼主不到400行还包括打印。当然我的支持几乎所有2维条码。
 
打印机又不是扫描枪,他怎么会识别???
 
不好意思,我说错了,是扫描枪识别不了。
不过我敢肯定应该能做输出扫描枪可以识别的条形码的。希望有环境的朋友们帮我研究研究是哪儿出问题了。谢谢大家。
 
是有条形码控件,不过我们公司现在自己开发了一套报表控件,适用于c/s和b/s结构。现在想把条形码这块也加上去,所以才和大家共同研究研究的。
 
我这没有扫描枪了,测试不了
你看看fr的条码,我一直用他,效果可以,支持的格式也很多
也要看看你的扫描枪支持的格式
 
[:(][:(][:(][:(][:(]
 
扫描枪识别,有几个条件
首先,条码首部和尾部要有足够的空白.
ean13商品条码,实际有效的只有12个,最后一个必须是校验码,否则识别不出来.
其他的,39码好像前后还要加*符号
128码没什么特别要求.
 
那ufo兄:
我的这段代码有什么问题吗?
 
你的代码没看,不知你要打什么类型的条码?
用于什么场合?
 
开发过程太长,而且测试过程也很长。
再说市场上已经普及了。
 
是呀,用FR吧,支持很多种条码格式的,打印出来的条码,用条码枪很容易读取
 
没有人写过打印条形码的程序吗?
 
顶部