Поскольку никто не предоставил ответ, и проблема теперь решена, я отмечаю это как вики сообщества. Не стесняйтесь, чтобы улучшить этот ответ.

могу использовать API XPS, так как программа должна быть в состоянии печатать на Windows XP.

Я пытаюсь установить размер бумаги от Letter до A4, используя WinSpool.

Это мой тестовый код:

var
  H          : THandle;
  I          : TBytes;
  Info       : PPrinterInfo2;
  NeededSize : DWORD;
  DevMode    : PDeviceMode;
  PD         : TPrinterDefaults;
begin
  PD.pDatatype     := nil;
  PD.pDevMode      := nil;
  PD.DesiredAccess := PRINTER_ACCESS_ADMINISTER;
  if not OpenPrinter('Brother HL-5350DN series Printer', H, @PD) then begin
    raise Exception.Create('OpenPrinter error: ' + SysErrorMessage(GetLastError));
  end;
  try
    Assert(not GetPrinter(H, 2, nil, 0, @NeededSize));
    SetLength(I, NeededSize);
    Info := @I[0];
    if not GetPrinter(H, 2, Info, NeededSize, @NeededSize) then begin
      raise Exception.Create('GetPrinter error: ' + SysErrorMessage(GetLastError));
    end;
    DevMode             := Info.pDevMode;
    DevMode.dmFields    := DevMode.dmFields or DM_PAPERSIZE;
    DevMode.dmPaperSize := DMPAPER_A4;
    Info.pSecurityDescriptor := nil; // According to MSDN it has to be niled if we're not going to change it.

    if not SetPrinter(H, 2, Info, 0) then begin
      raise Exception.Create('SetPrinter error: ' + SysErrorMessage(GetLastError));
    end;
  finally
    ClosePrinter(H);
  end;
  TPrintDialog.Create(Self).Execute; // This is just so I can check the paper size
end;

У меня есть две проблемы, связанные с правами доступа.

Если я установлюPD.DesiredAccess вPRINTER_ACCESS_ADMINISTER GetPrinter вызов не удается, я думаю, это связано с UAC.

Если я установлю его наPRINTER_ACCESS_USE GetPrinter вызов успешен и структура Info в порядке, но вызовSetPrinter выходит из строя.

Достаточно интересно, когда я игнорирую РезультатSetPrinter в диалоговом окне печати отображается размер принтера A4, хотяSetPrinter выходит из строя.

Я делаю это совершенно неправильно, и достаточно передать правильно настроенный PDeviceMode в OpenPrinter? (Я действительно придумал это после написания этого вопроса :-)

Еще один вопрос относительно VCL:

Если я используюPrinters блок, как я знаю, насколько большими должны быть буферы, которые передаются в качестве параметров вTPrinter.GetPrinter метод?

Фон:

Система: Windows 7 Профессиональная 64-битная английская с английским языком.

Я пытаюсь распечатать на бумаге формата A4 на сетевом принтере (Brother HL-5350DN).

Я установил все настройки принтера на панели управления на бумагу A4, но программа Delphi 2009, которую я пишу, все еще получает размеры бумаги для US Letter.

Другими словами: программа Delphi не соответствует настройкам по умолчанию диспетчера очереди печати.

Если я сначала запускаю TPrinterDialog и вручную выбираю правильный размер бумаги (в дополнительных настройках принтера), все в порядке.

Программа должна работать без какого-либо пользовательского интерфейса, поэтому я должен решить эту проблему программно, или желательно, чтобы программа просто учитывала настройки диспетчера очереди печати Windows по умолчанию.

Может быть, я пропустил какое-то неосведомленное урегулирование?

Ответы на вопрос(2)

Ваш ответ на вопрос