国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

關于中文折行及相關問題的解決方法

2019-11-18 18:37:59
字體:
來源:轉載
供稿:網友
 

打印中一些問題的解決方法 (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,本次東東就東到這里,同志們,好東西拿出來共享吧


上一篇:字幕圖標控件

下一篇:利用內存映射文件擴充程序可用的內存

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 永安市| 嘉义县| 淮北市| 项城市| 河南省| 马公市| 两当县| 彭水| 铜梁县| 扎赉特旗| 拉孜县| 通辽市| 甘肃省| 青冈县| 湖南省| 遵义县| 梧州市| 汕头市| 平远县| 宜丰县| 页游| 泸定县| 光泽县| 武乡县| 南投市| 丹江口市| 东乡族自治县| 阿尔山市| 徐汇区| 高要市| 黄骅市| 富阳市| 荣成市| 罗江县| 巴南区| 全南县| 定结县| 涞水县| 清流县| 丽水市| 阿克陶县|