質問

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;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top