如何进行打印预览时进行无级缩放,有源码者分高?(300分)

  • 主题发起人 主题发起人 zouming
  • 开始时间 开始时间
Z

zouming

Unregistered / Unconfirmed
GUEST, unregistred user!
1、在previewform放置paintbox;
2、在paintbox上使用lineto()进行画表格,在表格中画使用textout()进行输出文本;
3、当改变paintbox的尺寸时,如何进行无级缩放(包括线条和文本),而不会在不同
的缩放系数下的文本长度不协调;
4、字体的缩放具体如何处理?
5、打印时使用Tprinter类。
 
难度较高,值得探讨...
 
我的办法可能比较笨拙。
我把你的paintbox改成image组件,image的streah=true, align=alclient
var
tb:Tbitmap;
begin
tb:=tbitmap.create;
try
tb.pixformat:=pr4bit //我想你16色图就够了,可以节约内存
tb.width:= w //你要花的宽度
tb.height:= h //你要花的高度
with tb.canvasdo
begin
............. // 把你在paintbox中的内容 画在这里
end;
iamge1.picture.bitmap.assign(tb);
finally
tb.free;
end;
end;
 
你只要画一次图象,当你无论如何改变image的大小,基本上可以满足你的要求
 
procedure Tmypreview.ZoomFitClick(Sender: TObject);
begin
//ZoomToFit 缩 放 至 全 屏
QRPreview1.ZoomToFit;
SetZoom(QRPreview1.Zoom);
end;

procedure Tmypreview.Zoom100Click(Sender: TObject);
begin
//ZoomTo100% 缩 放 至 实 际 大 小
QRPreview1.Zoom:=100;
SetZoom(QRPreview1.Zoom);
end;

procedure Tmypreview.ZoomToWidthClick(Sender: TObject);
begin
//ZoomToWidth 缩 放 至 页 宽
QRPreview1.ZoomToWidth;
SetZoom(QRPreview1.Zoom);
end;
 
不能使用QR,须使用TPrinter
 
