![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сделать разбиение по строкам [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