Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.035 c
14-1093018781
Igorek
2004-08-20 20:19
2004.09.12
Патч для TApplication (помидорами не бросаться!!!) :-)))


14-1093172099
Светик
2004-08-22 14:54
2004.09.12
Жаждущая чего-нибудь ахового и интересного


3-1092729831
Wolfram
2004-08-17 12:03
2004.09.12
Непонятный глюк с ADO.


14-1093349790
Суслик
2004-08-24 16:16
2004.09.12
XML и MS Excel.


1-1093534167
hamster
2004-08-26 19:29
2004.09.12
Двоичные данные





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский