скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Проверить, печатает ли текущий принтер в цвете



Автор: Slava Vitebski
WEB-сайт: http://monfort.co.il


uses 
  Printers, WinSpool; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
  Dev, Drv, Prt: array[0..255] of Char; 
  DM1: PDeviceMode; 
  DM2: PDeviceMode; 
  Sz: Integer; 
  DevM: THandle; 
begin 
  Printer.PrinterIndex := -1; 
  Printer.GetPrinter(Dev, Drv, Prt, DevM); 
  DM1 := nil; 
  DM2 := nil; 
  Sz  := DocumentProperties(0, 0, Dev, DM1^, DM2^, 0); 
  GetMem(DM1, Sz); 
  DocumentProperties(0, 0, Dev, DM1^, DM2^, DM_OUT_BUFFER); 
  if DM1^.dmColor > 1 then 
    label1.Caption := Dev + ': Color' 
  else 
    label1.Caption := Dev + ': Black and White'; 
  if DM1^.dmFields and DM_Color <> 0 then 
    Label2.Caption := 'Printer supports color printing' 
  else 
    Label2.Caption := 'Printer does not support color printing'; 
  FreeMem(DM1); 
end;

Недавно мне нужно было найти надёжный способ определить печатает ли принтер цветом или нет. Пример который приведен выше не подходит так как он использует API - DocumentProperties а эта функция возвращает положительный результат для чёрно-белых принтеров способных печатать оттенки серого цвета (пример такого принтера - HP LasetJet 1200). Быстры поиск привёл меня к функции - DeviceCapabilities (в Delphi она определена в WinSpool). Функция имеет следующий формат:

DWORD DeviceCapabilities(
  LPCTSTR pDevice,         // printer name
  LPCTSTR pPort,           // port name
  WORD fwCapability,       // device capability
  LPTSTR pOutput,          // output buffer
  CONST DEVMODE *pDevMode  // device data buffer
);

параметр fwCapability получает константу которая говорит о том что мы хотим узнать о принтере. В данном случае нас интересует DC_COLORDEVICE. MSDN пишет следующее о б этом параметре:

Windows 2000/XP: If the printer supports color printing, the return value is 1; otherwise, the return value is zero. The pOutput parameter is not used.

Не всё так просто. значение константы DC_COLORDEVICE определенно не верно!!! Заглянем в Windows.pas файл (это часть определений):

  DC_COLLATE = 22;
  {$EXTERNALSYM DC_MANUFACTURER}
  DC_MANUFACTURER = 23;
  {$EXTERNALSYM DC_MODEL}
  DC_MODEL = 24;
  {$EXTERNALSYM DC_COLORDEVICE}
  DC_COLORDEVICE = 23;
  {$EXTERNALSYM DC_NUP}
  DC_NUP = 24;
  {$EXTERNALSYM DC_PERSONALITY}
  DC_PERSONALITY = 25;

Обратите внимание на выделенные строчки, у них одинаковые значения. Похожая ситуация наблюдается во всех версиях Delphi и в Visual C++ 6. Только в Visual C++ 7 (Visual Studio .NET) Microsoft решили исправить ситуацию и дали нам правильные кода. Ну а вот собственно и сама функция:

uses
    Printers, WinSpool;

    const
         {Those constants definition is WRONG !!! in Delphi and "VC 6".
          Only in "VC 7" those definitions are corrected.}
         DC_PERSONALITY         = 25;
         DC_PRINTRATE              = 26;
         DC_PRINTRATEUNIT       = 27;
         DC_PRINTERMEM          = 28;
         DC_MEDIAREADY          = 29;
         DC_STAPLE                   = 30;
         DC_PRINTRATEPPM      = 31;
         DC_COLORDEVICE        = 32;
         DC_NUP                         = 33;
         DC_MEDIATYPENAMES = 34;
         DC_MEDIATYPES           = 35;

    function IsPrinterSupportColor(APtinterName: string): boolean;
    var
      fRes: Integer;
      pPrinterInfo: ^PRINTER_INFO_2;
      Needed: cardinal;
      phPrinter: cardinal;
    begin
         OpenPrinter(PChar(APtinterName), phPrinter, nil);
         GetPrinter(phPrinter, 2, nil, 0, @Needed);
         GetMem(pPrinterInfo, Needed);
         try
            GetPrinter(phPrinter, 2, pPrinterInfo, Needed, @Needed);

             fRes := WinSpool.DeviceCapabilities(pPrinterInfo^.pPrinterName,
              pPrinterInfo^.pPortName, DC_COLORDEVICE, nil, nil);
            if fRes = -1 then
               raise Exception.Create(SysErrorMessage(GetLastError));
            Result := fRes = 1;
         finally
            FreeMem(pPrinterInfo, Needed);
         end;
    end;





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook