Como definir o tamanho do papel usando a API WinSpool?

Não consigo usar a API XPS, pois o programa precisa ser capaz de imprimir no Windows X

Estou tentando definir o tamanho do papel de Carta para A4 usando o WinSpoo

Este é o meu código de teste:

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;

Tenho dois problemas relacionados aos direitos de acess

Se eu definirPD.DesiredAccess paraPRINTER_ACCESS_ADMINISTER aGetPrinter chamada falhar, acho que isso se deve ao UA

Se eu defini-lo comoPRINTER_ACCESS_USE aGetPrinter chamada @ foi bem-sucedida e a estrutura Info está correta, mas a chamada paraSetPrinter falha.

Curiosamente, quando ignoro o resultado deSetPrinter a caixa de diálogo de impressão informa A4 como o tamanho da impressora, mesmo queSetPrinter falha.

Estou fazendo isso completamente errado e é suficiente passar uma configuração correta do PDeviceMode para o OpenPrinter? (Na verdade, eu vim com isso depois de escrever esta pergunta: -)

Outra pergunta sobre a VCL:

Se eu usar oPrinters unit, como sei qual o tamanho dos buffers que são passados como parâmetros para oTPrinter.GetPrinter método?

Fund:

O sistema é: Windows 7 Professional em inglês de 64 bits com localidade em inglê

Estou tentando imprimir em papel A4 em uma impressora de rede (Brother HL-5350DN).

Definei todas as configurações da impressora no painel de controle para papel A4, mas o programa Delphi 2009 que estou escrevendo ainda obtém as dimensões do papel para US Lette

Em outras palavras: o programa Delphi não respeita as configurações padrão do spooler da impressor

Se eu executar um TPrinterDialog primeiro e selecionar manualmente o tamanho de papel correto (nas configurações avançadas da impressora), tudo estará be

O programa deve ser executado sem nenhuma interface do usuário, por isso tenho que resolver isso de forma programática ou preferencialmente, o programa deve respeitar apenas as configurações padrão do spooler de impressora do Window

Talvez eu tenha perdido alguma configuração importante?

questionAnswers(2)

yourAnswerToTheQuestion