首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 软件教学-> 办公软件
关于中文折行及相关问题的解决方法_delphi教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
 

打印中一些问题的解决方法 (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
                TQRLabel(FDetail.Controls[j]).Caption:=;
            end;
            for j:=1 to FPageMaxLines*ParentReport.PageNumber-HasPrintedLines  do 
            //  FPageMaxLines 页最大打印行数,外部传进来的变量 
     //ParentReport.PageNumber  总共打印的页数,因为只对最后一页进行控制,
             //所以当前的打印页数已经确定,可以直接取
            begin       
              Application.ProcessMessages;  //begin   1
              if ParentReport.QRPrinter.Cancelled then Exit;
              PrintGroupHeaders;
              PrintBeforeControllers;
              if assigned(FDetail) then FDetail.MakeSpace;
              NotifyClients(qrMasterDataAdvance);
              ParentReport.PrintBand(FDetail);  
              PrintAfterControllers;    //end  1 
              //从begin 1到这里的函数是直接COPY自2.0版本上的打印(此处应该有更加好的解决方法,
              //偶只是懒了一下,:)  )  其实这段用在2.0中也是没有问题DI
            end;  //Add end
          end

        end else
        begin
          MoreData := false;
          if assigned(FOnNeedDataEvent) and not (csDesigning in ComponentState) then
            OnNeedData(SelfCheck, MoreData);
        end;
        if CheckGroups then
          begin
            if DSOK then
              DataSet.Prior;
            PrintGroupFooters;
            if DSOK then
              DataSet.Next;
        end;
        if ParentReport is TQuickRep and
          DSOK and  (TQuickRep(ParentReport).DataSet = DataSet) and (RecCount <> 0) then
            ParentReport.QRPrinter.Progress := (Longint(DetailNumber) * 100) div RecCount;
      end;


注:第一次写这样的东东和大家共享,感觉有点力不从心。原因?太明显了,1、不知道格式该怎么定义
2、不知道怎么写注解  3、我的文笔又很懒   4、不知道MM是否在想我呢???:)

OK,本次东东就东到这里,同志们,好东西拿出来共享吧


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·ASP.NET2.0连接SQL Server数据库详解-.NET教程,Asp.Net开发
·在.net中轻松掌握Windows窗体间的数据交互-.NET教程,.NET Framework
·Java中的类反射机制-JSP教程,Java技巧及代码
·小技巧让pdf文件与word文档之间自由地转换
·j2ee程序员应该掌握的linux知识-JSP教程,J2EE/EJB/服务器
·通过WMI获得硬盘和CPU的物理序列号(VB.net)-.NET教程,VB.Net语言
·firfox浏览器开发人公开firfox2.0开发计划
·VB.net入门(10):补充:类~属性-.NET教程,VB.Net语言
·office2003实战秘笈之excel轻松制胜招
·C#编码规范.doc-.NET教程,C#语言
最新文章
·天涯试水网络口碑营销 邢明:希望与"关键词"媲美_站长访谈
·美梨网站长冰寒的商务之道_站长访谈
·白手起家 新网站流量快速提高之道_站长心得
·照片处理 photoshop简单制作照片柔光效果_photoshop教程
·网络百戒 ---网页外观_站长心得
·utf-8转换gb2312编码,解决统计google搜索来源关键字乱_google推广
·googleadsense作弊不是技术的较量_google推广
·google改进搜索服务 企业可在local更新资料_google推广
·rss订阅对你的网站搜索表现有好处吗?_站长心得
·15种简洁有效的网站推广方法_站长心得
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