Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Вниз

Двусторонняя печать.   Найти похожие ветки 

 
Тимохов ©   (2004-06-07 14:01) [0]

Добрый день.
Есть следующий код, определяющий поддерживает ли принтер двустороннюю печать.

var
  kPrinterHandle : THandle;
  kDevice : array[0..1023] of Char;
  kDriver : array[0..1023] of Char;
  Port : array[0..1023] of Char;
  kDeviceMode: THandle;
  kResult : integer;
begin
  // получить инф. о принтере (нам интересно имя)
  fPrinter.GetPrinter(kDevice, kDriver, Port, kDeviceMode);
  // по имени получаем хэндл принтера
  if not OpenPrinter(kDevice, kPrinterHandle, nil) then
  begin
     RaiseLastOSError();
  end;
  // проверяем, поддерживает ли принтер двухстороннюю печать
  kResult := WinSpool.DeviceCapabilities(kDevice, Port, DC_DUPLEX, nil, nil);
  if kResult = -1 then
  begin
     RaiseLastOSError();
  end;
  Result := kResult = 1;
  // true поддерживает, false не поддерживает
end;


Проблема состоит в том, что будучи выполненным на компьютере, к которому непосредственно подсоединен принтер result принимает правильное значение (т.к. там, где принтер не поддерживает двустороннюю печать false, где поддерживает - true), но на компьютере, который соединен по сети с компьютером, к которому подключен принтер, показывает всегда true, т.е. поддерживает двустороннюю печать.

Вопрос: в чем заключается особенность работы с функцией DeviceCapabilities при обращении к сетевому принтеру и к локальному принтеру?


 
Тимохов ©   (2004-06-07 18:33) [1]

Дополнение к вопросу.
Скажите, что называется дуплексной печатью - когда принтер автоматически перевертывает бумагу или когда принтер требует, чтобы я сам перевернул бумагу нажал кнопку и тем самым получил как бы двусторонюю печать?

Вопрос вызван тем, что есть ощущение, что считается именно второе. Именно поэтому приведенный в вопросе код на всех принтерах (у меня на работе) говорит, что дуплексная печать поддерживается.


 
YuRock   (2004-06-07 20:05) [2]

1. Для получения настроек/возможностей принтера необходимо указывать последний параметр DeviceCapabilities (структура DEVMODE - ее можно получить ч-з CreateDC), иначе вернутся настройки, которые ставятся этому принтеру по умолчанию.

2. В Help"е написано: "If pOutput is zero, DeviceCapabilities returns the number of bytes required for the output data."
На сколько я знаю английский, то если не указать предпоследний параметр, ф-ция просто вернет кол-во байт, необходимое для получения данных (т.е. ф-цию надо вызывать 2 раза - вначале - для получения размера pOutput, а потом, выделив память под pOutput, вызвать ее еще раз). Хотя может я и ошибаюсь (хотя вряд ли) :))

3. Что такое дуплексная печать - не знаю. Думаю, что ф-ция вернет просто возможность принтером печатать с 2-х сторон - не более того. "С кнопкой" или "без кнопки".


 
KilkennyCat ©   (2004-06-08 04:22) [3]

Дуплексная печать - принтер автоматически переворачивает бумагу. У меня такой HP 2200 DN. Прикольно. Но долго.


 
Тимохов ©   (2004-06-08 10:50) [4]


> YuRock   (07.06.04 20:05) [2]

из описания той же функции devicecapabilities:

"DC_DUPLEX If the printer supports duplex printing, the return value is 1; otherwise, the return value is zero. The pOutput parameter is not used."


> KilkennyCat ©   (08.06.04 04:22) [3]

Значете, я тоже так думал. Но!
У нас на работе есть как принтеры с дуплексной печатью, так и без нее. На обоих принтерах devicecapabilities показывает, что дуплексная печать есть. На принтере с индексом D (как у вас) действиетльно после выставления режима дуплексной печати сначала печатает одну сторону, затем другую затянув предварительно бумагу обратно. На принтерах без индекса D (т.е. без дуплексной печати) дуплексная печать реализована в ручном режиме, т.е. после установки дуплексного режима (замечу, что для таких принтеров он ставится без проблем, т.е. без ошибки) и начала печати, т.е. printer.begindoc вылазит диалоговое окно с интсрукциями, как переварачивать бумагу и на какие кнопки жать, чтобы была печать с двух сторон. Т.е. выходит :)))), что все принтеры поддерживают дуплексную печать: одни в автоматическом режиме, другие в ручном. В настройках принтеров второго типа (т.е. без авт. дуплексной печати) есть галочка: разрешить двустороннюю печать. Если ее снять, то devicecapabilities все равно говорит, что дуплексная печать есть, хотя печатать отказывается.

