title: Default printer settings are ignored
body: <p>Using Windows Print Spooler API's, we can print out XPS files.</p>
  
  <p>The problem is that the print <strong>spooler ignores</strong> the <strong>default printer settings</strong>.</p>
  
  <p>(We've given up on trying to <a href="https://stackoverflow.com/questions/10345179/resetdc-does-nothing-print-spooler-apis-for-windows"><em>apply</em> printer settings</a>.  Default printer settings will just have to suffice.)</p>
  
  <p>For example... the printouts always come out in colour and on one paper per page, regardless of what the settings are set to in the control panel:  black &amp; white/colour, duplex/not duplex, multiple pages per sheet/single page per sheet.</p>
  
  <p>Other applications such as MS Word and Adobe respect the default printer settings.</p>
  
  <p>We're using Delphi XE2 and Windows 7 64-bit.</p>
  
  <p>This test code is self contained, so you can just paste it in to test it...</p>
  
  <p>Populate a combo box with printer names using:</p>
  
  <pre><code>uses
    Printers
  
  ComboBox1.Items.Assign(Printer.Printers);
  </code></pre>
  
  <p>Printing procedure:</p>
  
  <pre><code>uses
    Winapi.WinSpool
  
  procedure PrintXPS(PrinterName, FileNameXPS: string; ParentFormHandle: THandle = 0);
  
    //  Printer handle
  
    procedure Printer_Open(out Printer: THandle; Defaults: PPrinterDefaultsW = nil);
    begin
      if  not OpenPrinterW(PWideChar(PrinterName), Printer, Defaults) then
        RaiseLastOSError;
    end;
  
    procedure Printer_Close(Printer: THandle);
    begin
      if  not ClosePrinter(Printer) then
        RaiseLastOSError;
    end;
  
    //  Print jobs
  
    function  JobCreate(Printer: THandle; FileName: string): Cardinal;
    var
      lBufferSize: Cardinal;
      lAddJobInfo: PAddJobInfo1W;
    begin
      //  Create job
      AddJobW(Printer, 1, nil, 0, lBufferSize);
      GetMem(lAddJobInfo, lBufferSize);
      try
        if  not AddJobW(Printer, 1, lAddJobInfo, lBufferSize, lBufferSize)  then
          RaiseLastOSError;
        Result  := lAddJobInfo.JobId;
        //  Copy the file into place
        CopyFile(PWideChar(FileName), lAddJobInfo.Path, True);
      finally
        FreeMem(lAddJobInfo, lBufferSize);
      end;
    end;
  
    procedure JobStart(Printer: THandle; JobID: Cardinal);
    begin
      if  not ScheduleJob(Printer, JobID) then
        RaiseLastOSError;
    end;
  
  var
    PrinterA: THandle;
    JobID: Cardinal;
  begin
    if  not FileExists(FileNameXPS)  then
      raise Exception.Create('File not found: ' + FileNameXPS);
  
    Printer_Open(PrinterA, nil);
    try
      JobID := JobCreate(PrinterA, FileNameXPS);
      JobStart(PrinterA, JobID);
    finally
      Printer_Close(PrinterA);
    end;
  
  end;
  </code></pre>