如何做打印预览,欢迎提供思路(200分)

  • 主题发起人 主题发起人 inforum
  • 开始时间 开始时间
I

inforum

Unregistered / Unconfirmed
GUEST, unregistred user!
我想用TPanle控件做打印预览(不光光是报表预览),要求能缩放。
将Canvas属性共享后,在上面TextOut,
当指定的字体教小时,字体大小不变,是不是要用API
欢迎提供思路或源码。谢谢!
 
很简单,根据显示比例重新指定Canvas.Font.Size,如原Size为12,现在500%的比例显示,
计算结果:Round(12*500/100),因为字体是矢量的,不用担心会变型
 
To 小隐:
放大可以,可缩小不行。字体还是那么大
 
Report Mathine 已经实现打印可缩放,希望对你有帮助。
 
缩小不行有两种原因,你跟踪一下:
1、你使用的字体不允许使用你指定的大小。
2、你没有保存字体的原始大小。
否则不可能
 
那该如何保存字体的原始大小呢?
[:(]
下面的做法为什么字体大小不变呢。
var
RScale: double;
SaveFont: TFont;
begin
RScale := PrintPrev.Width / Printer.PageWidth;
SaveFont := TFont.Create;
try
SaveFont.Assign(PrintPrev.Canvas.Font);
ACanvas.Font.Name := 'Arial';
PrintPrev.Font.Size := Trunc(ARatio * 10);
PrintPrev.TextOut(Px, Py, 'Test');
PrintPrev.Canvas.Font.Assign(SaveFont);
finally
SaveFont.Free;
end;

 
我认为:可以:把:QUICKREPORT的打印预览汉化一下,就OK了。
使用,也方便。
 
缩小怕不容易,很多字体最小只支持到那么小。
可以先用比较大的字写在比较大的画布上,然后对小画布用 StrechDraw
此招数对图形同样奏效:)
 
缩放比较正规的方法是使用SetMapMode、SetViewportExtEx、SetWindowExtEx函数来实现;
 
如果你要缩放,用PANEL来实现比较困难,整体的缩放效果比较容易,但字体就有点困难了。

所以我建议你用image控件,通过图元文件画矢量图来预览,这样可以无级缩放,且效果很
好,你可以看一下我以前问的问题,或许有些帮助。
 
在我的印象中,Truetype的字体是可以缩放的,非truetype的,
如 System好像小不到哪里去。
我做过一个打印预览,因为想做的通用,所以针对不同的打印要求,
抽象出来一个接口如下,需要打印的类实现这个接口后,作为参数传给我的打印预览窗口。

IPrintable = interface
// 打印纸的方向
function GetOrient: TPrinterOrientation;
procedure SetOrient(const Value: TPrinterOrientation);
// 在纸上的打印原点
function GetOrigin: TPoint;
procedure SetOrigin(const Value: TPoint);
// 纸张大小(相对于A4,B5等预定义的纸张,只是一个整数)
function GetPaperSize: Integer;
procedure SetpaperSize(const Value: Integer);
// 自定义纸张的大小
function GetPaperLength: Integer;
function GetPaperWidth: Integer;
procedure SetPaperLength(const Value: Integer);
procedure SetPaperWidth(const Value: Integer);
// 要打印的总页数
function GetTotalPage: Integer;
// 缩放比例
function GetZoomRatio: Integer;
procedure SetZoomRatio(const Value: Integer);
// 要打印的每页实际的大小
function GetPageWidth: Integer;
function GetPageHeight: Integer;
// 打印
procedure PrintPage(Canvas: TCanvas; PageIndex: Integer; Scale: double = 1);
// 保存打印的配置,包括纸张,纸的方向,绘图原点,缩放比例等
procedure SavePrintConfig;

property ZoomRatio: Integer read GetZoomRatio write SetZoomRatio;
property PrintOrient: TPrinterOrientation read GetOrient write SetOrient;
property PaperSize: Integer read GetPaperSize write SetPaperSize;
property PaperLength: Integer read GetPaperLength write SetPaperLength;
property PaperWidth: Integer read GetPaperWidth write SetPaperWidth;
property Origin: TPoint read GetOrigin write SetOrigin;
property TotalPage: Integer read GetTotalPage;
property Caption: string read GetCaption;
property PageWidth: Integer read GetPageWidth;
property PageHeight: Integer read GetPageHeight;
end;

在我的打印预览窗口中,我用PaintBox模拟一张纸。要注意,打印函数
procedure PrintPage(Canvas: TCanvas; PageIndex: Integer; Scale: double = 1);
是一个,也就是说在屏幕上显示、在模拟纸上的显示、在打印机上实际打印,用的都是这个函数。
不同的是Canvas,为了能保持一致,要注意不同的Canvas是有不同的分辨率的。所以,打印函数中
要对所有的坐标进行 * Scale 的处理。比如字体,如果你用的是TrueType字体,我的经验保证
可以这样写: Font.Height := Round(Font.Height * Scale);
下面是在PaintBox上的 OnPaint函数:
procedure TFormPreview.PaintBoxPaint(Sender: TObject);
begin
with PaintBox.Canvas do
begin
Pen.Color := clBlack;
Brush.Color := clWhite;
rectangle(PaintBox.ClientRect);
...
//画当前页
MoveWindowOrg(handle, R(offSetL), R(offSetT));
FPrintable.PrintPage(PaintBox.Canvas, CurPage, Scale);
MoveWindowOrg(handle,-R(offSetL), -R(offSetT));
end;
...
end;

要做一个好的打印预览,需要考虑的东西挺多,我的实现也有很多毛病,比如我用的是像素,没有
用毫米这样设备无关的长度单位,接口抽象的也不是很好,但是对我来说够用了,也就懒得改了。

我是为一个报表写的打印预览,也许你的要求不是那么高,你可以去DSP找一些现成的PrintPreview
控件来参考一下,这会让你对Windows下的打印有更深层次的认识。
 
谢谢大家,马上就要结帖。
TO Jinghui
本人水平很低,
能把TrueType字体介绍一下吗,后缀为*.ttf的文件是TrueType字体吗
 
谢谢大家,马上就要结帖。
TO x_coffee:
机械版《Delphi5开发人员指南》上说
“一个更好的打印预览可以由图元文件创立。要创建图元文件,使用参照设备的打印机句柄,然后如同在打印机画布上一样,在图元文件画布上进行描绘,再将图元文件显示在屏幕上。
不需要比例尺或视区范围的调整。”
我用TImage已基本实现了预览功能,也可以无级缩放(通过修改Printer.pas,所以在预览窗口打印的时候,
先要SetPrinter(NIL),但是打完了报错,因为我没保存打印机),但我不满意。特请教
1)如何显示图元文件的内容(使用PlayMetaFile函数吗?)
最好将示例贴出来。
2)怎样把显示的图元文件发送给打印机.
谢谢。
 
在选择字体的对话框中,看到字体前有两个T的图标的字体就是TrueType字体。
有时还会有其他的图标,比如word中会看到打印机的图标,这些都是矢量字体,
也就是说可以缩放旋转的,而没有图标的,有可能是点阵字体。*.ttf 应该是
TrueType字体。
其实打印、显示对于程序来说,都是一样的。特别是我们用Delphi的人。
都是在画布(canvas)上画图,你怎么在屏幕上显示,就怎么在打印机上输出,
这就是windows的好处,不用针对不同的打印机编程(想想Dos时代)。你要注意
的问题就是,这两种画布的质地不一样,一个每英寸96个点,另一个可能是300、
600或其他数个点,仅此而已。
 
我还是用TImage实现了预览功能,
现在结帖
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部