Wie legen Sie das Papierformat mit den WinSpool-API?

Kann ich nicht verwenden Sie die XPS-API, da das Programm in der Lage, drucken auf Windows XP.

Ich versuche, legen Sie die Papiergröße von Letter auf A4 mit WinSpool.

Dies ist mein test-code:

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;

Ich habe zwei Probleme im Zusammenhang mit Zugriffsrechten.

Wenn ich PD.DesiredAccess zu PRINTER_ACCESS_ADMINISTER die GetPrinter Aufruf schlägt fehl, ich denke, dies ist aufgrund der UAC.

Wenn ich es auf PRINTER_ACCESS_USE die GetPrinter Aufruf erfolgreich und der Info-Struktur ist in Ordnung, aber der Aufruf SetPrinter ausfällt.

Interessanterweise, wenn ich das ignorieren das Ergebnis SetPrinter den dialog drucken von berichten A4 als Drucker Größe, obwohl SetPrinter ausfällt.

Mache ich es komplett falsch und es ist genug, um pass ein richtig setup bis PDeviceMode zu OpenPrinter? (Ich kam eigentlich mit dieser nach dem schreiben dieser Frage 🙂

Eine andere Frage, die VCL:

Nutzen, wenn ich die Printers Gerät Woher weiß ich wie groß der Puffer sein, der bekommt als Parameter übergeben, um die TPrinter.GetPrinter Methode?

Hintergrund:

System ist: Windows 7 Professional 64-Bit Englisch mit englischen Gebietsschema.

Bin ich versucht, drucken auf A4-Papier auf ein Netzwerk-Drucker (Brother HL-5350DN).

Habe ich alle Drucker-Einstellungen in der Systemsteuerung, um A4-Papier, aber die Delphi 2009-Programm, das ich Schreibe, wird immer noch der Papier-Abmessungen, die für UNS Schreiben.

In anderen Worten: Das Delphi-Programm nicht, respektieren Sie die Standard-Einstellungen der Drucker-spooler.

Wenn ich ein TPrinterDialog erste und wählen Sie das richtige Papierformat von dort aus manuell (in der erweiterten Drucker-Einstellungen) alles in Ordnung ist.

Kann das Programm ausführen, ohne UI, also ich habe um dieses Problem zu lösen, programmgesteuert oder vorzugsweise sollte das Programm nur hinsichtlich der Standard-Windows-Drucker-spooler-Einstellungen.

Vielleicht habe ich etwas verpasst wichtige Einstellung?

  • warum können Sie nicht verwenden, TPrinter?
  • Es gibt keine PageFormat Einstellung in TPrinter, die einzige Möglichkeit die ich sehen kann, ist die Verwendung von TPrinter.GetPrinter und TPrinter.SetPrinter. Wie weiß ich, wie viel Platz zu vergeben für die Argumente der TPrinter.GetPrinter?
  • Was machst du eigentlich hier zu tun versuchen? Sicherlich weiß der Drucker, welche Größe das Papier ist. Der Benutzer wählt das Fach, die Sie wollen aus den Drucker-Einstellungen-dialog. Sie können nicht ändern Sie die Papiergröße im code! Es könnte uns auch helfen, wenn du uns die ganze Geschichte, anstatt nur ein Fenster in eine winzige Ecke Ihres Problems.
  • Ich habe einige Hintergrundinformationen zu der Frage.
  • Es klingt für mich wie die Drucker-Einstellungen sind nicht richtig eingestellt. Ich würde auf der Suche um das zu beheben, anstatt zu versuchen, um code herum.
  • Ich werde mich durch alle relevanten Einstellungen wieder seufzen.
  • Die VCL nicht zu füllen in der 'Treiber' und 'port' - Felder (es sei denn, das laufen auf W9x) und es scheint, als würde Sie bereits wissen, den Namen des Druckers, reservieren Sie ein Zeichen für die 'driver' - und 'port' und die Länge der den Namen des Druckers für 'Gerät'. Wenn Sie nicht wissen, den Namen des Druckers, es ist am meisten 539 Zeichen. Sie können auch hack Printer.Printers.Objects[#] zu einem TPrinterDevice ( =class Driver,Device,Port: string; end; ), um sicher zu sein.

Schreibe einen Kommentar