在Delphi中实现打印预览

Author: 顾银晓 Date: 2001年 35期

?牐犜诤芏嘤τ贸绦蛑校夹枰绦蚓哂写蛴≡だ拦δ埽员苊庥没в捎谘≡癫坏背鱿执蛴〈砦蟆T贒elphi下一般的打印预览实现方式为通过创建一个Tpanel的派生类并公开它的canvas属性来实现,这种方式需要编程者小心的调整比例尺或视区范围,使用较为不方便,笔者通过实践实现了用图元文件(Metafile)来实现打印预览的方法,这种方式不需要调整比例尺和视区范围。
  ?牐牷驹砗头椒ǎ?
  ?牐犕荚募渤谱鳌盎嫱祭嘈汀钡耐夹危且酝夹味韵螅ㄏ摺⒃不 ⒍啾咝危┓绞蕉皇窍袼胤绞嚼创娲⑼枷瘛M荚募夹味ㄒ逦嗦氲南叨魏屯夹巍?Windows系统下有两种类型的图元文件:标准型(WMF文件格式)和增强型(EMF文件格式)。
  ?牐犑褂猛荚募暮么υ谟谒芄蝗我獯笮∷醴挪⑶胰阅鼙3忠欢ǖ谋普娑龋馐且蛭荚募ǔS梢幌盗惺噶客夹蔚耐荚槌桑荚侵赶咛酢⑻畛涞那蛞约奥掷痔宓取@┐蠡蛩跣⊥枷裰皇羌虻サ厮醴哦ㄒ逭庑┩荚乃凶甑悖缘钡髡枷翊笮∈保荚募酝枷竦谋4姹认袼馗罚Ч谩?
  ?牐燚elphi以Tmetafile对象对Win32增强型图元文件进行了封装,通过设置Enhanced属性可以设定图元文件是以标准型或可增强型格式存储。
  ?牐犜贒elphi中使用图元文件的基本方法是:
  ?牐牎翊唇ㄍ荚募?
  ?牐牎袷褂貌握丈璞傅拇蛴』浔唇ㄍ荚募级韵螅═metafilecanvas)
  ?牐牎袢缤诖蛴』忌弦谎谕荚募忌辖忻杌?
  ?牐牎窠荚募谄聊簧舷允境隼?
  ?牐犑迪植街瑁?
  ?牐犑紫冉?立一个窗体文件,在适当位置放上一个panel控件(panel1),一个checkbox控件(chedkbox1),并设定checkbox的caption为”打印预览”,在panel上放置一个image控件(image1),并设image1的align属性为alclient。
  ?牐犜赨SES中添加打印程序单元(Printers),尽管Delphi在生成窗体时会自动在USES部分加入许多程序单元,但打印程序单元却不在此列,只能手工给它加上。
  ?牐牴丶胨得鳎?
  ?牐犛肎etDeviceCaps (Printer.Handle,LOGPIXELSX)获取当前打印机的水平分辨率。
  ?牐犎绻肴么蛴〕绦蛟谌魏未蛴』隙寄苷5卮蛴。憔捅匦敫谋淠愕亩攘康ノ弧?
  ?牐燿pm:=trunc(dpi/25.4);??
  ?牐?//算出每毫米的打印机点数。
  ?牐燤yMetafile:= TMetafile.Create;
  ?牐?//创建图元文件
  ?牐燭MetafileCanvas.Create?煟∕yMetafile,printer.Handle)
  ?牐?//以打印机句柄创建图元文件画布
  ?牐爐extout(trunc(sx* dpm),trunc(sy*dpm)',我的打印');//进行打印输出
  ?牐爄mage1.Canvas.StretchDraw?煟╥mage1.canvas.cliprect,MyMetafile);
  ?牐?//显示图元文件
  ?牐牫绦蛟创耄?
  ?牐爑nit u_print;
  ?牐爄nterface
  ?牐爑ses
  ?牐燱indows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,
  ?牐燬tdCtrls,Buttons,printers,ExtCtrls;
  ?牐爐ype
  ?牐燭F_print = class(TForm)??
  ?牐牎?
  ?牐爌rivate
  ?牐爗?? Private declarations }
  ?牐爌ublic
  ?牐爗?? Public declarations  }
  ?牐爀nd;
  ?牐爒ar
  ?牐燜_print:TF_print;
  ?牐爄mplementation
  ?牐爗$R*.DFM}??
  ?牐爌rocedure TF_print.BitBtn1Click?煟⊿ender: TObject);?牔?
  ?牐燽egin
  ?牐燾lose;
  ?牐爀nd;
  ?牐?//定义report过程,使真实打印和打印预览共用此过程
  ?牐爌rocedure TF_print.report?煟ˋcanvas:Tcanvas);??
  ?牐爒ar
  ?牐爏x,sy,sy0,sx0:real;//起始位置
  ?牐燿pi,dpm:real; //每毫米的点数
  ?牐燗Rect: TRect;??
  ?牐燽egin
  ?牐燿pi:=GetDeviceCaps?煟≒rinter.Handle,LogPixelsX);?牔?
  ?牐燿pm:=trunc(dpi/25.4); //每毫米的点数
  ?牐爏x:=100;sx0:=10;sy0:=10;sy:=sy0;??
  ?牐爓ith Acanvas do
  ?牐爐ry
  ?牐爁ont.name:='宋体';
  ?牐爁ont.size:=18;??
  ?牐爐extout(trunc(60*dpm),trunc(sy*dpm),'我的打印预览');
  ?牐爏y:=sy+10;
  ?牐爐extout(trunc(60*dpm),trunc(sy*dpm),'姓名');?牔?
  ?牐爏y:=sy+10;??
  ?牐爌en.Width:=5;??
  ?牐燤oveTo(trunc(sx0*dpm),trunc('sy*dpm))',?牐牔?
  ?牐燣ineTo(trunc((sX0+200)*dpm),trunc(sy*dpm));?牐牔?
  ?牐爁ont.size:=12;??
  ?牐爏y:=sy+5;??
  ?牐爐extout(trunc(sx0*dpm),trunc(sy*dpm),'内容');?牔?
  ?牐爏y:=sy+5;
  ?牐燤oveTo(trunc(sx0*dpm),trunc(sy*dpm)),?牐牔?
  ?牐燣ineTo(trunc((sX0+200)*dpm),?爐runc(sy*dpm));?牐牔?
  ?牐爁inally
  ?牐燜ree;??
  ?牐爀nd;
  ?牐爀nd;
  ?牐爌rocedure TF_print.BitBtn2Click(Sender:TObject);?牔?
  ?牐爒ar mymetafile:Tmetafile;
  ?牐爄fprt:boolean;??
  ?牐燽egin
  ?牐爄fprt:=not checkbox1.checked;
  ?牐?//是false则打印预览,true则打印
  ?牐爄f ifprt then
  ?牐燽egin
  ?牐爌rinter.BeginDoc;
  ?牐爎eport(printer.canvas);
  ?牐?//将打印机画布对象传给report过程
  ?牐爀nd
  ?牐爀lse
  ?牐燽egin
  ?牐燤yMetafile??=TMetafile.Create??
  ?牐?//创建图元文件
  ?牐?//以打印机句柄创建图元文件画布对象(Tmetafilecanvas),并调用report过程
  ?牐爎eport (TMetafileCanvas.Create?煟∕yMetafile,printer.Handle));
  ?牐爀nd;
  ?牐?//如果是打印则结束打印
  ?牐爄f ifprt then printer.enddoc;
  ?牐?//如果是打印预览,则在image1上显示出来
  ?牐爄f not ifprt then image1.Canvas.StretchDraw?煟╥mage1.canvas.cliprectMyMetafile);
  ?牐爀nd;
  ?牐爀nd.
  ?牐犚陨洗朐赪indows 98、Delphi 5.0下调试通过。