条形码打印控制(300分求) ( 积分: 100 )

  • 主题发起人 主题发起人 xiongw
  • 开始时间 开始时间
X

xiongw

Unregistered / Unconfirmed
GUEST, unregistred user!
我要将某一图片打印到条形码上(只印图片),我要求能动态调整图片的大小和打印位置,即当我在程式里设定让图片布满label一定的区域,然后打印一行,看打印的效果,如果发现因为放纸原因或是图片内容的原因造成印在label上的位置偏高或是偏低时,我能动态地调整图片在label上的打印位置,现在不限什么方式实现,但要求不要再通过第三方软件来实现,请大家帮忙,最好能有建设性的源码,解决的话再开贴送200分
(我试过了,用打印机的canvas直接打印,是可以,但是我不能控制到以一行为单位打印,它一印就印一行,然后空跑很多行label,同样用EXCEL模板也是遇到一样的问题,如何让程式采用自定义纸张?)
 
什么乱七八糟的?
表达不清楚,代码也没有,怎么回答?
只能告诉你,textout可以行输出,仔细检查代码.
 
这是我用EXCEL的做法:
procedure TMainForm.Button4Click(Sender: TObject);
Var FExcel :OleVariant;
//excel应用程序
FWorkBook :OleVariant;
//工作表
FWorksheet:OleVariant;
//工作薄
FPicture:OleVariant;
TmpStr:String;
i,labelcount:integer;
begin
labelcount:=4;
//label栏数
FExcel:= CreateoleObject('excel.Application');
FWorkBook:=FExcel.WorkBooks.Add;
//新的工作表
FWorksheet:=FWorkBook.Worksheets[1];
FWorksheet.Select;
//插入图象并设置位置与大小
tmpstr:='c:/aa.bmp';
SetPaperHeight(10);
for i:=0 to labelcount-1do
begin
FPicture:=FWorksheet.Pictures.Insert(tmpstr);
FPicture.Left:=i*23;
//左上角位置
FPicture.Top:=0;
//
FPicture.width:=22;
//设定图片覆盖的面积
FPicture.height:=9;
FPicture:='null';
//FWorksheet.PageSetup.PaperSize := 126;
end;
FExcel.visible:=true;
end;
这是用打印机的Canvas做的:
WITH PRINTERdo
begin
ScaleX := GetDeviceCaps(Handle, logPixelsX) div
PixelsPerInch;
ScaleY := GetDeviceCaps(Handle, logPixelsY) div
PixelsPerInch;
showmessage(inttostr(ScaleX));
//SetPaperHeight(10);
//SetPaperWidth(90);
Printer.begin
Doc;
for i:=0 to 3do
begin
Printer.Canvas.StretchDraw(Rect(i*22*ScaleX*3+interval*(i+1), 0,(22*ScaleX*3+interval)*(I+1),9*ScaleY*3), bitmap);
end;
Printer.EndDoc;
以上我想打印前调用自定义纸张,但不知道怎么做。
 
问题大意是否如下:
1. 将图片打印在已经印好条码的Label纸上,等同于将图片打印在特定尺寸的纸张上面。
2. 图片在纸张中的文件可以在打印过程中调整。
3. 如何设置自定义纸张。
我的回答是,如果你有条码打印机,那可以第一遍先打印条码,然后把打印好的整卷标签纸再放入条码打印机中打印图形。因为条码打印机有光电管检测条码开始的位置,能够准确控制位置,图片打偏的情况应该会很少,如果有累计误差,那就分几个打印任务完成就可以了。用程序来控制的确有些难度,如果配合FastReport和ReportMachine应该会好一些,因为可以用代码来控制每个打印对象的位置。
 
不是的,我讲的有些乱,是这样:
1。我要将已经设计好的图片,按比例缩小打印到label上,此label只印这张图片,且一行有几个label就拷贝相应数量的图片来排列当成一行来打印
2。当label张规格比较小时(如高度为10mm以下),你装纸时的微小差别以及图片内容的差别都有可能造成打印在label纸上的图形的位置有些偏差而且会比较明显(偏高偏低或是偏左偏右),这样,就会想调整一下图片打在纸上的位置。
3。因为我试过用excel和Canvas直接打印的效果,发现我打印一行,但机器会空跑出来几行纸(已经用机器测过纸),首先我想到的是因为没有在程式中设定纸张的规格,所以造成以上结果,
SO,以上两种方式可以实现位置的可调,但是请大家帮忙:
A。如何在以上两种情况中设定自定义纸张以便可以精确控制打印到一行上;
B。如果A不能实现,那么大家会用什么控件或是什么方法来做,请提供源码。
 
