zoukankan      html  css  js  c++  java
  • FastReport 4.7 的两个BUG及修复方法

    现在做的一个项目,需要涉及到打印,所以选择了FASTREPORT。网上下的FOR DELPHI2009是有源代码的,用起来还是不错,我前面的BLOG中已经写了几个封装的功能,用了下还是比较爽的。

    但是发现几个问题。

    项目需要打印一个很大篇幅的文章,文章内容放在一个数据库的TEXT字段中,内容大小又不一样,大的可能需要用好几十页纸才能打完,小的可能只有几个字,并且每行打印的时候都要求要下划先,如果一行文字中间折行的,整行需要加下划线。

    效果如下:

    image

    用FASTREPORT设计还是比较简单的,直接把这个字段拖进来就好了,然后设置这个MemoView的StretchMode为smActualHeight,这样就可以打印多行了,然后设置UnderLines为True就可以打印的时候有下划线了。然后设置一下字体和LineSpacing就可以了。

    但是运行后发现两个问题:

    1.设置UnderLines属性后,最后一行的下划线有时候会打印出来,有时候又不打印。

    2.文章内容,如果超过一页,文章的最后一行也是有时候会打出来,有时候又打不出来。

    网上下了几个版本,都存在这个问题,并且官方网站也没有提起,没办法,只能自己去研究FASTREPORT的代码了。

    最开始认为这两个问题是同一个问题,经过分析发现是不同的两个BUG。

    先研究下划线问题。

    这个问题比较简单,先找到frxClass单元中的TfrxCustomMemoView的Draw方法,专门有一个函数DrawUnderlines;是用于划下划线的,中间有一段循环:

        dy := FY + h + (GapY - LineSpacing + 1) * ScaleY;
        while dy < FY1 do
        begin
          Canvas.MoveTo(FX, Round(dy));
          Canvas.LineTo(FX1, Round(dy));

    。。。。

    这个代码中循环的判断while dy < FY1 do是有问题的。他并没有考虑最后一行的情况,修改如下:

        h := FDrawText.LineHeight * ScaleY;
        dy := FY + h + (GapY - LineSpacing + 1) * ScaleY;
        //hl changed  20090602
        while dy < (FY1 + Trunc(LineSpacing/2) ) do
    //    while dy < FY1 do
        begin
          Canvas.MoveTo(FX, Round(dy));
          Canvas.LineTo(FX1, Round(dy));

    OK,问题解决。

    最后一行有可能不打印的问题就麻烦了。要去研究整个FASTREPORT的运行机制。折腾到凌晨一点多,基本有点眉目了。

    原因在于计算行高的时候,没考虑到最后一行是不需要计算LineSpacing的情况。

    错误代码如下:

    function TfrxDrawText.GetOutBoundsText(var ParaBreak: Boolean): WideString;
    var
      PrnSz: Integer;
      n, vl, Ln: Integer;
      ratio: Extended;
      Tag: TfrxHTMLTags;
      cl: LongInt;
    begin
      ParaBreak := False;
      Result := '';
      n := FText.Count;
      if n = 0 then Exit;

      FCanvas.Lock;
      try
        PrnSz := -FCanvas.Font.Height;
        ratio := FDefPPI / FScrPPI;

      // number of lines that will fit in the bounds
        vl := Trunc((FOriginalRect.Bottom - FOriginalRect.Top + 1) / (PrnSz / ratio + FLineSpacing));--这里是有问题的

    修改为:

    function TfrxDrawText.GetOutBoundsText(var ParaBreak: Boolean): WideString;
    var
      PrnSz: Integer;
      n, vl, Ln: Integer;
      ratio: Extended;
      Tag: TfrxHTMLTags;
      cl: LongInt;
    begin
      ParaBreak := False;
      Result := '';
      n := FText.Count;
      if n = 0 then Exit;

      FCanvas.Lock;
      try
        PrnSz := -FCanvas.Font.Height;
        ratio := FDefPPI / FScrPPI;

      // number of lines that will fit in the bounds
        vl := Trunc((FOriginalRect.Bottom - FOriginalRect.Top + 1) / (PrnSz / ratio + FLineSpacing));
        //hl changed 20090603
        if ((FOriginalRect.Bottom - FOriginalRect.Top + 1) - vl * (PrnSz / ratio + FLineSpacing)) >= (PrnSz / ratio) then
          Inc(vl);

    然后再修改计算剩余高度的代码。修改方法同上。

    OK,问题解决。

  • 相关阅读:
    CAD2014启动出现loadlibrary failed with error 87
    MFC界面更新实现方法
    easyui tabs update后tab上关闭图标失效的解决方案
    SQLServer
    Socket异步存储示例
    AspNetPager控件分页使用方法
    sqlserver 2008 孤立用户解决方法
    NPOI 2.0 读取、编辑、保存Excel文件
    NPOI 2.0 创建Excel文件
    jQuery.extend 函数详解
  • 原文地址:https://www.cnblogs.com/barryhong/p/1495723.html
Copyright © 2011-2022 走看看