转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
关于中文折行及相关问题的解决方法 (taogou)         ★★★★

关于中文折行及相关问题的解决方法 (taogou)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1228 更新时间:2009/4/23 18:38:57

打印中一些问题的解决方法 (taogou)
以下quickrpt版本都为3.6


关于自动折行 
需求:将超过长度的文本自动折行
解决方法:根据DELPHI的判断函数来控制超过长度文本的取舍,其实它本身有判断并截取中文字符的功能,
但是只取了第一行,所以就没有折行的效果。
源码:文件 QRCtrls;函数 FormatLines;子函数AddWord

procedure AddWord(aWord : string);
{$ifdef ver100}
  var
    S: string;
{$endif}
  begin
    while aLineWidth(NewLine + aWord) > Width do   //字符长度超过指定长度
    begin
      if NewLine = '''''''' then
      begin
{$ifdef ver100}   //版本控制 似乎只分了{$ifdef VER36} 和这个。
        if SysLocale.FarEast then
        begin
          while true do
          begin
            if (aWord[1] in LeadBytes) and (Length(aWord) > 1) then
              S := copy(aWord, 1, 2)
            else
              S := copy(aWord, 1, 1);

            if aLineWidth(NewLine + S) < Width then
            begin
              NewLine := NewLine + S;
              Delete(aWord, 1, Length(S));
            end
            else
              Break;
          end;
        end
        else
          while aLineWidth(NewLine + copy(aWord, 1, 1)) < Width do
          begin
            NewLine := NewLine + copy(aWord, 1, 1);
            Delete(aWord, 1, 1);
          end;
{$else}
        while aLineWidth(NewLine + copy(aWord, 1, 1)) <= Width do
        begin
          if ByteType(aWord, Length(aWord)) = mbTrailByte then  //如果是是双字节字符,则截两位
                  //如果截的是双字节字符而长度恰好又超过了指定长度,
                        //系统默认将指定长度扩展一位。如果不愿意,当然这里也可以自己再加入控制       
          begin 
            NewLine:=NewLine +copy(aWord,1,2); 
            Delete(aWord, 1, 2);
          end else
          begin
            NewLine := NewLine + copy(aWord, 1, 1);
            Delete(aWord, 1, 1);
          end;
        end;
{$endif}
//taogou        aWord := '''''''';  //该句的赋值就将导致不能换行
      end;
      FlushLine;     //将截取的指定长度的字符加入到字符串列表中
{      if aLineWidth(aWord) > Width then     
      begin
        if NewLine = '''''''' then
        begin
          if Width = 0 then
            aWord := ''''''''
          else
            while aLineWidth(aWord) > Width do
{$ifdef ver100}
 {             if ByteType(aWord, Length(aWord)) = mbTrailByte then
                Delete(aWord, Length(aWord)-1, 2)
              else}
//{$endif}
{              begin
                Delete(aWord, Length(aWord), 1);
              end;
        end;
        NewLine := aWord;
        FlushLine;
        aWord := '''''''';
      end;}
      if not WordWrap then
      begin
        aWord := '''''''';
        LineFinished := true;
      end;
    end;
    NewLine := NewLine + aWord;
  end;


关于自动折行所引起的页行数可变控制

需求:文本折行后,是已设格式的行高自动变化,行数不容易控制,预览效果不堪入目。
解决方法:不允许已设行高自动变化,根据detail行高取舍文本的行数。例:不折行的情况下打印5行的固定
格式,会因为折行而打不了5行,程序自动将行高增大,在套打的情况下,情况非常糟糕。所以强制固定行高,
如果折行超过了固定高度,则超出部分不打印。

源码:文件 QRCtrls;主函数 PrintToCanvas;子函数CanPrint

找到下面着一行
 TQRCustomBand(Parent).ExpandBand(LineHeight, AFExpanded, HasExpanded); 
该行是根据你的CAPTION的行数来增加行数的,所以屏蔽掉
 在主函数中找到下面这一行
  ControlBottom := aTop + aHeight +1;
修改为
  ControlBottom := aTop + TQRCustomBand(Parent).size.Length +1;
 TQRCustomBand(Parent).size.Length 是当前DETAIL的行高

 然后找到下面这个循环
  while (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint do 
  if (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint  then
  begin
    PrintLine(FCurrentLine);
    inc(FCurrentLine);
  end;
  修改为
  while (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint do  //taogou
  if (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint  then
  begin
    if Y + LineHeight < ControlBottom then //taogou Y为当前开始打印的位置,lineHeight为字符行高
      PrintLine(FCurrentLine); //controlbottom为detail的下限位置,仅当位置小于允许的位置才打印  
    inc(FCurrentLine);
  end;
  FCurrentLine:=FFormattedLines.Count;  //不管打了几行,都将当前行表示为该caption已经打印完毕


需求:控制多余行数,例:页打印行数为5行,当前打印记录数为12,带格式不套打,
则在最后页只有2行数据,从第3行到页脚为一片空白。这里需要将最后一页上3行打印上无数据的空格式.
解决方法:循环N次detail行的打印方法,并屏蔽掉记录

源码:文件 QuickRpt;主函数 TQRController.Execute


      HasPrintedLines:=0;  //新增本函数局部变量  记录已经打印的行数
      while MoreData do
      begin
        inc(HasPrintedLines);  //增1
        Application.ProcessMessages;
        if ParentReport.QRPrinter.Cancelled then
          Exit;
        if ParentReport.PreparingDesignTime and (ParentReport.FPageCount > 1) then Exit;
        inc(FDetailNumber);
        PrintGroupHeaders;
        PrintBeforeControllers;
        ParentReport.PrintBand(FDetail);
        PrintAfterControllers;
        if DSOK then
        begin
          DataSet.Next;
          MoreData := not FDataSet.Eof;
          if (FDataSet.Eof)  then       //Add begin
          begin
            if FDetail<>nil then      //将detail中的TQRDBText and TQRLabel 全部不打
            for j:=0 to FDetail.ControlCount-1 do
            begin
              if  FDetail.Controls[j] is TQRDBText then
                TQRDBText(FDetail.Controls[j]).Enabled:=False;
              if FDetail.Controls[j] is TQRLabel then
   &n

[1] [2]  下一页


[Sql Server]Sql精妙语句--各种求值函数  [网页制作]网页表格之---多个表格纵向排列
[网页制作]JavaScript另类用法--读取和写入cookie  [网页制作]号称非常安全的上网工具---360安全浏览器介绍
[办公软件]信息技术教学篇---Word工具栏的显示、隐藏及四种菜…  [操作系统]开始菜单---运行命令大总结
[操作系统]网络转载---64位操作系统与32位的区别  [操作系统]ldap:///(没有响应)Windows无法访问指定设备、路径…
[网络技术]安全篇---交换机设置方法介绍  [聊天工具]Real10 & Xpdf installation on Linux Box
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台