Проверить, печатает ли текущий принтер в цвете
Автор: 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;
|