Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi 2 Druckertreiber für 1 Drucker? (https://www.delphipraxis.net/180827-2-druckertreiber-fuer-1-drucker.html)

Mattze 20. Jun 2014 14:26

2 Druckertreiber für 1 Drucker?
 
Hallo,

folgendes Problem:
Mache ich Printer.getprinter... bekomme ich als Druckertreiber den Namen des Druckers selber zurück.
Mache ich VORHER Printdialog.execute und OK, dann bekomme ich, auch mit Printer.getprinter, als Druckertreiber winspool zurück.

Ich nehme an, winspool ist richtig!

Es reicht nicht, den printerindex entsprechend zu setzen. Offenbar setzt der Printdialog also noch etwas, damit es richtig wird. Aber was? Aus dem Quelltext kriege ich es leider nicht raus.

Wie bekomme ich denn das nun korrekt OHNE den Printdialog?
(Zumindest nicht mal so und mal so.)

Übrigens habe ich das mit mehreren Druckern probiert.

(Delphi 7 pro, Win 7 64)

Gruß
Mattze

mkinzler 20. Jun 2014 14:27

AW: 2 Druckertreiber für 1 Drucker?
 
WinSpool ist nicht der Treiber für den Drucker, sondern die Druckerwarteschlange

Mattze 20. Jun 2014 15:34

AW: 2 Druckertreiber für 1 Drucker?
 
Hallo!

Das dachte ich auch und war verwundert: Warum wird es dann in PPrinterInfo2 unter pDriverName angegeben.

Das hilft mir aber nun nicht weiter, weil ich nicht weiß, wie das einzuordnen ist!
Warum zwei Drivernamen? Was ist der richtige?

Gruß
Mattze

himitsu 20. Jun 2014 16:05

AW: 2 Druckertreiber für 1 Drucker?
 
Zitat:

Es reicht nicht, den printerindex entsprechend zu setzen
Ja, in Delphi 7 gibt es einen Bug.
Mindestens seit XE ist das aber repariert.

Mal sehn, ob ich den Bugfix wiederfinde, den ich vor paar Wochen ausgebaut hatte. (denn seit des in Delphi wieder funktioniert, macht nun der Bugfix das kaputt)

Mattze 20. Jun 2014 17:31

AW: 2 Druckertreiber für 1 Drucker?
 
Hallo himitsu,

vielen Dank! Dass es ein Bug in Delphi 7 ist, tröstet mich tatsächlich schon ein bisschen. Dann habe nämlich nicht ich wieder mal alles durcheinander gebracht!

Bitte, bitte suche den Bugfix und finde ihn auch! Das wäre super!

Ich bin jetzt soweit, dass ich mit Printer.GetPrinter winspool als Treiber bekomme (oder, je nachdem, wie ich es initialisiere (!) auch den Druckernamen als Treiber!) und mit openprinter den richtigen Port. Wobei ich eben nicht weiß, was winspool als Treiber bedeuten soll.

Aber, irgendwie befriedigt mich das nicht!
Ich denke mir, dass Printer.GetPrinter das ALLES richtig zurückgeben sollte.

Gruß
Mattze

himitsu 22. Jun 2014 10:44

AW: 2 Druckertreiber für 1 Drucker?
 
Ob das jetzt alles ist, kann ich auf die Schnelle nicht sagen.

Delphi-Quellcode:
i := Printer.Printers.IndexOf(Drucker);
if i >= 0 then begin
  Printer.PrinterIndex := i;
  {$IF CompilerVersion <= 16}  // k.A. ab wann es genau wieder funktioniert
  SetPrinterFromData; // richtigen Printer anhand des PrinterIndex setzen
  {$IFEND}
end;
Das war praktisch der hauptsächliche Code, welchen auch vom Printterdialog ausgeführt wird.
Delphi-Quellcode:
procedure GetPrinter(var DeviceMode, DeviceNames: THandle);
var
  Device, Driver, Port: array[0..1023] of char;
  DevNames: PDevNames;
  Offset: PChar;
begin
  Printer.GetPrinter(Device, Driver, Port, DeviceMode);
  if DeviceMode <> 0 then
  begin
    DeviceNames := GlobalAlloc(GHND, SizeOf(TDevNames) +
     StrLen(Device) + StrLen(Driver) + StrLen(Port) + 3);
    DevNames := PDevNames(GlobalLock(DeviceNames));
    try
      Offset := PChar(DevNames) + SizeOf(TDevnames);
      with DevNames^ do
      begin
        wDriverOffset := Longint(Offset) - Longint(DevNames);
        Offset := StrECopy(Offset, Driver) + 1;
        wDeviceOffset := Longint(Offset) - Longint(DevNames);
        Offset := StrECopy(Offset, Device) + 1;
        wOutputOffset := Longint(Offset) - Longint(DevNames);;
        StrCopy(Offset, Port);
      end;
    finally
      GlobalUnlock(DeviceNames);
    end;
  end;
end;


procedure SetPrinter(DeviceMode, DeviceNames: THandle);
var
  DevNames: PDevNames;
begin
  DevNames := PDevNames(GlobalLock(DeviceNames));
  try
    with DevNames^ do
      Printer.SetPrinter(PChar(DevNames) + wDeviceOffset,
        PChar(DevNames) + wDriverOffset,
        PChar(DevNames) + wOutputOffset, DeviceMode);
  finally
    GlobalUnlock(DeviceNames);
    GlobalFree(DeviceNames);
  end;
end;


function CopyData(Handle: THandle): THandle;
var
  Src, Dest: PChar;
  Size: Integer;
begin
  if Handle <> 0 then
  begin
    Size := GlobalSize(Handle);
    Result := GlobalAlloc(GHND, Size);
    if Result <> 0 then
      try
        Src := GlobalLock(Handle);
        Dest := GlobalLock(Result);
        if (Src <> nil) and (Dest <> nil) then Move(Src^, Dest^, Size);
      finally
        GlobalUnlock(Handle);
        GlobalUnlock(Result);
      end
  end
  else Result := 0;
end;


procedure THauptForm.SetPrinterFromData;
var
  PrintDlgRec: TPrintDlg;
  DevHandle: THandle;
begin
  FillChar(PrintDlgRec, SizeOf(PrintDlgRec), 0);
  with PrintDlgRec do
  begin
    lStructSize := SizeOf(PrintDlgRec);
    hInstance := SysInit.HInstance;
    GetPrinter(DevHandle, hDevNames);
    hDevMode := CopyData(DevHandle);
    Flags := PD_ENABLESETUPHOOK or PD_PRINTSETUP;
    //lpfnSetupHook := DialogHook;
    //hWndOwner := Application.Handle;
    //Result := TaskModalDialog(@PrintDlg, PrintDlgRec);
    SetPrinter(hDevMode, hDevNames)
  end;
end;

Mattze 22. Jun 2014 11:04

AW: 2 Druckertreiber für 1 Drucker?
 
Hallo himitsu,

vielen Dank!
Probiere ich gleich mal
Falls das nicht alles sein sollte, werde ich das schon hinkriegen.
Du hast mir ja damit den Weg gezeigt.

Ich hatte das nun über die Registry gemacht. Das geht natürlich auch, aber so richtig schön finde ich das nicht. MS gibt sich ja auch das Recht, die zu ändern.

Gruß
Mattze

Sir Rufo 22. Jun 2014 11:31

AW: 2 Druckertreiber für 1 Drucker?
 
Zitat:

Zitat von Mattze (Beitrag 1263173)
Ich hatte das nun über die Registry gemacht. Das geht natürlich auch, aber so richtig schön finde ich das nicht. MS gibt sich ja auch das Recht, die zu ändern.

Was doch auch völlig in Ordnung ist, denn in der Registry speichern die diese Informationen (irgendwo müssen die ja gespeichert werden) auf eine Art und Weise und Ort wie es beliebt, weil es eben nur ein beliebiger Ort zum Speichern von Informationen ist und eben keine Schnittstelle (API) um an diese Informationen zu gelangen.

Viele Programmierer machen aber genau das, was genau so schlimm ist, wie die Daten im Anwendungsverzeichnis zu speichern, die TaskBar über FindWindow zu ermitteln .... könnte endlos fortgesetzt werden.

Mattze 22. Jun 2014 13:15

AW: 2 Druckertreiber für 1 Drucker?
 
Hallo Sir Rufo,

natürlich ist das völlig richtig!
Da habe ich wohl missverständlich formuliert.

Alles andere hätte mich auch sehr gewundert. Schließlich ist die Systementwicklung nicht abgeschlossen und wer weiß schon was die Zukunft bringt.

Gruß
Mattze

Mattze 23. Jun 2014 14:45

AW: 2 Druckertreiber für 1 Drucker?
 
Hallo himitsu,

das tut es leider auch nicht.
Ich kann sogar bei meinem Delphi 7 pro keinen Unterschied entdecken, ob ich das nun mit dem Bugfix oder ohne mache.

Nochmals mein Problem:
Printer.getprinter will neben dem Namen und dem Devicemode - was OK ist - auch den Treiber und den Port liefern.
Tut es aber bei mir nicht! Das ist immer leer.

Evtl. liegt das aber auch daran, dass ich D7 pro unter Win 7 pro 64 und höher mache.
Leider habe ich nix 32-bittiges zum Probieren in der Nähe.

Ich habe es ja über die Registry gemacht und das geht auch gut.
Trotzdem, nur interessenhalber - was sollen die Parameter in der Prozedur, wenn sie sowieso immer leer sind?

Gruß
Mattze


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz