Форум: "Основная";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
Вниз
Программная смена размера бумаги Найти похожие ветки
← →
Borion © (2004-08-25 12:22) [0]У меня для печати используется пользовательский размер бумаги. Этот тип бумаги указан для принтера, как размер по умолчанию. Однако, при печати используется другой формат. Хотелось бы программно принудительно непосредственно перед печатью задать свой размер бумаги.
Смену принтера и проверку размера делаю так:
for i:= 0 to Printer.Printers.Count-1 do
begin
if (pos("Godex", Printer.Printers[i]) <> 0) or (pos("EZ", Printer.Printers[i]) <> 0) then
begin
Printer.PrinterIndex:= i;
ShowMessage("Текущий принтер " + Printer.Printers[Printer.PrinterIndex]);
ShowMessage("Текущая высота бумаги " + IntToStr(GetDeviceCaps(Printer.Handle, VertSize)) + " мм"+ #13#10 +
"Текущая ширина бумаги " + IntToStr(GetDeviceCaps(Printer.Handle, HorzSize)) + " мм");
//frPriceLabelReport.ChangePrinter(0, Printer.PrinterIndex);
break;
end; //if...
end; //for...
Хотелось бы сделать смену бумаги дельфовыми средствами, а не с помощью WinAPI. Хотя, если кто-нибудь смог бы привести подробный код на WinAPI, то и на это согласен:))
← →
Skier © (2004-08-25 12:28) [1]посмотри как "устроен" класс TPrinterSetupDialog
думаю там можно найти много полезного и "взять на вооружение"...
← →
Sergey Kaminski © (2004-08-25 12:48) [2]
procedure SetPaperSize(const Value: DWORD);
var
ADevice,ADriver,APort: array [0..255] of char;
DeviceHandle: THandle;
DevMode: PDeviceMode;
begin
{взято из Пачеко, т.1}
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
if DeviceHandle = 0 then
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
end;
if DeviceHandle = 0 then
Raise Exception.Create ("Error setting printer caps!")
else
DevMode := GlobalLock (DeviceHandle);
with DevMode^ do
begin
dmFields := dmFields or DM_PAPERSIZE;
DevMode^.dmPaperSize := Value
end;
Printer.SetPrinter(ADevice,ADriver,APort,DeviceHandle);
if not DeviceHandle = 0 then
GlobalUnlock (DeviceHandle);
{AdjustImageSize;}
end;
function GetPaperSize: DWORD;
var
ADevice,ADriver,APort: array [0..255] of char;
DeviceHandle: THandle;
DevMode: PDeviceMode;
begin
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
if DeviceHandle = 0 then
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
end;
if DeviceHandle = 0 then
Raise Exception.Create ("Error setting printer caps!")
else
DevMode := GlobalLock (DeviceHandle);
with DevMode^ do
begin
Result := DevMode^.dmPaperSize;
end;
if not DeviceHandle = 0 then
GlobalUnlock (DeviceHandle);
end;
Константы для задания стандартных размеров бумаги см. в Windows.pas:
DMPAPER_LETTER = 1; { Letter 8 12 x 11 in }
{$EXTERNALSYM DMPAPER_FIRST}
DMPAPER_FIRST = DMPAPER_LETTER;
{$EXTERNALSYM DMPAPER_LETTERSMALL}
DMPAPER_LETTERSMALL = 2; { Letter Small 8 12 x 11 in }
{$EXTERNALSYM DMPAPER_TABLOID}
DMPAPER_TABLOID = 3; { Tabloid 11 x 17 in }
{$EXTERNALSYM DMPAPER_LEDGER}
DMPAPER_LEDGER = 4; { Ledger 17 x 11 in }
{$EXTERNALSYM DMPAPER_LEGAL}
DMPAPER_LEGAL = 5; { Legal 8 12 x 14 in }
{$EXTERNALSYM DMPAPER_STATEMENT}
DMPAPER_STATEMENT = 6; { Statement 5 12 x 8 12 in }
{$EXTERNALSYM DMPAPER_EXECUTIVE}
DMPAPER_EXECUTIVE = 7; { Executive 7 14 x 10 12 in }
{$EXTERNALSYM DMPAPER_A3}
DMPAPER_A3 = 8; { A3 297 x 420 mm }
{$EXTERNALSYM DMPAPER_A4}
DMPAPER_A4 = 9; { A4 210 x 297 mm }
{$EXTERNALSYM DMPAPER_A4SMALL}
DMPAPER_A4SMALL = 10; { A4 Small 210 x 297 mm }
{$EXTERNALSYM DMPAPER_A5}
DMPAPER_A5 = 11; { A5 148 x 210 mm }
и т.д. по тексту.
Это что касается стандартных, предустановленных размеров. Но если нужно задавать какие-то нестандартные свои значения, то тогда нужно модифицировать поля dmPaperWidth, dmPaperHeight той же структуры DevMode, установив соответствующие флаги.
Вообще, рекоммендую почитать главу о печати у Пачеко. В сети есть.
← →
Borion © (2004-08-25 13:03) [3]2Sergey Kaminski:
Вау!!! Огромное спасибо. Насчет задания dmPaperWidth, dmPaperHeight знаю, но я в принципе "экспериментально" определил dmPaperSize, который мне нужно использовать и думаю можно напрямую его задать.
На самом деле, я не мог дойти своим умом вот до этой строки
DevMode := GlobalLock (DeviceHandle);
Крутился вокруг, да около.
Книгу тоже поищу.
2Skier:
Поглядел я в TPrintSetupDialog, у него "своих" методов кроме Execute нету, да и там идет вызов диалога, хотя можно было бы копнуть глубже.
← →
[lamer]Barmaglot © (2004-08-25 13:10) [4]Хм... А использовать встроенный printer.pas в uses религия не позволяет? Там все это уже сделано...
← →
Borion © (2004-08-25 13:32) [5]2[lamer]Barmaglot:
Ну и какими же методами из printers.pas оперировать для этого??
← →
Sergey Kaminski © (2004-08-25 13:32) [6][lamer]Barmaglot © (25.08.04 13:10) [4]
Попробуйте ;)
Borion © (25.08.04 13:03) [3]
Тут еще один нюанс (в реализации у Пачеко).
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
if DeviceHandle = 0 then
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
end;
if DeviceHandle = 0 then
Raise Exception.Create ("Error setting printer caps!")
Т.е., хэндл, пытаемся получить ДВАЖДЫ, если не выходит сразуPrinter.GetPrinter
, то драйвер в данный момент может быть выгружен (насколько я понял, это вина TPrinter"а, впрочем, не берусь судить, не копал), а если это не прошло, то устанавливаем текущий принтер еще раз посредством "бессмыссленной" операцииPrinter.PrinterIndex := Printer.PrinterIndex;
и опять берем хэндл.
Пачеко, кажется, есть на podgoretsky.com.
← →
Borion © (2004-08-25 13:58) [7]Вот чудеса, блин!
Значит на строке
Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
получаем нужный Handle (проверяю имя принтера через Printer.Printers[Printer.PrinterIndex]),
но затем
при обращении (специально поставил такую проверку) к
DevMode^.dmDeviceName
оказывается, что обращаемся не к тому принтеру!
Ну, и естественно, смена бумаги не происходит, т.е. происходит, но на другом принтере.
Пока не могу разобраться:(
← →
Sergey Kaminski © (2004-08-25 14:10) [8]Printer.PrinterIndex := Printer.PrinterIndex
пробовал?
← →
Borion © (2004-08-25 14:25) [9]Пробовал, поставил перед Printer.GetPrinter(...), не помогло.
Попробовал DevMode := GlobalLock(Printer.Handle), но тогда DevMode указывает в nil
← →
Sergey Kaminski © (2004-08-25 14:49) [10]Две приведенные функции у меня успешно и активно работают месяцев 6 на нескольких машинах с кучей принтеров, в том числе и виртуальных вроде Acrobat Distiller. Попробуйте использовать их ЦЕЛИКОМ, как я привел, они выдраны один в один из рабочего юнита, т.е. это не пример.
← →
[lamer]Barmaglot © (2004-08-25 15:46) [11]to Sergey Kaminski © (25.08.04 13:32) [6]
А что
procedure SetOrientation(Value: TPrinterOrientation);
function GetOrientation: TPrinterOrientation;
уже не работают? Или я отстал от жизни либо одно из двух...
← →
Sergey Kaminski © (2004-08-25 16:02) [12][lamer]Barmaglot © (25.08.04 15:46) [11]
См. сабж:
Программная смена размера бумаги
А не ориентации страницы
← →
Borion © (2004-08-25 16:22) [13]А нет ли в использовании этих функций каких-нибудь особенностей, связанных с тем, что у меня есть и локальные и сетевые принтеры?
← →
Sergey Kaminski © (2004-08-25 16:31) [14]
Borion © (25.08.04 16:22) [13]
А нет ли в использовании этих функций каких-нибудь особенностей, связанных с тем, что у меня есть и локальные и сетевые принтеры?
Вроде не замечал ничего такого. Возможно что-то идет не так, если в данный момент сетевой принтер недоступен? Нужно проверить на практике, у меня сейчас доступа к сетевым принтерам нет, я дома сижу.
← →
Borion © (2004-08-25 16:36) [15]Экспериментально установил, что GetPrinter у меня всегда возвращает Handle принтера по умолчанию в системе, независимо от того, какой сейчас принтер является текущим. Не понимаю почему так.
← →
Sergey Kaminski © (2004-08-25 16:38) [16]А что записывает в ADevice, ADriver, APort?
← →
Borion © (2004-08-25 17:07) [17]В ADevice по ходу то, что нужно, по крайней мере через Ctrl+F7 видно, что там нужный девайс.
← →
Sergey Kaminski © (2004-08-25 17:11) [18]И что, размер страницы он меняет НЕ для того принтера, название которого в ADevice???
← →
Borion © (2004-08-25 17:22) [19]Ну да:))
← →
Borion © (2004-08-26 11:39) [20]Добрый день!
Сегодня почитал Пачеко и немного разобрался.
Не совсем для меня была понятна строкаdmFields := dmFields or DM_PAPERSIZE;
и поэтому у меня в коде не было строкdmFields := dmFields or DM_PAPERWIDTH;
иdmFields := dmFields or DM_PAPERLENGTH;
Осталась только проблема с тем, что возвращается хэндл принтера по умолчанию. Однако, у Пачеко нашел описание программной смены принтера по умолчанию. На крайний случай, можно временно менять принтер по умолчанию на нужный мне.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.039 c