Т.о. перефразирую еще раз вопрос (он же единственный, т.е. предыдущие вопросы не принимайте во внимание):
1. как определить, что принтер реально спосообен напечатать дуплексно - в ручном или автоматическом режиме не важно.
2. как определить, что принтер реально способен напечатать дуплесно - в автоматическом режиме.

Заранее спасибо.


 
YuRock ©   (2004-06-08 13:23) [5]

> Тимохов ©   (08.06.04 10:50) [4]
> DC_DUPLEX If the printer supports duplex printing, the return value is 1; otherwise, the return value is zero. The pOutput parameter is not used."

Да, не заметил.

> В настройках принтеров второго типа (т.е. без авт. дуплексной печати) есть галочка: разрешить двустороннюю печать. Если ее снять, то devicecapabilities все равно говорит, что дуплексная печать есть, хотя печатать отказывается.

Это ситуация, описанная мною в пункте 1 ответа [2].


 
Тимохов ©   (2004-06-08 13:53) [6]


> YuRock ©   (08.06.04 13:23) [5]


> Это ситуация, описанная мною в пункте 1 ответа [2].

Не могли бы вы прокомментировать данное утверждение. Где это написано? В описании devicecapabilities я этого нашел...
Заранее спасибо.


 
YuRock ©   (2004-06-08 14:12) [7]

> Тимохов ©   (08.06.04 13:53) [6]

"pDevMode

Pointer to a DEVMODE structure. If this parameter is NULL, DeviceCapabilities retrieves the current default initialization values for the specified printer driver. Otherwise, the function retrieves the values contained in the structure to which pDevMode points."


 
Тимохов ©   (2004-06-08 14:24) [8]


> YuRock ©   (08.06.04 14:12) [7]

спасибо, но читайте лучше msdn. прочитайте приведенную вами фразу очень внимательно и поймете, что вы совсем не о том.

hint: devicecapabilities в случае заданность pDevMode просто используется как средство облегчения доступа в переданную вами же pDevMode и ничего более.

PS. Есть конечно шанс (у меня), что вы действительно обладаете глубокими познаниями в этой области и вы реально делали то, о чем я спрашиваю, а не просто прочли msdn. Если я прав в первом предположении, то за помощь буду очень плагодарен.


 
YuRock ©   (2004-06-08 16:15) [9]

Попробуйте вот это (надеюсь (скорее всего), Вам поможет):


function SelectPrinter(hWnd: HWND; DevMode: PDevMode): Boolean;
var
 pdlg : TPrintDlg;
 dm : PDevMode;
begin
 Result := False;

 ZeroMemory(@pdlg, SizeOf(pdlg));
 pdlg.lStructSize := SizeOf(TPrintDlg);
 pdlg.hwndOwner := hWnd;
 pdlg.Flags := PD_HIDEPRINTTOFILE or PD_NOPAGENUMS;
 pdlg.hInstance := HInstance;
 if PrintDlg(pdlg) then begin
   dm := GlobalLock(pdlg.hDevMode);
   try
     if Assigned(DevMode) then CopyMemory(DevMode, dm, SizeOf(TDeviceModeA));
   finally
     GlobalFree(pdlg.hDevNames);
     GlobalUnlock(HGLOBAL(dm));
   end;

   Result := True;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 DevMode: TDevMode;
 cDuplexMode: String;
begin
 if SelectPrinter(Handle, @DevMode) then begin
   case DevMode.dmDuplex of
     DMDUP_SIMPLEX: cDuplexMode := "DMDUP_SIMPLEX";
     DMDUP_HORIZONTAL: cDuplexMode := "DMDUP_HORIZONTAL";
     DMDUP_VERTICAL: cDuplexMode := "DMDUP_VERTICAL";
     else cDuplexMode := "NONE";
   end;

   ShowMessage("Режим дуплексной печати: " + cDuplexMode);
 end;
end;


В случае, если флажок двусторонней печати не стоит - возвращается DMDUP_SIMPLEX, если стоит - то одно из двух...


 
YuRock ©   (2004-06-08 16:52) [10]

Бысрое (на сколько смог) дополнение: ф-ция DeviceCapabilities просто определяет возможность дуплексной печати на заданном устройстве. А ее настройки - содержатся в DEVMODE.

Немного изменив приведенный пример, получаем:

function SelectPrinter(hWnd: HWND; DevMode: PDevMode; var Name, Port: String): Boolean;
var
 pdlg : TPrintDlg;
 dm : PDevMode;
 dn: PDevNames;
begin
 Result := False;

 ZeroMemory(@pdlg, SizeOf(pdlg));
 pdlg.lStructSize := SizeOf(TPrintDlg);
 pdlg.hwndOwner := hWnd;
 pdlg.Flags := PD_HIDEPRINTTOFILE or PD_NOPAGENUMS;
 pdlg.hInstance := HInstance;
 if PrintDlg(pdlg) then begin
   dm := GlobalLock(pdlg.hDevMode);
   try
     if Assigned(DevMode) then CopyMemory(DevMode, dm, SizeOf(TDevMode));
   finally
     GlobalUnlock(HGLOBAL(dm));
   end;

   dn := GlobalLock(pdlg.hDevNames);
   try
     Name := String(PChar(dn) + dn.wDeviceOffset);
     Port := String(PChar(dn) + dn.wOutputOffset);
   finally
     GlobalUnlock(HGLOBAL(dn));
     GlobalFree(pdlg.hDevNames);
   end;

   Result := True;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 kResult: Integer;
 DevMode: TDevMode;
 Name, Port: String;
begin
 if SelectPrinter(Handle, @DevMode, Name, Port) then begin
   kResult := DeviceCapabilities(PChar(Name), PChar(Port), DC_DUPLEX, nil, @DevMode);
   if kResult = -1 then
     RaiseLastOSError;

   if kResult = 0 then
     ShowMessage("Дуплексная печать не поддерживается")
   else begin
     case DevMode.dmDuplex of
       DMDUP_SIMPLEX: ShowMessage("Дуплексная печать отключена (может использоваться вручную)");
       DMDUP_VERTICAL: ShowMessage("Дуплексная печать работает в "книжном" режиме");
       DMDUP_HORIZONTAL: ShowMessage("Дуплексная печать работает в "альбомном" режиме");
     end;
   end;
 end;
end;


Думаю, информация исчерпывающая.


 
Тимохов ©   (2004-06-08 17:06) [11]


> YuRock ©   (08.06.04 16:52) [10]

Спасибо за участие:))

Данный код дает ответ (проверил) на первый вопрос, заданный в [4] т.е. на  "1. как определить, что принтер реально спосообен напечатать дуплексно - в ручном или автоматическом режиме не важно". Но не дает ответа на "2. как определить, что принтер реально способен напечатать дуплесно - в автоматическом режиме.". Т.е. в случае DMDUP_SIMPLEX принтер вообще не поддерживает никакой дуплекс, только если будешь класть по одному листку и переварачивать его (но, думаю, это вообще нельзя назвать дуплексом). В случае DMDUP_VERTICAL и DMDUP_VERTICAL мой принтер печатает так - печатает сторону и ждет пока я переверну лист и не нажму кнопку. В другой комнате печатает полностью автоматически - лист выезжает, затем утягивается (сам) обратно и вылезает напечатанный с двух сторон. Вот именно эти два случая не получается отличить :((


 
YuRock ©   (2004-06-08 17:18) [12]

Может принтер, на котором надо нажать кнопку, считает, что это тоже "автоматически".

А Вам какая разница то? Вы отправляйте на печать - а "он" (драйвер) сам разберется, когда что делать.

> Т.е. в случае DMDUP_SIMPLEX принтер вообще не поддерживает никакой дуплекс

Совсем не обязательно! Просто может эта возможность в настройках отключена! А вот если DeviceCapabilities вернула 0 - тогда да, не поддерживает никак.
В [10], помоему, максимально много информации можно узнать. Ну, сколько есть :))


 
Тимохов ©   (2004-06-08 17:27) [13]


>  [10], помоему, максимально много информации можно узнать.
> Ну, сколько есть :))

с этим пожалуй согласен.


> А Вам какая разница то? Вы отправляйте на печать - а "он"
> (драйвер) сам разберется, когда что делать.

с этим пожалуй тоже согласен.

В общем спасибо за участие.
Буду набираться опыта

ЗЫ. Эх 10 лет занимаюсь программирование - принтеров просто ненавижу до сих пор.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.037 c
1-1089650210
maverick
2004-07-12 20:36
2004.07.25
FastReport


3-1088677826
Lord
2004-07-01 14:30
2004.07.25
Delphi6 - SQL


1-1089757628
Lego
2004-07-14 02:27
2004.07.25
ListBox


14-1088762602
Snip
2004-07-02 14:03
2004.07.25
Облом с интернетом


14-1088594973
Александр Иванов
2004-06-30 15:29
2004.07.25
У меня в субботу свадьба





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский