Delphi-PRAXiS
Seite 1 von 2  1 2      

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 Eigene Instanz von Printers / Fragen zum Druck (https://www.delphipraxis.net/114840-eigene-instanz-von-printers-fragen-zum-druck.html)

Assertor 1. Jun 2008 13:19


Eigene Instanz von Printers / Fragen zum Druck
 
Hi,

eine kurze Frage zu Printers: Kann man mit
Delphi-Quellcode:
function SetPrinter(NewPrinter: TPrinter): TPrinter;
eine lokal begrenzte Instanz eines Printers erzeugen?

Ich muß z.B. in einem Thread dauernd auf einem vorgegeben Drucker drucken, dies soll sich aber mit einem manuellen Druck des Users aus der GUI nicht in die Quere kommen.

Ich brauch also einen PrinterDialog, der nur den "lokalen" Drucker ändert und dann darauf drucken kann, aber damit nicht das Ziel des Thread-Drucks ändert.

Zusätzlich befürchte ich Probleme/Exceptions, wenn der Thread gerade auf Drucker XYZ druckt, aber der User per GUI auch auf Drucker XYZ drucken will. Das wird Printers.pas wohl überfordern...

Wie würdet Ihr das machen? mit Enter/LeaveCritical pro Print-Job/Seite und jedesmal das Globale Objekt ändern und prüfen?

OH und Suche ist hier etwas ungenau.

Gruß Assertor

Hansa 1. Jun 2008 13:24

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Hier werden einige noch besser polierte Glaskugeln haben. 8) Aber was ist ein "Thread-Druck" ? :shock: Es gibt Printjobs, die werden in der Reihenfolge ihres Eingangs beim Drucker gedruckt. Wo liegt das Problem ?

rotfc 1. Jun 2008 13:29

Re: Eigene Instanz von Printers / Fragen zum Druck
 
So auf die Schnelle mal einen PDF-Drucker(treiber) temporär/silent installieren?

Wäre ganz gewiss nicht die feine Art!

Assertor 1. Jun 2008 14:35

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Hi,

Zitat:

Zitat von rotfc
So auf die Schnelle mal einen PDF-Drucker(treiber) temporär/silent installieren?
Wäre ganz gewiss nicht die feine Art!

Da sag ich mal: Nein. So auf die schnelle hat die Anwendung garantiert nicht ausreichende (Admin) Rechte auf jedem PC ;)

Zitat:

Zitat von Hansa
Hier werden einige noch besser polierte Glaskugeln haben. 8) Aber was ist ein "Thread-Druck" ?

Hmm, nochmal:
Zitat:

Zitat von Assertor
Ich muß z.B. in einem Thread dauernd auf einem vorgegeben Drucker drucken [...] Thread-Drucks ändert.

Also, sollte klar sein, daß ich hier mit einem Thread-Druck den Druck in aus einem Thread meine. Steht da ja auch ;)

Warum überhaupt Glaskugel, ich hab doch alles nötige geschrieben, oder?

Ok, nochmal einfach: Kann man ein eigenes TPrinter Objekt instanzieren, mit eigenem Ziel-Drucker?

Wenn ja, kann man dann durch dieses Objekt drucken und dafür einen PrintDialog verwenden, ohne Exceptions falls gleichzeitig über das globale TPrinter (Printer) Objekt gedruckt wird?

Gruß Assertor

Hansa 1. Jun 2008 18:13

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Ich verstehe das Problem immer noch nicht. Das kann man im gleichen Stil 100mal neu schreiben und dann ist das immer noch nicht zu verstehen. Es ist entsetzlich. :mrgreen: Was hat ein Druckauftrag mit was weiß ich zu tun ? Wer soll sich denn da ins Gehege kommen ?

Assertor 2. Jun 2008 08:47

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Zitat:

Zitat von Hansa
Was hat ein Druckauftrag mit was weiß ich zu tun ? Wer soll sich denn da ins Gehege kommen ?

Delphi-Quellcode:
Exception aus Printers.pas:
SPrinting          = 'Printing in progress';
Ich mach mal eine Skizze und ein paar Grundlagen für Hansa :twisted:

Anwendung XYZ
- Hauptthread / VCL: Druck an Drucker ABC / BCD / DEF (PrintDialog!) manuell durch den Benutzer möglich
- Workerthread: Automatischer Druck immer an Drucker BCD

Druck erfolgt per Printers.pas (!), es wird per XSL erzeugtes HTML gedruckt.

Wenn der Workerthread druckt, würde ein manueller Druck aus dem Hauptthread wohl die SPrintingException auslösen.

Da stellen sich mir die folgenden Fragen:
- Kann man parallel zu dem Globalen Printer-Objet eine weitere Instanz erzeugen? (natürlich)
- Kann einem PrinterDialog diese Instanz übergeben werden, damit der Drucker nur für diese Instanz ausgewählt wird?
- Kann man pro Instanz gleichzeitig drucken?

