小弟用FastReport 做报表,但是在打印中文时,在换行的时行,经常会出现一个汉字被分成两半的现象,因而出现乱码.主要是打中文时,打印框的长度可能会出现只能下半个汉字的部题. 还请帮忙. 出出主意啊!

解决方案 »

  1.   

    在Fr_Class单元,找到如下代码,按着改下试试
    procedure TfrMemoView.WrapMemo;
    var
      size, size1, maxwidth: Integer;
      b: TWordBreaks;
      WCanvas: TCanvas;  procedure OutLine(const str: String);
      begin
        SMemo.Add(str);
        Inc(size, size1);
      end;  procedure WrapLine(const s: String);
      var
        i, cur, beg, last, LoopPos: Integer;
        WasBreak, CRLF: Boolean;
        cl: Integer;  // 解决汉字折行问题,By Rocky
      begin
        CRLF := False;
        LoopPos := 0;
        for i := 1 to Length(s) do
          if s[i] in [#10, #13] then
          begin
            CRLF := True;
            break;
          end;
        last := 1; beg := 1;    if not CRLF and ((Length(s) <= 1) or (WCanvas.TextWidth(s) <= maxwidth)) then
          OutLine(s + #1)
        else
        begin
          cur := 1;
          while cur <= Length(s) do
          begin
            if s[cur] in [#10, #13] then
            begin
              OutLine(Copy(s, beg, cur - beg) + #1);
              while (cur < Length(s)) and (s[cur] in [#10, #13]) do Inc(cur);
              beg := cur; last := beg;
              if s[cur] in [#13, #10] then
                Exit else
                continue;
            end;
            if s[cur] <> ' ' then
            begin
              { 添加如下代码补丁,解决中文折行问题, by Rocky }
              if ByteType(s, cur) = mbLeadByte then                   // 如果是汉字的第一字节
                cl := WCanvas.TextWidth(Copy(s, beg, cur - beg + 2))  // 考虑整个汉字
              else
                cl := WCanvas.TextWidth(Copy(s, beg, cur - beg + 1));
              // End of Rocky's Code
              // if WCanvas.TextWidth(Copy(s, beg, cur - beg + 1)) > maxwidth then  // 这是原来的代码,By Rocky
              if cl > maxwidth then
              begin
                WasBreak := False;
                if (Flags and flWordBreak) <> 0 then
                begin
                  i := cur;
                  while (i <= Length(s)) and not (s[i] in spaces) do
                    Inc(i);
                  b := BreakWord(Copy(s, last + 1, i - last - 1));
                  if Length(b) > 0 then
                  begin
                    i := 1;
                    cur := last;
                    while (i <= Length(b)) and
                      (WCanvas.TextWidth(Copy(s, beg, last - beg + 1 + Ord(b[i])) + '-') <= maxwidth) do
                    begin
                      WasBreak := True;
                      cur := last + Ord(b[i]);
                      Inc(i);
                    end;
                    last := cur;
                  end;
                end
                else
                  if last = beg then last := cur;
                if WasBreak then
                  OutLine(Copy(s, beg, last - beg + 1) + '-')
                else if s[last] = ' ' then
                  OutLine(Copy(s, beg, last - beg))
                { 添加如下代码补丁,解决中文折行问题, by Rocky }
                else if ByteType(s,last) = mbLeadByte then   //判断是否是汉字字节
                  OutLine(Copy(s, beg, last - beg))
                // 代码补丁到此
                else begin
                  OutLine(Copy(s, beg, last - beg));
                  Dec(last);
                end;
                if ((Flags and flWordBreak) <> 0) and not WasBreak and (last = cur - 1) then
                  if LoopPos = cur then
                  begin
                    beg := cur + 1;
                    cur := Length(s);
                    break;
                  end
                  else
                    LoopPos := cur;
                //beg := last + 1; last := beg;   // 这是原来的代码
                { 添加如下代码补丁,解决中文折行问题, by Rocky }
                if ByteType(s, last) = mbLeadByte then
                  beg := last   // last = beg
                else begin
                  beg := last + 1;
                  last := beg;
                end;
                // 代码补丁到此
              end;
            end;
            
    //        if s[cur] in spaces then last := cur;
            if s[cur] = ' ' then last := cur;
            Inc(cur);        { 添加如下代码补丁,解决中文折行问题, by Rocky }
            if ByteType(s, cur) = mbTrailByte then Inc(cur);
            // End of Rocky's code
          end;
          if beg <> cur then OutLine(Copy(s, beg, cur - beg + 1) + #1);
        end;
      end;  procedure OutMemo;
      var
        i: Integer;
      begin
        size := y + gapy;
        size1 := -WCanvas.Font.Height + LineSpacing;
        maxwidth := dx - gapx - gapx;    if (DocMode = dmDesigning) and (Memo1.Count = 1) and
           (WCanvas.TextWidth(Memo1[0]) > maxwidth) and
           (Memo1[0] <> '') and (Memo1[0][1] = '[') then
          OutLine(Memo1[0])
        else
          for i := 0 to Memo1.Count - 1 do
            if FWrapped then
              OutLine(Memo1[i])
            else
              if (Flags and flWordWrap) <> 0 then
                WrapLine(Memo1[i]) else
                OutLine(Memo1[i] + #1);
        VHeight := size - y + gapy;
        TextHeight := size1;
      end;  procedure OutMemo90;
      var
        i: Integer;
        h, oldh: HFont;
      begin
        h := Create90Font(WCanvas.Font);
        oldh := SelectObject(WCanvas.Handle, h);
        size := x + gapx;
        size1 := -WCanvas.Font.Height + LineSpacing;
        maxwidth := dy - gapy - gapy;
        for i := 0 to Memo1.Count - 1 do
          if FWrapped then
            OutLine(Memo1[i])
          else
            if (Flags and flWordWrap) <> 0 then
              WrapLine(Memo1[i]) else
              OutLine(Memo1[i]);
        SelectObject(WCanvas.Handle, oldh);
        DeleteObject(h);    VHeight := size - x + gapx;
        TextHeight := size1;
      end;begin
      WCanvas := TempBmp.Canvas;
      WCanvas.Font.Assign(Font);
      WCanvas.Font.Height := -Round(Font.Size * 96 / 72);
      SetTextCharacterExtra(WCanvas.Handle, CharacterSpacing);
      SMemo.Clear;
      if (Alignment and $4) <> 0 then OutMemo90 else OutMemo;
    end;