有了解决办法:
预览时,用如下代码:
procedure TFrm_Preview.PaintBox1Paint(Sender: TObject);
var
PageSize : TSize;
begin
SetMapMode(PaintBox1.Canvas.Handle, MM_ISOTROPIC);
PageSize.cx := PaintBox1.Width;
PageSize.cy := PaintBox1.Height;
SetWindowExtEx(PaintBox1.Canvas.Handle, FPageWidth, FPageHeight, @PageSize);
SetViewPortExtEx(PaintBox1.Canvas.Handle, PaintBox1.Width, PaintBox1.Height, @PageSize);
DrawOnePage(PaintBox1.Canvas.Handle, PaintBox1.Canvas,iPageWidth,iPageHeight,iLeftMargin,iTopMargin,iRightMargin,iBottomMargin, nFooterMargin, true,PrePpiX,PrePpiY, sMainDir+'/Temp/'+IntToStr(iPageNumber)+'.tmp', iScale);
{
if iScale=100 then
begin
PaintBox1.Height:= Round(ScrollBox1.Height+0.5)-10;
PaintBox1.Width:= Round(PaintBox1.Height*iPageWidth/iPageHeight*1.0+0.5);
end else
begin
PaintBox1.Height:= Round(OrignDrawHeight*iScale/100+0.5);
PaintBox1.Width:= Round(PaintBox1.Height*iPageWidth/iPageHeight+0.5);
end;
}
//DrawOnePage(PaintBox1.Canvas.Handle, PaintBox1.Canvas,iPageWidth,iPageHeight,iLeftMargin,iTopMargin,iRightMargin,iBottomMargin, nFooterMargin, true,iScale, iScale, sMainDir+'/Temp/'+IntToStr(iPageNumber)+'.tmp', iScale);
end;
打印时,用如下代码:
procedure Printting(OffsetLenght: Integer;
CannotMargin: TRect;
nPageNumber: Integer);
var
PageSize :TSize;
begin
//SetMapMode(Printer.Canvas.Handle, mm_Text);
//Printer.Title:= '房屋安全鉴定报告';
if Printer.Orientation=poPortrait then
if OffsetLenght<= iTopMargin then
begin
SetMapMode(Printer.Handle, MM_ISOTROPIC);
PageSize.cx := Printer.PageWidth;
PageSize.cy := Printer.PageHeight;
SetWindowExtEx(Printer.Handle, Printer.PageWidth, Printer.Pageheight, @PageSize);
SetViewPortExtEx(Printer.Handle, Printer.PageWidth, Printer.Pageheight, @PageSize);
DrawOnePage(Printer.Handle, Printer.Canvas,iPageWidth,iPageHeight,iLeftMargin,iTopMargin-OffsetLenght,iRightMargin,iBottomMargin+OffsetLenght,nFooterMargin+OffsetLength, false,PrinterPpiX,PrinterPpiY, sMainDir+'/Temp/'+IntToStr(nPageNumber)+'.tmp', iScale);
end else
Application.MessageBox('打印机偏移量大于上边距,打印错误!', szProgramTitle, MB_OK+MB_ICONERROR)
else
if OffsetLenght<= iLeftMargin then
begin
SetMapMode(Printer.Handle, MM_ISOTROPIC);
PageSize.cx := Printer.PageWidth;
PageSize.cy := Printer.PageHeight;
SetWindowExtEx(Printer.Handle, Printer.PageWidth, Printer.Pageheight, @PageSize);
SetViewPortExtEx(Printer.Handle, Printer.PageWidth, Printer.Pageheight, @PageSize);
DrawOnePage(Printer.Handle, Printer.Canvas,iPageWidth,iPageHeight,iLeftMargin-OffsetLenght,iTopMargin,iRightMargin+OffsetLenght,iBottomMargin, nFooterMargin, false,PrinterPpiY,PrinterPpiX, sMainDir+'/Temp/'+IntToStr(nPageNumber)+'.tmp', iScale);
end else
Application.MessageBox('打印机偏移量大于左边距,打印错误!', szProgramTitle, MB_OK+MB_ICONERROR);
end;
缩放时,用如下代码:
procedure TFrm_Preview.PaintBox1Click(Sender: TObject);
var
lpPoint : TPoint;
begin
GetCursorPos(lpPoint);
LockWindowUpdate(FRM_Preview.Handle);
//Application.ProcessMessages;
PaintBox1.Visible := false;
ScrollBox1.Visible:=false;
if iScale=100 then
begin
//iScale:=Round(190*iPageHeight/186);
iScale:=160;
//PaintBox1.picture := nil;
SetPreviewSize;
SetPreviewPpi;
PaintBox1.Left:= 0;
PaintBox1.Top:= 0;
Scrollbox1.HorzScrollBar.Range := PaintBox1.Width+10;
Scrollbox1.VertScrollBar.Range := PaintBox1.Height+10;
if lpPoint.x>= (Scrollbox1.width/2) then
Scrollbox1.HorzScrollBar.Position := Round(lpPoint.x * iScale/100-Scrollbox1.width/2)+2
else
Scrollbox1.HorzScrollBar.Position := Round(lpPoint.x * iScale/100-PaintBox1.Width)+2;
if lpPoint.y> Scrollbox1.Height/2 then
Scrollbox1.VertScrollBar.Position := Round(lpPoint.y * iScale/100-Scrollbox1.height/2)+2
else
Scrollbox1.VertScrollBar.Position := Round(Scrollbox1.height/2-lpPoint.y * iScale/100)+2
end else
begin
iScale:=100;
//image1.picture := nil;
SetPreviewSize;
SetPreviewPpi;
Scrollbox1.HorzScrollBar.Range := PaintBox1.Width;
Scrollbox1.VertScrollBar.Range := PaintBox1.Height;
Scrollbox1.HorzScrollBar.Position := 0;
Scrollbox1.VertScrollBar.Position := 0;
PaintBox1.Top:=5;
FRM_Preview.PaintBox1.Left:= (FRM_Preview.ScrollBox1.Width-FRM_Preview.PaintBox1.Width) div 2;
end;

//DrawOnePage(PaintBox1.Canvas.Handle, PaintBox1.Canvas,iPageWidth,iPageHeight,iLeftMargin,iTopMargin,iRightMargin,iBottomMargin, nFooterMargin, true,PrePpiX,PrePpiY, sMainDir+'/Temp/'+IntToStr(iPageNumber)+'.tmp', iScale);
PaintBox1.Visible := true;
ScrollBox1.Visible:=true;
LockWindowUpdate(0);
PostMessage(Handle, WM_ERASEBKGND, ClientHandle, 0);
end;

请问各位还有什么好的建议?
 
为什么在刚启动预览窗口,将paintbox1.height=Scrollbox1.height,相应的paintbox1.width按比例进行改变时,
左边的线条、文字显示不出来(其实paintbox 的小部分白板也没有显示,直接可看到scrollbox),为什么?
 
应重设paintbox1.picture.bitmap.width := NewWidth
 
建议你看看《Delphi开发人员指南》中图像那一章,看看窗口、视图的概念,你会觉的
缩放很简单的。
 
如果想将鼠标位置放大(或缩小),请问有什么好的算法?
 
对报表的缩放如果采用和处理图形一样的方法的话,在缩放比例不大的情况下还可以,
一旦范围过大,不作处理得话失真太大,没有太大的意义。只有按照矢量图的方式才可
能做平滑的无级缩放。
个人观点。
 
后退
顶部