如何用程序語句定義打印標簽的尺寸? ( 积分: 100 )

  • 主题发起人 主题发起人 shuyue1981
  • 开始时间 开始时间
S

shuyue1981

Unregistered / Unconfirmed
GUEST, unregistred user!
我現在要在標簽上打印流水號,每個標簽的尺寸是40mm*20mm。
請問如何用程序語句定義打印標簽的尺寸?
希望各位大俠能夠賜教。
 
方法一:利用Delphi 的TPrinter 类
TPrinter 类是Delphi 对Windows 打印处理系统的封装,它能够帮助程序员在开发打印程序时尽可能地减少工作量。在程序中使用TPrinter,只要在单元的Use 子句后面添加Printers 即可。当前打印机的DevMode 结构的句柄可以通过调用Tprinter 类中的GetPrinter 方法来获取。当程序获得DevMode 结构的句柄后,就调用GlobalLock 函数来得到指向该结构的指针,随后可对结构中的某些成员进行修改。下面就举一个例子来说明这一问题:假设当前打印机的默认纸张尺寸是A3 纸,现在要打印长度为114mm、宽度为190mm 的纸张。为了简单起见,我们只在Form1 上放置一个Button1 按钮,增加一个OnClick 事件,在Use 子句后添加Printers。程序的代码如下:
Procedure TForm1.Button1Click(Sender: TObject);
var
Device : array[0..cchDeviceName -1] of Char;
Driver : array[0..(MAX_PATH -1)] of Char;
Port : array[0..32]of Char;
hDMode : THandle;
pDMode : PDevMode;
begin
Printer.GetPrinter(Device,Driver,Port,hDMode);
// 获取打印机DevMode 结构的句柄值,
存放在hDMode 中
if hDMode < > 0 then
begin
pDMode := GlobalLock(hDMode);
// 获取指向打印机DevMode 结构的// 指针
if pDMode < > nil then
begin
pDMode^.dmPaperSize := 256;
// 如果要将当前打印机纸张变为自定义
dmPaperSize 必须设置成256
pDMode^.dmPaperLength := 1140;
pDMode^.dmPaperWidth := 1900;
pDMode^.dmFields := pDMode^.dmFields or
DM_PAPERSIZE;
pDMode^.dmFields :=
pDMode^.dmFields or DM_PAPERLENGTH;
pDMode^.dmFields :=
pDMode^.dmFields or DM_PAPERWIDTH;
{ 以上三条语句是对相应
的dmFields 成员进行置位。}
ResetDC(Printer.Handle,pDMode^);
// 设置打印机设备环境句柄的值
GlobalUnlock(hDMode);
end;
end;
{ 下面的代码是为了测试打印机是否
按190 *114 纸张大小来打印}
with Printerdo
begin
begin
Doc;
Canvas.TextOut(10,10,'Hello, My Friend!');
EndDoc;
end;
end;

