API调整纸张大小

LONG DocumentProperties
(
  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 所需的字节数。


  if   (!OpenPrinter((char   *)alpszPrinterName,&hPrinter,NULL))   return   1;  
  //set   papersize  
  DWORD   dwBytesNeeded;  
  dwBytesNeeded=DocumentProperties(NULL,hPrinter,NULL,NULL,NULL,0);  
  HGLOBAL   lhDevMode=GlobalAlloc(GHND,dwBytesNeeded);  
  PDEVMODE   lpdmDevMode=(PDEVMODE)GlobalLock(lhDevMode);  
  DocumentProperties(NULL,hPrinter,NULL,lpdmDevMode,NULL,DM_OUT_BUFFER); 
  lpdmDevMode->dmFields=DM_PAPERLENGTH   |   DM_PAPERWIDTH;  
  lpdmDevMode->dmPaperLength=aiPaperLength;  
  lpdmDevMode->dmPaperWidth=aiPaperWidth;  
  dwBytesNeeded=DocumentProperties(NULL,hPrinter,NULL,  
  lpdmDevMode,lpdmDevMode,DM_IN_BUFFER   |   DM_OUT_BUFFER);  
  ClosePrinter(hPrinter);  
  if(!(hdcPrinter=CreateDC(NULL,alpszPrinterName,NULL,lpdmDevMode)))   return   2;  
  GlobalUnlock(lhDevMode);GlobalFree(lhDevMode);

/////////////////////////////////////////////////////


承接上述例子,现在将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;
  DocInfo : PDocInfo;
begin
  OpenPrinter('Epson LQ -1600K',PrnHd,nil); 
  // 获得打印机句柄PrnHd
  GetMem(PrnInfo,1024);
  GetPrinter(PrnHd,1,PrnInfo,1024,@pcbNeeded);
  PDevModeBytes:= DocumentProperties
( Handle,PrnHd,prninfo^.
 pDescription,DevMode^,DevMode^,0 );
{ 获取DevMode 结构所需的字节数}
  GetMem(DevMode,PDevModeBytes); 
// 给结构DevMode 分配空间
  DocumentProperties( 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;
  DocumentProperties( 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( DocInfo, 100 );
  With DocInfo^ do begin
   cbSize := sizeof(DocInfo);
   lpszDocName := nil;
   lpszOutput := nil;
   lpszDatatype := nil;
   fwType := DI_APPBANDING;
  end;
  StartDoc( PrnHdc, DocInfo^);
  StartPage(PrnHdc);
  TextOut( PrnHdc, 10, 10, 'Hello My Friend!',17);
  EndPage(PrnHdc);
  EndDoc(PrnHdc);
  DeleteDC(PrnHdc);
  FreeMem(DocInfo);
  FreeMem(PrnInfo);
  FreeMem(DevMode);
end;
  至此,程序实现了本文开头所提出的要求。需要指出的是,上述代码是在程序运行时,动态地改变打印机纸张大小,而不改变打印机默认纸张大小。也就是说当 打印程序运行结束后,打印机还是会按照默认打印纸张大小来打印、走纸。动态调整打印机纸张尺寸也是因打印机而异,某些打印机基本不支持自定义纸张,例如惠 普的HP DeskJet 1120C 喷墨打印机以及众多激光打印机。因此在这些打印机上,不能实现按任意纸张大小打印。对于一些针式打印机则没有上述问题。

posted @ 2012-06-28 00:44  小软狐  阅读(3486)  评论(0编辑  收藏  举报