沒有人會動態改變打印紙張的寬,高,打印邊距嗎?我不活了~~~[:(]
 
===========
东芝TEC B-452条码打印机
【性能参数】
.....
【适用范围】
3.打印标签宽度:25MM-114MM
4.打印标签长度:5MM-500MM
5.打印精细度:300DPI,精细
=================
看到这个 属性了吗?
------
打印标签长度:5MM-500MM
---------
每次打印,他的最小走纸长度是5MM,最大是500MM,处于中间距离的长度,应该是可以控制的。
不知道你的一行有多少距离?
如果大于 5MM的话,理论上 通过自定义纸张 可以实现的。
在 Microsoft Windows 95、Windows 98 和 Windows Millennium Edition (Me) 系统上,可以灵活地自定义页面大小。
但在运行 Windows NT 和 Windows 2000 的系统上,必须先将所有页面大小定义为页形 (form) 才能使用。
第一步 定义自己需要的自定义纸张(NT 2000下的方法,看一个高手的演示例子代码)
第二步 程序打印时,调用第一步定义的自定义纸张。(有2种方法,高手的演示例子代码是一种方法,另外一种方法,我的一个帖子里有,我是看了MS MSDN的一个VB例子 用D7学写的,没有试过)

这样的话,
一次
printer.begin
doc
printer.enddoc
标签打印机的走纸距离,应该是自定义纸张的长度了,也就是“一行”的效果。
菜鸟言论,仅供参考。
 
纸张的间隙无法测到,如果使用连续纸,请用软体调软体调整到连续纸的值
7. 纸张的间隙部份不明确,请使用条码机专用纸张,可确保间隙部份的透光度为若为X系列,不明确的纸张可用SEE THOGH的方式进行纸张侦测(此功能只有X系列机械器方有,请参见技术文件-版面设定。
=========
标签打印机的走纸是否和纸张本身有关系?
 
我们公司原来使用的标签为10X13厘米的
因为最近打印的量太大,一个月需要打印100多卷
所以现在想将一台闲置的GODEX 2100用起来,但是发现godex2100好像不支持自定义尺寸的纸张,是这样的吗?
另外,我们公司使用的炭带也很多 成本较高 贵公司是否有价格比较便宜的混合基炭带?
条码专家 回复: 条码软件可以排版设定的,我们销售人员会与你联系。
 
to:delhpi
多谢delphi,现在我用的是专用条码纸,间隙2mm,纸张最小高度为9mm,利用打印机配的软件打印没有问题,因为配套软件功能不能满足我们的要求,所以要通过程序来打,以下程式:
WITH PRINTERdo
begin
ScaleX := GetDeviceCaps(Handle, logPixelsX) div PixelsPerInch;
ScaleY := GetDeviceCaps(Handle, logPixelsY) div PixelsPerInch;
//showmessage(inttostr(ScaleX));
//SetPaperHeight(10);
//SetPaperWidth(90);
SetPaperSize(220,90);
//printer.Printers.IndexOfName(1);
Printer.begin
Doc;
for i:=0 to 3do
begin
Printer.Canvas.StretchDraw(Rect(i*22*ScaleX*3+interval*(i+1), 0,(22*ScaleX*3+interval)*(I+1),9*ScaleY*3), bitmap);
end;
Printer.EndDoc;
end;
//
------------------------------
procedure TMainForm.SetPaperSize(X, Y: Integer);
var
Device: array[0..255] of char;
Driver: array[0..255] of char;
Port: array[0..255] of char;
hDMode: THandle;
PDMode: PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
if (x = 0) or (y = 0) then
begin
{设置合法的纸张大小}
pDMode^.dmFields := pDMode^.dmFields or dm_PaperSize;
pDMode^.dmPaperSize := DMPAPER_FANFOLD_US;
// 合法的纸张大小标示
end
else
begin
{设置用户自定义纸张}
pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE or DM_PAPERWIDTH or DM_PAPERLENGTH;
pDMode^.dmPaperSize := DMPAPER_USER;
// 设置为用户自定义纸张标示
pDMode^.dmPaperWidth := x;
// 纸张宽度
pDMode^.dmPaperLength := y;
// 纸张长度
end;
{设定纸张来源}
pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
pDMode^.dmDefaultSource := DMBIN_MANUAL;
GlobalUnlock(hDMode);
end;
end;
end;
发现这与什么不设直接输出没有什么差别,还是多空跑几行纸,要再试我又要重新探测纸张
但是我问过厂商,他们说可以用自定义纸张,不过他发给我的东西没有什么用,我还得找他们:
----------
另外,换标签后,请先做纸张探测再打印!!!
用API函数:
DWORD DeviceCapabilities(
LPCTSTR pDevice, // pointer to a printer-name string
LPCTSTR pPort, // pointer to a port-name string
WORD fwCapability, // device capability to query
LPTSTR pOutput, // pointer to the output
CONST DEVMODE *pDevMode // pointer to structure with device data
);

具体用法看帮助,下面是个Delphi的调用:
var
szDeviceName: String;

szPort: String;

dwPapers: DWord;

lpwPapers: array[0..255] of Word;

...

begin

...

//取打印机支持的全部纸型,存储在数组lpwPapers中
dwPapers:=DeviceCapabilities(PChar(szDeviceName),
PChar(szPort),DC_PAPERS,@lpwPapers,nil);

if (dwPapers<1)or(dwPapers>256) then

ShowMessage('Error');


//判断打印机是否支持自定义、A3、A4、B5纸型
while (dwPapers > 0) do

begin

case DWORD(lpwPapers[dwPapers]) of
DMPAPER_USER: ShowMessage('自定义');

DMPAPER_A3: ShowMessage('A3');

DMPAPER_A4: ShowMessage('A4');

DMPAPER_B5: ShowMessage('B5');

end;

dwPapers:=dwPapers-1;

end;

---------
昨天我想先把图片转成PCX格式再用打印机的API来输出,但是发现什么也没印出来,他们周一才能给我答复,请帮帮忙,
不过我没有用过godex2100,
对于你所说的碳带,我在深圳,不知你们买的是什么价格,型号是什么。
 
我晚上试下你的方法:
procedure SelectPaper;
//from delphi
var
Device, Driver, Port: array[0..255] of char;
ADevMode: THandle;
pDMode: PDevMode;
begin
Printer.PrinterIndex := printer.PrinterIndex;
with Printerdo
GetPrinter(Device, Driver, Port, ADevMode);
if ADevMode <> 0 then
pDMode := GlobalLock(ADevMode);
pDMode.dmFormName:= 'A5';//这里设置纸张名称 即使是自定义的也可以
pDMode.dmFields:=pDMode^.dmFields or DM_FORMNAME;
ResetDC(Printer.Handle,pDMode^);
GlobalUnlock(ADevMode);
end;
是这样吧:
SelectPaper ;
Printer.begin
Doc;
。。。
Printer.EndDoc;
 
.SetPaperSize(X, Y: Integer);
这个过程代码,只对9x系统有效。
你的帖子里, SetPaperSize(220,90);这个代码本身有错误,90是表示9厘米吧,应该写成900,这才表示9厘米。
pDMode^.dmPaperWidth := x;
// 纸张宽度 单位是0.1MM
pDMode^.dmPaperLength := y;
// 纸张长度 单位是0.1MM
 
没做过之前确实感觉挺麻烦,但做过后,发现并不是那么麻烦的,其实和程序没什么关系,我前几天刚做了一个这方面的打印,也是DELPHI倒到EXECL,你只需要直接设置每台打印机上的自定义打印格式,然后选择你要的那种格式.作为模板保存即可.但有一点,这个模板只能一台台电脑设置,自定义格式,同样的模板拷到不同电脑上或不同的操作系统其格式都得重新在每台电脑上自定义设置纸张大小,我虽然已经实现了你这功能 ,但对这个也不能理解,不知道是技术还没过关还是确实不能固定.所以现在也只能哪台打印机打印就到那台电脑上去设置自定义格式,同时再保存一边模板选择及设置就可
 
在一个打印进程中,打印机默认纸张类型,如果是A4,需要选择一个打印机支持的其他纸张类型如A3,A5,或者定义的纸张名称,需要用到DEVMODE结构的dmFormName或者dmPaperSize域,这2个域都可以选择纸张,
dmFormName是按照名称选择。
dmPaperSize是按照“常量”值选择。有个高手做的演示程序,你看看,就是用的这个域。
 
我試過了,用SelectPaper 過程對打印過程沒有影響
我把過程改成了' pDMode.dmFormName:= '220*90''
220*90是我增加的自定義紙張的名字,
但是我這樣做,利用printersetupdialog1,打印時選擇我上面設定的220*90的紙張,打印就一點沒有問題,能夠按要求只出一行紙
我的意思是選擇紙張這一步能否通過程式實現,不要跑出設置畫面,
 
应该是可以的,只是我们水平问题。
 
问题解决,多谢liuyanghi及delphi兄的帮忙,已经为你们各加了100分,现请liuyanghi与delphi再来接50分,
 
本公司诚聘软件工程师数名,要求大专以上学历,计算机专业,熟练掌握DELPHI+SQL编程,能开发C/S 或B/S结构的应用软件,二年以上工作经验,有在软件公司工作经验优先考虑。有意者请联系QQ419682853,邮箱:ljy42af@gdou.com
 
祝贺xiongw。
liuyanghi的水平应该可以的,不过他那个例子还是有点小问题。
我是菜鸟。
通过这个过程,您在打印方面是否也进步了?
 
結案了吧,liuyanghi沒來,都給你了,delphi,TKS~
 
后退
顶部