![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
печать [D7, WinXP]
Dmitry_177 © (2007-05-11 23:52:00)Как задать объекту Printer: TPrinter; ширину и высоту страницы, число копий да и сам выбранный принтер в PrintDialog1? Правильно ли вообще так будет?
uses
Printers
procedure TForm1.Button1Click(Sender: TObject);
var
Printer: TPrinter;
begin
if PrintDialog1.Execute then
try
Printer := TPrinter.Create;
Printer.Copies := PrintDialog1.Copies;
Printer.PageHeight := // незнаю что тут писать из PrintDialog1
finally
Printer.Free;
end;
end;
{RASkov} (2007-05-15 22:50:00) [1]> [30] Dmitry_177 (15.05.07 22:36)
> Честно говоря не ожидал как-то это-то..
Разрешение монитора и принтера разные, вот отсюда и нестыковка;) экономист :)
Dmitry_177 (2007-05-15 22:36:00) [2]Я только что разобрался.. я перед тем как печатать смотрел в предварительном просмотре(в программе для принтера) что из этого получится, чтобы не тратить бумаги, так вот в этом предварительном просмотре нерисовывается последняя буква, а вот сам принтер печатает все ОК =) Честно говоря не ожидал как-то это-то..
{RASkov} (2007-05-15 22:12:00) [3]> [28] Dmitry_177 (15.05.07 20:46)
Покажи свой код....
Dmitry_177 (2007-05-15 20:46:00) [4]может немного не так выразился, последнее слово в строках обрезаются на букву или на пол буквы.. это если последнее слово в строке очень близко расположено к правому краю..
Dmitry_177 (2007-05-15 20:41:00) [5]как то странно, у меня DrawText с флагом DT_WORDBREAK(без всяких других) почему-то немного недорисовывает строки, т.е. половина или целая последняя буква в строках не прорисовывается, если слово впритык влазиет в ширину..
{RASkov} (2007-05-13 02:35:00) [6]> DrawText в этом плане в полную тебе не поможет,
Хотя... как раз она может и поможет :)
Вот посмотри:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetLongStr: String;
var N: Integer;
begin
for N:= 0 to 50 do Result:=Result+'Длинная строка - много слов ';
end;
function DivStr(var S: String; R: TRect): String;
begin
InflateRect(R, -4, -4);
Result:=Copy(S, 1, Length(S));
DrawText(Form1.Canvas.Handle, PChar(S), -1, R, DT_WORDBREAK or DT_MODIFYSTRING or DT_EDITCONTROL or DT_END_ELLIPSIS);
S:=StrPas(PChar(S));
if Length(Result)>=(Length(S)+3) then Delete(Result, 1, Length(S)-3) else Result:='';
end;
procedure TForm1.Button1Click(Sender: TObject);
procedure ModifRect(var R: TRect);
var W, H: Integer;
begin
W:=R.Right-R.Left; H:=R.Bottom-R.Top;
if (R.Right+W>ClientWidth-10) then begin
INC(R.Top, H+10);
R.Bottom:=R.Top+H;
R.Left:=10;
R.Right:=130;
end else begin
INC(R.Left, W+10);
R.Right:=R.Left+W;
end;
end;
var PS: String; R: TRect;
begin
PS:=GetLongStr;
R:=Rect(10, 35, 130, 230);
Canvas.Brush.Style:=bsSolid;
Canvas.Brush.Color:=Color;
Canvas.FillRect(Canvas.ClipRect);
repeat
Canvas.Brush.Style:=bsSolid;
Canvas.Brush.Color:=clWhite;
Canvas.Rectangle(R);
Canvas.Brush.Style:=bsClear;
PS:=DivStr(PS, R);
ModifRect(R);
until PS='';
end;
end.
Может и не так красиво, чисто для примера....
{RASkov} (2007-05-13 00:35:00) [7]> [23] Dmitry_177 (13.05.07 00:05)
DrawText в этом плане в полную тебе не поможет, либо разбивай такую строку на две(три,...), либо начинай всю строку на новой странице....
С новой строки проще начать(но... см дальше в предложении), а если хочешь разбивать, то тут нужно придумать алгоритм, который будет вычислять сколько теста поместится в заданном Rect'е и возвратить текст в двух частях(который поместился и который остался) и тоже самое проделать с остатком(т.к. остаток тоже может быть больше всей страницы, :) что будет косяком если переносить на новую страницу :)
Еще вот этот пример посмотри на вский случай:
procedure TForm1.Button1Click(Sender: TObject);
var S: String; N: Integer; R: Trect;
begin
for N:= 0 to 50 do S:=S+''Длинная строка - много слов ';
Canvas.Pen.Width:=2;
R:=Canvas.ClipRect; Canvas.FillRect(R); Canvas.Brush.Style:=bsClear;
Canvas.Pen.Color:=clBlue; Canvas.Rectangle(R);
INC(R.Left, 4); INC(R.Top, 4);
N:=DrawText(Canvas.Handle, PChar(S), -1, R, DT_CALCRECT or DT_WORDBREAK); //изменяем/рассчитываем перемен. R без вывода текста
Canvas.Pen.Color:=clRed; Canvas.Rectangle(R);
DrawText(Canvas.Handle, PChar(S), -1, R, DT_WORDBREAK);
R:=Canvas.ClipRect; INC(R.Top, N+30); INC(R.Left, 4); DEC(R.Right, 4); DEC(R.Bottom, 4);
Canvas.Pen.Color:=clGreen; Canvas.Rectangle(R);
DrawText(Canvas.Handle, PChar(S), -1, R, DT_WORDBREAK);
end;
Dmitry_177 (2007-05-13 00:15:00) [8]вобщем мне нужно так что если длинная строка, она распечатываламь в несколько строк и так что если дошел конец страницы, то печать продо жалась на новой странице..
Dmitry_177 (2007-05-13 00:05:00) [9]вобщем мне нужно так что если длинная строка, она распечатываламь в несколько строк и так что если дошел конец страницы, то печать продо жалась на новой странице..
{RASkov} (2007-05-12 21:32:00) [10]> [21] Dmitry_177 (12.05.07 21:10)
>мне не надо как раз точки вставлять..
С учетом
> [14] Dmitry_177 (12.05.07 13:19)
> [17] Dmitry_177 (12.05.07 19:28)
> [19] Dmitry_177 (12.05.07 20:00)
Я не пойму что тебе надо :( Зачем тебе тогда DT_END[WORD]_ELLIPSIS ? См [15,16]
Dmitry_177 (2007-05-12 21:10:00) [11]мне не надо какраз точки вставлять..
{RASkov} (2007-05-12 20:53:00) [12]> [19] Dmitry_177 (12.05.07 20:00)
Для этого достаточно флага DT_END_ELLIPSIS текст, что не влезет в Rect, обрежется и в конец текста добавятся (...), без скобок.
Dmitry_177 (2007-05-12 20:00:00) [13]странно, у меня без ошибок все.. а про DT_WORD_ELLIPSIS я как понял это для того, чтобы если в поле prRect не влазиет весь текст, то сколько влазиет он выводит, а в строке strData остаются символы те которые были выведены, точнее вставляется нулевой символ к конце тех символов которые были выведены..
{RASkov} (2007-05-12 19:51:00) [14]> DT_WORD_ELLIPSIS
В справке D7 такой константы нет, хотя в модуле Windows определена константа DT_WORD_ELLIPSIS = $40000;
Код из [17] генерит ошибку. Я на канве формы пробывал...
Access violation at address 7C913088 in module 'ntdll.dll'. Write of address 00471BD0.
Dmitry_177 (2007-05-12 19:28:00) [15]Что-то ерунда какая-то... После выполнения функции с флагами:
DrawText(Printer.Canvas.Handle, PChar(strData), Length(strData), prRect, DT_WORDBREAK or DT_MODIFYSTRING or DT_WORD_ELLIPSIS);
никакой нулевой символ не вставляется в strData.. а сам текст уходит вниз за пределы prRect
{RASkov} (2007-05-12 15:28:00) [16]*DT_CALCRECT
{RASkov} (2007-05-12 15:24:00) [17]> [14] Dmitry_177 (12.05.07 13:19)
> а как тогда определять влезет ли он на текущую страницу
> или в противном случае нужно какую-то часть текста распечатать
> до конца текущей страницы, и остальную на новой?
> Попробовал создавать еще один Canvas
Не нужен еще один канвас, посмотри все параметры DrawText и вчасности DT_CALCKRECT (помоему правильно написал) вообщем с этим параметром идет расчет области вывода текста без его "рисования"....
Dmitry_177 (2007-05-12 13:19:00) [18]У меня опять небольшая загвоздка.. Функция DrawText возвращает то она высоту уже после того как выведет текст, а как тогда определять влезет ли он на текущую страницу или в противном случае нужно какую-то часть текста распечатать до конца текущей страницы, и остальную на новой?
Попробовал создавать еще один Canvas и на нем выводить и делать все расчеты, чтобы потом перенести его в Printer.Canvas, не знаю правильное ли решение или есть другое? Попробовал сделать так:
var
Canv: TCanvas;
begin
try
Canv := TCanvas.Create;
// рисуем-считаем..
finally
Canv.Free;
end;
end;
Но так у меня AV выскакивает..
Dmitry_177 (2007-05-12 03:56:00) [19]я уже разобрался.. действительно не подумал о том что переносится то по словам...=)
{RASkov} (2007-05-12 03:53:00) [20]> правым краем канвы
Т.е. у канвы краев нет.... в данном случае я хотел сказать правым краем формы. А точнее - Form1.Canvas.ClipRect.Right :^)