http://community.csdn.net/Expert/topic/4390/4390241.xml?temp=.7930719教:在delphi中如何发送打印机控制码?在我的打印机操作面板上有一个功能按钮——换行,执行后打印机向前走纸0.5cm,我想在程序中调用这个换行功能,请高手指点如何实现?windows提供的escape可以给打印机发送控制码,其定义如下:
int Escape(
HDC hdc, // 打印机的handle
int nEscape, // escape 函数
int cbInput, // 输入结构的大小
LPCSTR lpvInData, // 输入结构的指针
LPVOID lpvOutData // 输出结构的指针
);
在这个定义中,第二个参数nEscape,我不清楚要传什么呢?说明文档说提到,这个参数必须是一个预先定义好的,windows下提供了如下的几个定义:ABORTDO;ENDDOC;GETPHYSPAGESIZE;GETPRINTINGOFFSET;GETSCALINGFACTOR;NEWFRAME;NEXTBAND;PASSTHROUGH;SETABORTPROC;STARTDOC;其中好像没有我需要的,用于换行的。在win32api的说明文档中也提到,对于常用的print escape都已经定义对应的方法,如:AbortDoc,EndDoc等,没有对应的用于换行的方法。同时也了解到,如果需要发送一些私有的print escape 需要用到extEscape函数,该函数的定义如下:int ExtEscape(
HDC hdc, //设备Handle
int nEscape, // escape function
int cbInput, // number of bytes in input structure
LPCSTR lpszInData, // pointer to input structure
int cbOutput, // number of bytes in output structure
LPSTR lpszOutData // pointer to output structure
);同样的,在这个函数的定义中,我不知道需要都要传入那些参数呢??
我的环境是delphi7.0/winXP/EPSON LQ-1600KIII请高手们关注。
int Escape(
HDC hdc, // 打印机的handle
int nEscape, // escape 函数
int cbInput, // 输入结构的大小
LPCSTR lpvInData, // 输入结构的指针
LPVOID lpvOutData // 输出结构的指针
);
在这个定义中,第二个参数nEscape,我不清楚要传什么呢?说明文档说提到,这个参数必须是一个预先定义好的,windows下提供了如下的几个定义:ABORTDO;ENDDOC;GETPHYSPAGESIZE;GETPRINTINGOFFSET;GETSCALINGFACTOR;NEWFRAME;NEXTBAND;PASSTHROUGH;SETABORTPROC;STARTDOC;其中好像没有我需要的,用于换行的。在win32api的说明文档中也提到,对于常用的print escape都已经定义对应的方法,如:AbortDoc,EndDoc等,没有对应的用于换行的方法。同时也了解到,如果需要发送一些私有的print escape 需要用到extEscape函数,该函数的定义如下:int ExtEscape(
HDC hdc, //设备Handle
int nEscape, // escape function
int cbInput, // number of bytes in input structure
LPCSTR lpszInData, // pointer to input structure
int cbOutput, // number of bytes in output structure
LPSTR lpszOutData // pointer to output structure
);同样的,在这个函数的定义中,我不知道需要都要传入那些参数呢??
我的环境是delphi7.0/winXP/EPSON LQ-1600KIII请高手们关注。
解决方案 »
- 三方控件使用(DsnStage,DsnRegister,DsnSelect)
- Idtcpclient在服务器端断开时居然不触发ondisconnect事件?
- [hook相关]安装WH_CBT后有时没效果
- 【在线等】关于ActionList中奇怪的问题
- 用postmessage对某程序发消息,保存对话框的内容怎么办?
- view form 里怎么能显示中文的窗体名啊?
- delphi有没有类似MFCGridcontrol的第三方控件
- 提示内存不足,到底是线程数量有限制还是内存容量不够?????
- 各位高手:如何用ADO连接数据库,怎么传值给数据库?
- 麻烦高手批改作业。(winsocket问题)
- ******高手来一下吧!!!!有关走马灯****
- 用EnumWindows枚举出所有正在运行的窗体后,无法将指定的窗体最大化?
AssignPrn(textFile);
Rewrite(textFile);
WriteLn(textFile,chr(27) + chr(10));以上这些代码应该就是 直接写打印机吧??为什么达不到预期的效果。
printer.BeginDoc;
printer.Canvas.TextOut(100, 20, 'abc');
printer.Canvas.TextOut(100, 30, '下一行');
...
printer.NewPage;
...
printer.EndDoc;
printer.BeginDoc;
printer.EndDoc;
不管他们中间 有没有 语句,都会引起 走一页纸,也就是说,无法达到我只要换行的目的。嗯,我用的是 24针打印机。打印机的面板上有用于换行的按钮,也就是说,他有这个功能,但我现在不知道 如何把控制码 发给他。
这是票据打印一段代码(Epson LQ300K),仅供参考:
procedure PrintTicket(AStation,Achannel,Auserid,ATicketNo,
AMoney,APntdate,APnttime:string);stdcall;
var
F:TextFile;
...
begin
....
Assignfile(f,'LPT1');
rewrite(f);
{初始化打印机}
Write(f,chr(27)+'@'); //Chr(27)+'@' 即ESC @ 指令
{设置汉字显示方式}
write(f,chr(28)+chr(ord('&'))); //Chr(28) 即 FS
{设定打印相对水平位置}
Write(f,chr(27)+chr(ord('\'))+chr($CF)+chr($00));
//设置高速打印
//write(f,chr(28)+chr(ord('x'))+chr($01)); Writeln(f,PrintChannel+space(16)+Auserid+space(12)+carType);
Writeln(f);
write(f,chr(27)+chr(ord('\'))+chr($CF)+chr($00));
Write(f, AMoney);
Writeln(f,Space(26)+PrntTicketno);
Writeln(f);
write(f,chr(27)+chr(ord('\'))+chr($CF)+chr($00));
//Writeln(f);
Writeln(f,Apntdate+Space(12)+ApntTime);
//顺时针走纸控制
Writeln(f,chr(27)+chr(ord('J'))+chr($FF));
Writeln(f,chr(27)+chr(ord('J'))+chr($20)); flush(f);
Closefile(f);end;不同的打印机控制码会有所不同,具体参考打印机手册。》怎么让打印机在打印前后退2行,设定纸张的大小
将打印机纸张类型设为自定义,自定义纸张大小,
这类代码很多,搜索一下,以上也有给出了一些
至于,打印前后退2行,先将纸张在打印机装好,控制好
其装纸位置(可微调打印机),打印后重要的是走纸的控制,
最好是用控制码控制,实在没办法的话,你也可以用
writeln(f)
writeln(f)
这样的折行控制。>>//顺时针走纸控制
>>Writeln(f,chr(27)+chr(ord('J'))+chr($FF));
>>Writeln(f,chr(27)+chr(ord('J'))+chr($20));这个是我根据打印机控制码指令
执行n/180英寸顺方向走纸 Esc J n (1<=n<=255)
以及打印票据纸张的高度,来调整打印连续纸时的走纸长度。
另外,这里还有一些LQ300K的一些打印位置控制码指令:
设定高速打印 FS x n (n=0,1)
设定绝对水平打印位置 Esc ¥ nL nH (0<=nH<=127
0<=nL<=255)
设定相对水平打印位置 Esc \ nL nH (同上)供参考。具体你可以查看你的打印机手册。
方法就如你所说的,我都试了,和你代码唯一的区别是,你使用 Assignfile(f,'LPT1'); 打开打印机端口,而我使用
assignprn(f) 来打开打印机端口的,而实际上我的计算机因为是笔记本,所以打印机是通过usb口和打印机联系起来的,所以我想直接的操作 lpt1估计不行吧??
>>Writeln(f,chr(27)+chr(ord('J'))+chr($20));这两句代码中 J,和 $FF或者$20分别代表了什么阿??
从我的打印机手册中查到 ,换行是两个指令即:ESC + LF,对应的十进制编码也就是 27,10。
为什么你这里 中间会多一个 值呢??难道是打印机型号不同所致??
我的是 EPSON LQ-1600KIII
用文本的方式打印delphi需要用端口的方式,否则控制命令会没有用。
下面是小弟的现在用的pos 机的打印部分,供你参考(机型EPSON TM88III);type
TPrinterInfo = record
SeverName : PChar;
PrinterName : PChar;
ShareName : PChar;
PortName : PChar;
DriverName : PChar;
Comment : PChar;
Location : PChar;
DeviceMode : PDeviceModeA;
SepFile : PChar;
PrintProcessor : PChar;
DataType : PChar;
Parameters : PChar;
SecurityDescriptor: PSecurityDescriptor;
Attributes : Cardinal;
DefaultPriority : Cardinal;
StartTime : Cardinal;
UntilTime : Cardinal;
Status : Cardinal;
Jobs : Cardinal;
AveragePPM : Cardinal;
end;function GetCurrentPrinterInformation: TPrinterInfo;
var
hPrinter : THandle;
pInfo: PPrinterInfo2;
bytesNeeded: DWORD;
begin
hprinter := GetCurrentPrinterHandle;
try
Winspool.GetPrinter( hPrinter, 2, Nil, 0, @bytesNeeded );
pInfo := AllocMem( bytesNeeded );
try
Winspool.GetPrinter( hPrinter, 2, pInfo, bytesNeeded, @bytesNeeded );
Result.SeverName := pInfo^.pServerName;
Result.PrinterName := pInfo^.pPrinterName;
Result.ShareName := pInfo^.pShareName;
Result.PortName := pInfo^.pPortName;
Result.DriverName := pInfo^.pDriverName;
Result.Comment := pInfo^.pComment;
Result.Location := pInfo^.pLocation;
Result.DeviceMode := pInfo^.pDevMode;
Result.SepFile := pInfo^.pSepFile;
Result.PrintProcessor := pInfo^.pPrintProcessor;
Result.DataType := pInfo^.pDatatype;
Result.Parameters := pInfo^.pParameters;
Result.SecurityDescriptor := pInfo^.pSecurityDescriptor;
Result.Attributes := pInfo^.Attributes;
Result.DefaultPriority := pInfo^.DefaultPriority;
Result.StartTime := pInfo^.StartTime;
Result.UntilTime := pInfo^.UntilTime;
Result.Status := pInfo^.Status;
Result.Jobs := pInfo^.cJobs;
Result.AveragePPM := pInfo^.AveragePPM;
finally
FreeMem( pInfo );
end;
finally
ClosePrinter( hPrinter );
end;
end;procedure PrintData(PrintList: TStringList; Printname: string; Port: boolean);
var
Line: Integer;
PrintText: TextFile;//System.Text;
PrinterInfo: TPrinterInfo;
printport: string;
begin
if not Port then
begin
printer.PrinterIndex:= printer.printers.IndexOf(Printname);
PrinterInfo := GetCurrentPrinterInformation;
printport := PrinterInfo.PortName;
end
else
printport:= Printname;
AssignFile(PrintText,printport);
Rewrite(PrintText);
//Printer.Canvas.Font := Memo1.Font;
for Line := 0 to PrintList.Count - 1 do
Write(PrintText,PrintList[Line]);
CloseFile(PrintText);
end;
从你的意思来看,是需要用 Assignfile(f,'LPT1');而不是 assignprn(f)
我当前的打印机是通过usb接口连接到笔记本的,Assignfile(f,'usbidx');是不行的,暂时我没有通过并口直接连接的打印机,所以无法验证是否可以,验证后我再来发表结果。
请注意我的代码实现方式。Printname是打印机的名,他会转成printport.代码中考虑到这点了。
考虑到用到的单元(Printers,winspool)。
最后,希望楼主不要称我“大侠”。剩下的看楼主自己的了。祝好运。