Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сделать разбиение по строкам [D7, WinXP]


Urvin ©   (2005-03-07 19:17:00) 

Необходимо сделать из одной переменной типа string несколько строчек на канвасе, причем с разделением по словам.
Т.е. Нам задана максимальная ширина строки в пикселях, N. В одну строку могут помещаться несколько слов, если они достаточно короткие. Если слово длиннее заданной ширины строки, надо обрезать это слово по ширине строки, и остаток, если не слишком длинен напечатать на следующей строчке. Если он длинный, повторить обрезание..
Вот. Как бы это сделать? Желательно без всяких целомудренных функций...


easy   (2005-03-08 16:04:00) [1]

procedure TForm1.Button1Click(Sender: TObject);
var sourceStr: string;
   sourceStrLen: Integer;
   sz: TSIZE;
   max,th: Integer;
begin
 sourceStr:='Необходимо сделать из одной переменной типа string несколько'+
 ' строчек на канвасе, причем с разделением по словам.'+
 ' Т.е. Нам задана максимальная ширина строки в пикселях,'+
 ' N. В одну строку могут помещаться несколько слов, если они достаточно'+
 ' короткие. Если слово длиннее заданной ширины строки,'+
 ' надо обрезать это слово по ширине строки, и остаток, если не слишком'+
 ' длинен напечатать на следующей строчке. Если он длинный, повторить обрезание..'+
 ' Вот. Как бы это сделать? Желательно без всяких целомудренных функций...';
 sourceStrLen:=length(sourceStr);
 max:=0;
 th:=0;
 while sourceStrLen>max do begin
   GetTextExtentExPoint(Canvas.Handle, PChar(sourceStr),sourceStrLen,
     width-10,@max, nil,sz);
   canvas.TextOut(0,th,copy(sourceStr,1,max));
   delete(sourceStr,1,max);
   sourceStrLen:=length(sourceStr);
   inc(th,canvas.TextHeight(sourceStr));
 end;
 canvas.TextOut(0,th,sourceStr);
end;


??


Erik1   (2005-03-08 12:01:00) [2]

Вобщето есть API функции которые возвращают ширину слова на даном Canvas. А далее все расчитать элементарно.


Urvin   (2005-03-07 23:21:00) [3]

Низзя. Ща попробую в функцию расписать..


MU   (2005-03-07 22:37:00) [4]

или,там, в Word экспортнуть, в таблицу...


MU   (2005-03-07 22:08:00) [5]

8|
я сейчас, конечно, попробую разобраться...
но пока спрошу, а почему генератор отчетов не использовать?


Palladin   (2005-03-07 22:06:00) [6]

О боже. За такое убивают.
Я конечно понимаю ООП и ООА... но парни, не забывайте о главном принципе "разделяй и влавствуй", это основной принцип структурного программирования, и никуда он не делся и не денется.
А здесь. Где здесь влавтсвовать то? Это нагромождение над тобой властно, его трудно читать и, соотвессно, его трудно постигать. На хрена оно кому т нужно? В таком случае...


Urvin   (2005-03-07 21:55:00) [7]

Получается плохо, использую стронние элементы, но не суть важно:
procedure TfrmMain.actPrintExecute(Sender: TObject);
var i,j,ii,iii,jjj,isf: integer;
   n:integer;
   kx,ky,dy: integer;
   polex,poley: single;
   pwidth: array[0..12] of integer;
   pcontent: array[0..12] of string;
   nmax,nmaxall,cury,onrow,rowis,rows:integer;
   curstr,curword,currow:string;
   curchar: string[1];
const
   ptitles: array[0..12] of string = ( '№', 'Название', 'Клиент', 'Дата', 'Срок исполнения', 'Менеджер', 'Тираж', 'Формат', 'Цветность', 'Бумага', 'Особенности', 'Макет', 'Пленки');
