电信主站 网通分站
购买流程 付款方式 常见问题 在线提问 续租服务 购物车
用户名: 密 码: 忘记密码?
首 页
域名注册
虚拟主机
双线主机
服务器租用
VPS主机
企业邮局
代理专区
客服中心
虚拟主机行业资讯 虚拟主机评测对比 互联网最新动态 技术学院 站长资讯 在线教程 网站运营
搜索优化 服务器 网络编程 图形图象 站长之家 网页制作 操作系统
冲浪宝典 软件教学 视频通信 办公软件 邮件系统 网络安全 认证考试
您当前位置:西部数码->资讯中心-> 网络编程 -> Delphi教程
关于中文折行及相关问题的解决方法_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.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
相关主题
文章页数:[1] 
Google
热门文章
·如何在启动机器时自动运行adsl拨号(1)_delphi教程
·delphi的通配符比较(第五版)_delphi教程
·delphi托盘编程实战演练_delphi教程
·关于中文折行及相关问题的解决方法_delphi教程
·字幕图标控件_delphi教程
·一个很简单的加密算法_delphi教程
·winapi编程关闭qq登录窗体_delphi教程
·组件开发方式_delphi教程
·用ehlib二次开发报表打印程序,实现财务凭证的打印(三)_delphi教程
·delphi+汇编例子1(求和的比较)_delphi教程

最新文章
·阻止windwos xp系统蓝屏的几大绝招_windows xp
·photoshop极坐标滤镜巧绘三维游泳圈_photoshop教程
·photoshop将美女照片转为手绘效果_photoshop教程
·zend studio5.5测试版 兼容三系统_php文摘
·photoshop调整图片对比度方法浅析_photoshop教程
·一个设置任意窗口透明度的命令行delphi程序_delphi教程
·photoshop基础教程:跟我学调色练习3-润色_photoshop教程
·windows xp空间:文件的属性也玩“花样”_windows xp
·轻松清理windows xp系统垃圾_windows xp
·配景的使用与创建_autocad教程


 
 


版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
  打印  刷新  关闭
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 虚拟主机 | 资讯中心 | 友情链接 | 网站地图

版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2006 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86262244 86263048 86263408 86263960 86264018 86267838
售前咨询:总机转201 202 203 204 206 208
售后服务:总机转211 212 213 214
财务咨询:总机转224 223 传真:028-86264041 财务QQ:点击发送消息给对方635483282
售前咨询QQ:点击发送消息给对方2182518 点击发送消息给对方241975952 点击发送消息给对方275026793 点击发送消息给对方408235859
售后服务QQ:点击发送消息给对方17708515 点击发送消息给对方307742704 点击发送消息给对方287976517 点击发送消息给对方363783715
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号