![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по установке размеров страницы при печати
дикий © (2012-01-25 10:43:00)Возможно ли установить свои размеры страницы для принтера и нарисовав на ней что-нибудь напечатать без использования TPrintDialog?
Т.е. установили
procedure some(Width, Height: SmallInt);
var
Device, Driver, Port: array [0 .. 255] of char;
hDMode: THandle;
DevMode: PDeviceMode;
begin
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then begin
DevMode := GlobalLock(hDMode);
if DevMode <> nil then begin
DevMode^.dmFields := DevMode.dmFields or DM_PAPERSIZE or DM_PAPERWIDTH or DM_PAPERLENGTH;
DevMode^.dmPaperSize := DMPAPER_USER;
DevMode^.dmPaperWidth := Width;
DevMode^.dmPaperLength := Height;
Printer.setPrinter(Device, Driver, Port, hDMode);
GlobalUnlock(hDMode);
end;
end;
end;
Затем в другом месте программы прочитали
Phdc := Printer.Handle;
PageWidth := GetDeviceCaps(Phdc, HORZSIZE);
PageHeight := GetDeviceCaps(Phdc, VERTSIZE);
И напечатали
Printer.Canvas.Width = PageWidth = Width
PageWidth и Width из примеров выше
Dimka Maslov (2012-01-25 16:03:00) [1]Кстати, первый пост работать не будет, ибо Printer.GetPrinter выдаём совсем не DeviceMode, а некоторый, зависящий от драйвера принтера массив данных, определяющий состояние его настройки, а Printer.SetPrinter ни разу не принимает DeviceMode.
Dimka Maslov (2012-01-25 15:44:00) [2]Ещё есть в плоттерах функции автоповорота и автообрезки, позволяющие один раз задать в настройках размер ширина_рулона × 100500 и в дальнейшем не заморачиваться с фактическим размером.
дикий (2012-01-25 14:57:00) [3]
> Dimka Maslov © (25.01.12 12:41) [3]
> Идём в настройки плоттера, там задаём пользовательский размер и печатаем.
некошерно =(
Длина документа всегда разная, от полуметра до нескольких. Да и ширина тоже, но не больше А0
Меня устроили два варианта:
procedure setPageSize1(Width, Height: SmallInt);
var
HPrinter: THandle;
InfoSize, BytesNeeded: Cardinal;
DevMode: PDeviceMode;
PI2: PPrinterInfo2;
PrinterDefaults: TPrinterDefaults;
begin
with PrinterDefaults do begin
DesiredAccess := PRINTER_ACCESS_USE;
pDatatype := nil;
PDEVMODE := nil;
end;
if OpenPrinter(PWideChar(Name), HPrinter, @PrinterDefaults) then begin
try
SetLastError(0);
if not GetPrinter(HPrinter, 2, nil, 0, @BytesNeeded) then begin
PI2 := AllocMem(BytesNeeded);
try
InfoSize := SizeOf(TPrinterInfo2);
if GetPrinter(HPrinter, 2, PI2, BytesNeeded, @BytesNeeded) then begin
DevMode := PI2.PDEVMODE;
DevMode.dmFields := DevMode.dmFields or DM_PAPERSIZE or DM_PAPERWIDTH or DM_PAPERLENGTH;
DevMode.dmPaperSize := DMPAPER_USER;
DevMode.dmPaperWidth := Width;
DevMode.dmPaperLength := Height;
PI2.pSecurityDescriptor := nil;
if DocumentProperties(0, HPrinter, PWideChar(Name), PI2.PDEVMODE^, PI2.PDEVMODE^,
DM_IN_BUFFER or DM_OUT_BUFFER) = IDOK then begin
setPrinter(HPrinter, 2, PI2, 0);
end;
end;
finally
FreeMem(PI2, BytesNeeded);
end;
end;
finally
ClosePrinter(HPrinter);
end;
end;
end;
и второй
procedure setPageSize2(Width, Height: SmallInt);
Var
HPrinter: LongWORD;
pDATA: Pointer;
nRequired: PDWORD;
prnDefaults: TPrinterDefaults;
begin
with prnDefaults do begin
pDatatype := Nil;
PDEVMODE := Nil;
DesiredAccess := PRINTER_ALL_ACCESS;
end;
OpenPrinter(PChar(Printer.Printers[Printer.PrinterIndex]), HPrinter, @prnDefaults);
New(nRequired);
GetPrinter(HPrinter, 2, Nil, 0, nRequired);
GetMem(pDATA, nRequired^);
try
if GetPrinter(HPrinter, 2, pDATA, nRequired^, nRequired) then begin
with PRINTER_INFO_2(pDATA^).PDEVMODE^ do begin
PRINTER_INFO_2(pDATA^).pSecurityDescriptor := Nil;
dmFields := dmFields OR DM_PAPERSIZE OR DM_PAPERLENGTH OR DM_PAPERWIDTH;
dmPaperSize := 0;
dmPaperLength := Height;
dmPaperWidth := Width;
end;
if not setPrinter(HPrinter, 2, pDATA, 0) then
raise EAbort.Create(SysErrorMessage(GEtLastError));
end
else
raise EAbort.Create('GetPrinter 2 fails: ' + SysErrorMessage(GEtLastError));
finally
FreeMem(pDATA);
Dispose(nRequired);
end;
end;
Оба устанавливают нужные значения. Только второй почему-то не работает с параметром DMPAPER_USER для dmPaperSize, ему обязательно нужен 0.
А вот тот, что в первом посте никак не хочет работать =(
Dimka Maslov (2012-01-25 12:41:00) [4]Ну так и всё. Идём в настройки плоттера, там задаём пользовательский размер и печатаем.
А кроме того, содержимое DevMode можно сохранять и восстанавливать при следующем запуске программы, если особенно лениво каждый раз делать настройку через TPrintDialog.
дикий (2012-01-25 12:32:00) [5]
> Dimka Maslov © (25.01.12 11:49) [1]
> но работать это будет только при рулонной подаче.
Мне так и надо.
У меня плоттер, на который надо послать три с половиной метра.
Dimka Maslov (2012-01-25 11:49:00) [6]TPrintDialog есть надстройка над GetPrinter и SetPrinter. Следовательно, можно в одном месте программы сделать SetPrinter, а в другом GetPrinter. Свои размеры можно задать в системных настройках принтера, но работать это будет только при рулонной подаче.