Доброго времени суток, коллеги. Есть некая проблема, о которую я сломал голову.
Имеется принтер, поддерживающий двухстороннюю печать, с помощью WinSpool.SetPrinter я устанавливаю тип двухсторонней печати, после чего из этой же программы отправляю документ на принтер.
Проблема в том, что при первой же отправке документа на печать, дальнейшие изменения спулера никак на печати не отражаются, хотя зачитать я их (уже измененных) могу То есть получается следующая ситуация (на конкретном примере):
1) Открыли программу
2) Зачитали параметры двухсторонней печати, там лежит dmDuplex = DMDUP_SIMPLEX
3) Записали в принтер значение dmDuplex = DMDUP_VERTICAL через WinSpool.SetPrinter
4) Распечатали документ как и положено, на двух сторонах (согласно параметру DMDUP_VERTICAL)
5) Записали в принтер значение dmDuplex = DMDUP_SIMPLEX через WinSpool.SetPrinter
6) Зачитали параметры двухсторонней печати, там лежит dmDuplex = DMDUP_SIMPLEX
7) Распечатали документ, как будто 5-го пункта мы не выполняли, т.е. на двух сторонах (DMDUP_VERTICAL)
Я что-то забываю сбрасывать или обнулять, так как первая же операция печати "фиксирует" изменения спулера, но вот что именно не пойму. Прошу Вашей помощи!
Получаем Handle принтера:
Код:
function GetPrinterHandle: THandle;
const PrinterDefaults: TPrinterDefaults = (pDatatype: nil; pDevMode: nil; DesiredAccess: PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER);
var ADevice, ADriver, APort: array[0..MAX_PATH] of Char;
hDeviceMode: THandle;
begin
Printer.GetPrinter(ADevice, ADriver, APort, hDeviceMode);
if not OpenPrinter(@ADevice, Result, @PrinterDefaults) then
RaiseLastOSError;
end;
Вот код функции, с помощью которой я прописываю параметры печати:
Код:
function GetPrinterDuplex(const APrinterIndex: Integer): integer;
var
APrinterHandle: THandle;
APrinterInfo: PPrinterInfo2;
ABytesNeeded: DWORD;
begin
APrinterHandle := 0;
try
Printer.PrinterIndex := APrinterIndex;
APrinterHandle := GetPrinterHandle;
ABytesNeeded := 0;
if not WinSpool.GetPrinter(APrinterHandle, 2, nil, 0, @ABytesNeeded) then
if Windows.GetLastError <> ERROR_INSUFFICIENT_BUFFER then RaiseLastOSError;
GetMem(APrinterInfo, ABytesNeeded);
try
if not WinSpool.GetPrinter(APrinterHandle, 2, APrinterInfo, ABytesNeeded, @ABytesNeeded) then RaiseLastOSError;
Result := APrinterInfo^.pDevMode.dmDuplex;
finally
FreeMem(APrinterInfo);
end;
ClosePrinter(APrinterHandle);
except
on E: Exception do
begin
if APrinterHandle <> 0 then ClosePrinter(APrinterHandle);
raise;
end;
end;
end;
А это кусок кода, где происходит печать отчета Crystal Reports XI через VCL:
Код:
p := Printer.Printers.IndexOf(f_main.cb_printer_list.Text);
RefreshPrinter(p);
cr.Refresh;
cr.Printer.Name := cb_printer_list.Text;
cr.ParamFields[0].CurrentValue := '9897';
cr.ParamFields[1].CurrentValue := 'AK';
cr.Print;
На всякий случай уточню, что VCL 11-го кристала для 7 дельфи не поддерживают параметры двухсторонней печати, поэтому приходится шаманить с WinSpool.