I need to capture a printer driver's settings that a windows machine has set up to determine if they have collate turned on for a particular printer.
I know how to get whether a printer can collate using the DeviceCapabilities call passing in DC_COLLATE but this does not tell me whether the print driver is set to collate or not, only that the printer has the ability to collate, not that it will collate.
Why?
I am trying to work around an issue in QuickReports with Delphi XE2 where our program no longer works the way it did when compiled under Delphi 6. With the Delphi 6 version no matter the settings from QuickReport it ALWAYS obeyed the collate setting in the printer driver. With the Delphi XE2 version it does not.
The user does not have security to change collate settings, it is forced on for them by their sysadmins and these documents need to print collated on the specified printer.
If I can determine if the driver is set to collate always I can just force the collate setting in QuickReport and it will do what I need and thus my question above.
As always I appreciate any ideas.
Cheers!
You need to use the Windows API functions OpenPrinter
and GetPrinter
. When calling GetPrinter
, pass it a PRINTER_INFO_2
record, which will be returned with the pDevMode
member set to a DEVMODE
; that DEVMODE
record contains a flag for whether collation is enabled (among other things).
Here's an old Borland NG post by TeamB's Dr. Peter Below. It demonstrates updating printer settings to make them permanent, but it includes using OpenPrinter
, GetPrinter
, ClosePrinter
, and PRINTER_INFO_2
, as well as using the DEVMODE
(referred to as hDevMode
in the code below); it should get you started.
Procedure MakePrintersettingsPermanent;
var
hPrinter: THandle;
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port : array[0..255] of char;
hDeviceMode: THandle;
pDevMode: PDeviceMode;
bytesNeeded: Cardinal;
pPI: PPrinterInfo2;
Defaults: TPrinterDefaults;
retval: BOOL;
begin
Assert( Printer.PrinterIndex >= 0 );
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
FillChar( Defaults, Sizeof(Defaults), 0 );
Defaults.DesiredAccess:=
PRINTER_ACCESS_ADMINISTER or PRINTER_ACCESS_USE;
if not WinSpool.OpenPrinter(@Device, hPrinter, @Defaults ) then
RaiseLastWin32Error;
try
retval := WinSpool.GetPrinter(
hPrinter,
2,
Nil, 0, @bytesNeeded );
GetMem( pPI, bytesNeeded );
try
retval := WinSpool.GetPrinter(
hPrinter, 2,
pPI, bytesNeeded, @bytesNeeded );
If not retval Then
RaiseLastWin32Error;
pDevMode := GlobalLock( hDeviceMode );
Assert( Assigned( pdevmode ));
try
Move( pdevmode^, pPI^.pDevMode^, Sizeof( pdevmode^ ));
finally
GlobalUnlock( hDevicemode );
end;
If not WinSpool.SetPrinter(
hPrinter, 2,
pPI,
0 )
Then
RaiseLastWin32error;
finally
FreeMem( pPI );
end;
finally
WinSpool.ClosePrinter( hPrinter );
end;
end;