方法二:利用有关打印的Windows API 函数
解决问题的思路和第一种方法类似,首先要获取当前打印机的DevMode 结构的指针,然后再对该结构进行修改,从而修改打印机纸张大小。要完成上述功能,就得调用DocumentProperties 函数。利用该函数程序就可以获取并修改与当前打印机相关的DevMode 结构中的成员。DocumentProperties 函数申明如下:
LONGdo
cumentProperties
(
HWND hWnd,
HANDLE hPrinter,
LPTSTR pDeviceName,
PDEVMODE pDevModeOutput,
PDEVMODE pDevModeInput,
DWORD fMode
);
六个参数中只有pDevModeOutput 是输出变量,其余五个参数必须由程序给出具体值。其中,hWnd 表征当前窗口的句柄值;hPrinter 表示当前打印机的句柄;pDeviceName 是对打印机设备的描述;pDevModeOutput 是指向句柄值为hPrinter 的打印机DevMode 结构的指针;pDevModeInput 是指向一个修改后的DevMode 结构的指针,该结构有待于被句柄值为hPrinter 的打印机接受;fMode 定义了该函数的具体功能,如果取值DM_IN_BUFFER 那么表示打印机接受由参数pDevModeInput 表示的由程序修改了的DevMode 值,如果取值DM_OUT_BUFFER 那么程序可以通过参数pDevModeOutput 来获取打印机的DevMode 值,如果fMode 为零,则函数返回的值表示结构DevMode 所需的字节数。承接上述例子,现在将190 *114 大小的纸张设成A4 纸。再往Form1 上放置按钮Button2,增加OnClick 事件,在Use 子句后面添加WinSpool。代码如下:
Procedure TForm1.Button2Click(Sender: TObject);
var
PrnHd : THandle;
PrnInfo : PPrinterInfo1;
pcbNeeded : DWORD;
PDevModeBytes : DWORD;
DevMode: PDeviceMode;
PrnHdc : HDC;
do
cInfo : PDocInfo;
begin
OpenPrinter('Epson LQ -1600K',PrnHd,nil);
// 获得打印机句柄PrnHd
GetMem(PrnInfo,1024);
GetPrinter(PrnHd,1,PrnInfo,1024,@pcbNeeded);
PDevModeBytes:=do
cumentProperties
( Handle,PrnHd,prninfo^.
pDescription,DevMode^,DevMode^,0 );
{ 获取DevMode 结构所需的字节数}
GetMem(DevMode,PDevModeBytes);
// 给结构DevMode 分配空间
do
cumentProperties( Handle,PrnHd,PrnInfo^.p
Description,DevMode^,DevMode^,DM_OUT_BUFFER );
// 获取打印机的DevMode 结构
With DevMode^do
begin
dmPaperSize := DMPAPER_A4 ;
// 将纸张设置成A4 纸
dmFields := dmFields or DM_PAPERSIZE;
end;
do
cumentProperties( Handle,PrnHd,PrnInfo^.p
Description,DevMode^,DevMode^,
DM_OUT_BUFFER or DM_IN_BUFFER);
// 修改DevMode 结构。
{ 下面的代码是为了测试打印机
是否按A4 纸大小来打印 }
PrnHdc := CreateDC
( nil, 'Epson LQ -1600K',nil,DevMode );
GetMem(do
cInfo, 100 );
Withdo
cInfo^do
begin
cbSize := sizeof(DocInfo);
lpszDocName := nil;
lpszOutput := nil;
lpszDatatype := nil;
fwType := DI_APPBANDING;
end;
StartDoc( PrnHdc,do
cInfo^);
StartPage(PrnHdc);
TextOut( PrnHdc, 10, 10, 'Hello My Friend!',17);
EndPage(PrnHdc);
EndDoc(PrnHdc);
DeleteDC(PrnHdc);
FreeMem(DocInfo);
FreeMem(PrnInfo);
FreeMem(DevMode);
end;
 
我用方法一執行程序,發現錯誤提示“Printer selected is not valid.”
請問是什麼問題?
 
我想用delphi寫一個在標簽上面打印2列流水號的程序,程序內容如下面,但是
程序執行時出現&quot;Printer selected is not valid.&quot;的錯誤提示,各位大俠能否幫我看看是什麼問題?
procedure TForm1.Button1Click(Sender: TObject);
var
seq1: Integer;
seq2: Integer;
i: Integer;
j: Integer;
l: Integer;
Device:Array[0..cchDeviceName-1] of Char;
Driver:Array[0..(MAX_PATH-1)] of Char;
Port:Array[0..32] of Char;
hDMode:THandle;
pDMode:PDevMode;
begin

Printer.GetPrinter(Device,Driver,Port,hDMode);
if hDMode<>0 then
begin
pDMode:=GlobalLock(hDMode);
if pDMode<>nil then
begin
pDMode^.dmPaperSize:= 256;
pDMode^.dmPaperLength:= 40;
pDMode^.dmPaperWidth:= 10;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERSIZE;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERLENGTH;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERWIDTH;
GlobalUnLock(hDMode);
end;
end;

seq1:=StrToInt(Form1.Edit1.Text);
seq2:=StrToInt(Form1.Edit2.Text);
//read the start number and the end number
Printer.begin
Doc;
Printer.Canvas.Font.Name:='Arial Black';
Printer.canvas.Font.size:=18;
Printer.Canvas.Font.Style:=[fsBold];
//set font
l:=((seq2 - seq1) div 2)+1;
j:= 1;
for i:=1 to ldo
begin
Printer.Canvas.TextOut(1,j,IntToStr(seq1));
Printer.Canvas.TextOut(150,j,IntToStr(seq1+1));
// print
seq1:=seq1+2;
j:=j+150;
Printer.NewPage;
//newpage
end;
Printer.EndDoc;
end;
 
没有默认打印机,
 
有默認的打印機啊
 
后退
顶部