begin
 n:=0;

 if lwTekush.SelCount<>0 then
   if prdPrint.Execute then begin
     Printer.Orientation:=poLandscape;

     polex:=0.1; poley:=0.1;
     kx:=round(Printer.PageWidth/29.7);
     ky:=round(Printer.PageHeight/21);

     dy:=Printer.Canvas.TextHeight('8)`_');

     ////////////////////////////////////////////////////////////
     for i:=0 to 12 do begin
       pwidth[i]:=Trunc((Printer.PageWidth - polex*2*kx)/13);
     end;
     ////////////////////////////////////////////////////////////

     Printer.Title:= 'Manager Vis-a-viS';
     Printer.BeginDoc;

     with printer.Canvas do begin
       n:=0;
       for i:=0 to 12 do begin
         Brush.Style:=bsSolid;
         Brush.Color:= $EEEEEE;
         Rectangle(Trunc(polex*kx+n),Trunc(poley*kx),Trunc(polex*kx+n+pwidth[i]),Trunc(poley*kx + dy));
         Brush.Style:=bsClear;
         TextOut(Trunc(polex*kx+n+(pwidth[i] - TextWidth(ptitles[i]))/2),Trunc(poley*ky),ptitles[i]);
         n:= n+pwidth[i];
       end;

       //##################################################

       rows:=1;

       for i:=0 to lwTekush.Items.Count-1 do begin
        if lwTekush.Items[i].Selected=true then begin
           ibqQuery.First;
           ibqQuery.MoveBy(StrToInt(lwTekush.Items[i].SubItems[6]));

           pcontent[ 0]:=ibqQuery.Fields[ 0].AsString;
           pcontent[ 1]:=ibqQuery.Fields[ 4].AsString;
           pcontent[ 2]:=ibqQuery.Fields[ 2].AsString;
           pcontent[ 3]:=ibqQuery.Fields[ 1].AsString;
           pcontent[ 4]:=ibqQuery.Fields[10].AsString;
           pcontent[ 5]:=ibqQuery.Fields[ 3].AsString;
           pcontent[ 6]:=ibqQuery.Fields[ 5].AsString;
           pcontent[ 7]:=ibqQuery.Fields[ 6].AsString;
           pcontent[ 8]:=ibqQuery.Fields[ 7].AsString;
           pcontent[ 9]:=ibqQuery.Fields[ 8].AsString;
           pcontent[10]:=ibqQuery.Fields[ 9].AsString;
           pcontent[11]:='';
           pcontent[12]:='';

           //##################################################################
           nmaxall:=0;
           for j:= 0 to 12 do begin
             {onrow:=0;curstr:='';
             while TextWidth(curstr)<=pwidth[j] do begin
               curstr:=curstr + 'W';
               onrow:=onrow+1;
             end;
              }
             nmax:=0; iii:=1;isf:=0;curstr:=''; currow:='';

             pcontent[j]:=StringReplace(pcontent[j],#10,'',[rfReplaceAll])+#13;

             {for ii:= 1 to length(pcontent[j]) do begin
               curstr:=curstr+copy(pcontent[j],ii,1);
               if copy(pcontent[j],ii,1)=#13 then nmax:=nmax+1;
               if (ii mod onrow) = 0 then begin
                 curstr:=curstr+#13;
                 nmax:=nmax+1;
               end;
             end; }

             for ii:= 1 to length(pcontent[j]) do begin
               curchar:=copy(pcontent[j],ii,1);
               case Ord(curchar[1]) of
                 13: begin
                   nmax:=nmax+1;
                   iii:=ii+1;
                   isf:=0;
                   curstr:=curstr+curchar;
                   currow:='';
                   nmax:=nmax+1;
                 end;

                 32: begin
                   curword:=Copy(pcontent[j],iii,ii-iii);
                   iii:=ii+1;
                   if TextWidth(currow + ' ' + curword) <= pwidth[j] then begin
                     currow:=currow+' '+curword;
                     isf:=1;

                   end
                   else begin
                     if isf=0 then begin
                       jjj:=0;
                       while textwidth(Copy(curword,1,jjj))<= pwidth[j] do begin
                         jjj:=jjj+1;
                       end;

                       currow:=Copy(curword,1,jjj-1);
                       curstr:=curstr+#13+currow;
                       currow:=Copy(curword,jjj,length(curword)-jjj+1);
                       nmax:=nmax+1;
                     end
                     else begin
                       curstr:=curstr+#13+currow;
                       currow:=curword;
                       nmax:=nmax+1;
                     end;
                   end;
                 end;
               end;
             end;

             pcontent[j]:=curstr;

             if nmax>nmaxall then nmaxall:=nmax;

           end;

           if rows*dy+nmaxall*dy+poley*ky > Printer.PageHeight-2*poley*ky-rowis*dy then begin
             rows:=1;
             printer.NewPage;

             n:=0;
             for ii:=0 to 12 do begin
               Brush.Style:=bsSolid;
               Brush.Color:= $EEEEEE;
               Rectangle(Trunc(polex*kx+n),Trunc(poley*kx),Trunc(polex*kx+n+pwidth[ii]),Trunc(poley*kx + dy));
               Brush.Style:=bsClear;
               TextOut(Trunc(polex*kx+n+(pwidth[ii] - TextWidth(ptitles[ii]))/2),Trunc(poley*ky),ptitles[ii]);
               n:= n+pwidth[ii];
             end;

           end;

           n:=0;
           Brush.Style:=bsClear;
           for j:= 0 to 12 do begin
             Rectangle(Trunc(polex*kx+n),Trunc(poley*kx+rows*dy),Trunc(polex*kx+n+pwidth[j]),Trunc(poley*kx + (rows+nmaxall)*dy));

             rowis:=0;

             iii:=1;
             
             for ii:= 1 to length(pcontent[j]) do begin
               if Copy(pcontent[j],ii,1)=#13 then begin
                 printer.Canvas.TextOut(Trunc(polex*kx+n),Trunc(rowis*dy+rows*dy+poley*ky),Copy(pcontent[j],iii,ii-iii));
                 iii:=ii+1;
                 rowis:=rowis+1;
               end;
             end;

             //printer.Canvas.TextOut(Trunc(polex*kx+n),Trunc(rowis*dy+rows*dy+poley*ky),pcontent[j]);

             n:= n+pwidth[j];
           end;

           rows:=rows+nmaxall;

           //##################################################################
         end;
       end;

     end;

     Printer.EndDoc;
   end;

end;


Palladin   (2005-03-07 21:46:00) [8]

Нюка нюка, чего ты там старался :)


Urvin   (2005-03-07 21:38:00) [9]

Да. Тка как ни делаю, все мимо... Вот и хотел попросить алгоритм.
Цели и средства уже давно знаю...


MU   (2005-03-07 21:38:00) [10]

покажите, как делаете


MU   (2005-03-07 20:07:00) [11]

Используй TCanvas.TextHeight и TCanvas.TextWidth
и TCanvas.TextOut.


Urvin   (2005-03-07 20:00:00) [12]

Ннне то. ТЬакое я уже видел, и не известно, насколько длинный получится столбец текста.
Желательно алгоритмом...


MU   (2005-03-07 19:25:00) [13]

Вот одна очень похотливая функция:

int DrawText(

   HDC hDC, // handle to device context
   LPCTSTR lpString, // pointer to string to draw
   int nCount, // string length, in characters
   LPRECT lpRect, // pointer to structure with formatting dimensions  
   UINT uFormat  // text-drawing flags
  );

и флаг DT_WORDBREAK


Наверх

Титульная страница Поиск, карта сайта Написать письмо