Gruß Assertor

P.S.:
Zitat:

Zitat von Hansa
Das kann man im gleichen Stil 100mal neu schreiben und dann ist das immer noch nicht zu verstehen. Es ist entsetzlich.

Teile bitte mit, was Du an meinem Stil auszusetzen hast oder nicht verstehst, gerne auch per PN. Du selbst schreibst ja gerne Telegrammstil, das ist aber ebenfalls schrecklich und unhöflich, wenn Du selbst Hilfe willst. Schließlich ist das hier kein Supportforum für Einzelne. :zwinker:

SirThornberry 2. Jun 2008 09:07

Re: Eigene Instanz von Printers / Fragen zum Druck
 
[OT]ich finds verständlich. Durch die Verwendung von Threads:
- würden ja sonst mehrere gleichzeitig auf Printers.Canvas arbeiten (der Hauptthread + der erzeugte Thread). Bei wahl des gleichen Druckers würden die Dinge dann wohl übereinander gemalt. Und während ein Thread mit auf der Canvas malt etc. und der andere Thread setzt das Printer-Object plötzlich auf einen anderen Drucker um kommt auch müll raus. Und wenn plötzlich der andere Thread ein NewPage macht landet plötzlich auch alles auf dem nächsten Blatt und das erste bleibt unvollständig.
Zudem ist unklar ob das VCL-Printers-Object Threadsafe ist.

Um das Threadsafe etc. abzusichern würde ich das Drucken im Thread in eine DLL auslagern. Diese DLL dann dynamich im Thread laden und die Druckfunktion aufrufen. Dadurch ist der Hauptthread in der DLL dieser welchen du vorher manuell gestartet hast (denn der Hauptthread ist der mit welchem die Initializations etc. abgearbeitet werden).

Assertor 2. Jun 2008 09:21

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Hi Jens,

danke für die Idee. Das alles an VCL so "Unsafe" programmiert ist :? Hätt Printers.pas schon fast der RTL zugeordnet und mich gefreut...

Ein anderer "Workaround": ich könnte ja alles was mit dem Druck zu tun hat in einer eigenen, globalen Enter/Leave-CriticalSection machen. Innerhalb der CriticalSection kann ich den bisherigen Druckernamen speichern und am Ende wieder zuweisen.

Gäbe es hier Nachteile (außer möglicher Deadlocks)?

Gruß Assertor

SirThornberry 2. Jun 2008 09:31

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Nachteile sind das es nicht Threadsafe sein könnte.
In der VCL baut vieles auf das Application-Object etc. auf. Wenn man jetzt eine Komponente innerhalb eines Threads erzeugt und diese greift auf das Application-Object zu kann es zu lustigen Effekten kommen.
Die CriticalSection wäre eine Lösung wenn Printers Threadsafe ist (vielleicht ist es das auch, müsste man mal den Quelltext anschauen). Aber wie du schon sagtest macht der Thread dann nicht mehr viel Sinn wenn der Hauptthread plötzlich still steht weil er am Enter einer CriticalSection wartet während der Thread gerade druckt.

sx2008 3. Jun 2008 07:05

Re: Eigene Instanz von Printers / Fragen zum Druck
 
Man ist ja nicht gezwungen die Funktion Printers() zu benützten, sondern kann ja mit FMyPrinter := TPrinter.Create ein neues Objekt anlegen, dass dann auch ein eigenes Printer-Handle hat.
Im Thread dürfen dann aber die Funktionen Printer, SetPrinter und AssignPrn nicht benützt werden, da diese die globale Variable FPrinter benützen.
Könnte nun aber sein, dass gleichzeitiges Drucken aus Hauptanwendung und Thread ein Problem ergibt, da beiden das gleiche Printer-Handle von Windows zugeteilt wird. (nur wenn der gleiche Drucker angesprochen wird)
Dann sollte der Thread so lange warten, bis der Hauptthread fertig ist:
Delphi-Quellcode:
procedure TMyThread.CheckPrn;
var
   i : Integer;
begin
  if myprinter.Handle <> Printer.Handle then Exit; // versch. Drucker -> versch. Printjobs

  // 3 Mal prüfen um die Sicherheit zu erhöhen, den Hauptthread "auf dem falschen Fuss"
  // zu erwischen
  // 
  for i := 0 to 2 do
  begin
    // Prüfen, ob Hauptthread gerade druckt
    while Printer.Printing do
       Sleep(500);
    end;
    Sleep(0); // Rechenzeit abgeben
  end;
end;
Für den Hauptthread braucht man wahrscheinlich keine Vorkehrungen zu treffen; weil wenn es dann zu einer Fehlermeldung kommt, kann der Benutzer kurz warten und den Druck erneut auslösen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:49 Uhr.
Seite 1 von 2  1 2      

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