|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Запись и чтение параметров принтера через WinSpool.SetPrinter
Доброго времени суток, коллеги. Есть некая проблема, о которую я сломал голову.
Имеется принтер, поддерживающий двухстороннюю печать, с помощью 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. Последний раз редактировалось Hellner, 10.04.2013 в 11:48. |
#2
|
|||
|
|||
как оказалось, проблема была в кристаловской VCL, в которой надо было вызывать cr.Printer.Clear перед печатью.
|