Mehrere Dokumente hinereinander drucken

Von Ausgaben mit der Gra-Engine über Generatoren bis zum Export in diversen Formaten

Moderator: Moderatoren

notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Mehrere Dokumente hinereinander drucken

Beitrag von notloesung »

Hallo,

habe etwas was mir keine Ruhe gibt - vielleicht ist es einfach nur ein Verständnisproblem (?).

Schreibe gerade eine Anwendung die unter anderem folgendes leisten muss:
Im xbpFileDialog kann der User mehrere Dateien (bisher PDFs) auswählen.
Diese müssen dann bevor sie im Programm weiter verarbeitet werden können umgewandelt werden (das Zielformat ist TIF). Dazu nutze ich einen Druckertreiben der diese Konvertierung unterstützt.
Vom xbpFileDialog bekomme ich einen Array mit den ausgewählten Dateien. Nun will ich sie mit dem o.g. Druckertreiber drucken.
Das klappt natürlich noch nicht :cry:
Bisher gehe ich folgendermaßen vor:

Code: Alles auswählen

   IF ! empty( aFiles )

      // Printerobjekt
      oPrinter := XbpPrinter():New()
      oPrinter:create( "Universal Document Converter" )

      IF oPrinter:status() != XBP_STAT_CREATE
         Msgbox( "Fehler !!!" )
         RETURN NIL
      ENDIF

      // Auswaehlen des Druckers und Setzen der Druckparameter.
      // Feststellen, ob wirklich gedruckt werden soll.
      IF XbpPrintDialog():new():create():display(oPrinter) == NIL
         lPrint := .F.
      ELSE
         lPrint := .T.
      ENDIF

      IF lPrint
         FOR i := 1 TO LEN( aFiles )
            // an dieser Stelle will ich nun alle ausgewählten
            // Dateien drucken - aber wie funktioniert das?
            oPrinter:startDoc()
            oPrinter:endDoc()
         NEXT
      ENDIF

   ENDIF
Mir ist einfach noch nicht klar ob das so funktionieren kann.
Vielleicht hat einer den entschiedenen Tipp für mich?

Danke,
Notloesung
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hi,

meiner Meinung nach bist du auf dem richtigen Weg. Jetzt musst du nur noch die Ausgabe zwischen den Startdoc() und Enddoc() machen. Hier kann ich dir aber nicht weiter helfen, da ich diese Ausgabe nicht nutze und mit Reportgenerator arbeite.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

der XbpPrinter kann keine PDF Dokumente drucken.
Du must über RunShell() mit den richtigen Parametern (welche???) ein Programm aufrufen das das kann. z.B. acrobat reader
Wenn du syncron aufrufst kannst du das Ergebnis noch kontrollieren.
oder
du nutzt ein ActiveX Control (acrobat reader). Da gibt es unter der 1.90 AcitveX ein Beispiel. Ob das jetzt auch druckt weiß ich nicht, aber das müsste ja dann auch zu meistern sein.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

brandelh hat geschrieben: Da gibt es unter der 1.90 AcitveX ein Beispiel. Ob das jetzt auch druckt weiß ich nicht, aber das müsste ja dann auch zu meistern sein.
Ok, ich schaue mir das Bsp. mal an.
Irgendwie habe ich befürchtet das dass nicht ohne Umwege funktionieren kann :roll:

Notloesung
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Hallo,

ich glaube Du gehst von falschen Voraussetzungen aus. XbpPrinter kann keine Dokumente/Bilder/etc. ausdrucken. Außer Du fügst Sie in den PresSpace ein, der den Ausdruck beinhaltet.

Du müstest also die Tifs da rein legen, dann müsste es mit dem Drucken klappen.

Aber warum druckst Du die pdf nicht direkt über ActiveX oder RunShell aus? Dann sparst Du Dir auch die konvertiererei.

Jan


Edit: Na toll, Hubert hatte die schnelleren Finger. Man sollte halt keine Kundengespräche während des Schreibens annehmen 8)
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Jan hat geschrieben:Aber warum druckst Du die pdf nicht direkt über ActiveX oder RunShell aus? Dann sparst Du Dir auch die konvertiererei.
Hallo Jan,

das mit ActiveX würde mich brandend interessieren.
Leider finde ich bisher noch kein brauchbares Beispiel dafür.
Bis dato habe ich nichts Großartiges mit ActiveX gemacht,
würde mich aber gern der Herausforderung stellen.

Um das mit RunShell zu machen fehlt mir einfach die Erfahrung wie ich das mit einem Druckertreiber bewältigen könnte, was aber ‚ne tolle Sache währe.

Vielleicht hast du mal einen Tipp für mich wie ich dass angehen könnten.

Gruß,
Notloesung
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Moin,
versuche es mal damit:


Code: Alles auswählen


DLLFUNCTION FindExecutableA( cFileExtention, cPath, @cExe ) USING STDCALL FROM SHELL32.DLL
DLLFUNCTION ShellExcuteA( nWinHandle,  cMode, cExe, cFile, cDir, nShow) USING STDCALL FROM SHELL32.DLL


#define SHELL_OPEN      "open"
#define SHELL_PRINT     "print"
#define SHELL_EXPLORE   "explore"

// ShowWindow Modes
#define SW_HIDE             0
#define SW_SHOWNORMAL       1
#define SW_NORMAL           1
#define SW_SHOWMINIMIZED    2
#define SW_SHOWMAXIMIZED    3
#define SW_MAXIMIZE         3
#define SW_SHOWNOACTIVATE   4
#define SW_SHOW             5
#define SW_MINIMIZE         6
#define SW_SHOWMINNOACTIVE  7
#define SW_SHOWNA           8
#define SW_RESTORE          9
#define SW_SHOWDEFAULT      10

Func PrintPdf( cPdfFile )

if file( cPdfFile )
   RunDefaultShellProg( cPdfFile, SHELL_PRINT, SW_HIDE )
endif
Return ( NIL )

FUNC RunDefaultShellProg(cFile, cMode, nShow)
LOCAL cPath :=""
Local  cExe := space(256)
LOCAL nPos, nRet

   nPos := rat("\", cFile)
   if nPos > 0
      cPath := substr(cFile, 1, nPos)
      cFile := substr(cFile, nPos+1)
   endif

   nRet := FindExecutableA(cFile, cPath, @cExe)
   if nRet <= 32
      RETURN nRet
   endif

   nRet := ShellExecuteA(AppDesktop():getHWnd(), cMode, cExe, cFile, cPath, nShow)
RETURN nRet 
Gruß, Olaf
Zuletzt geändert von Lewi am Di, 13. Mär 2007 14:15, insgesamt 1-mal geändert.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

Die Lösung von Levi holt sich die Infos, die in Windows hinterlegt sind.
Diese kann man auch direkt aus dem Dateiobjekt auslesen, falls man die Parameter wissen will:

Explorer - Extras - Ordneroptionen - Dateitypen - PDF - ERWEITERT

Nun sieht man (zumindest bei mir) eine Listbox mit Vorgängen.

PRINT -> einfach drucken = ....exe" /p /h "%1"

Ich denke /P steht für drucken,
/h für Acrobat nicht anzeigen
"%1" hier muss der komplette PDF Name mit Pfad rein, am Besten mit " wegen Blanks im Namen.

Lewis Lösung ist eleganter und vielseitiger (nicht nur PDF), aber vielleicht hilft die Info ja.
Zuletzt geändert von brandelh am Di, 13. Mär 2007 14:43, insgesamt 1-mal geändert.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

die ActiveX Variante ist nicht so berauschend.
Ich habe gerade das Xbase++ Beispiel (wieder) angesehen.
Das Öffnen des ersten Dokumentes braucht ewig.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

hier habe ich auch einige Infos zum Drucken auf bestimmten Druckern gefunden, (mehr als eigene Gedanken Stütze ;-) ):
In der Developers FAQ steht in etwa:

How To: Drucken aus der Commandozeile:

Wie in der 'Acrobat Developer FAQ' dokumentiert dient der Paramter /t dem direkten Drucken:

Drucken auf einem Netzwerkdrucker mit Druckertreiber und IP-Adresse:

Code: Alles auswählen

AcroRd32.exe /t "C:\test.pdf" "\\servername\printername" "AdobePS Tektronix Phaser 840" "123.45.678.910"
oder auch nur auf den Drucker ohne Treibername und ohne IP:

Code: Alles auswählen

AcroRd32.exe /t "C:\test.pdf" "\\servername\printername"
und hier stehen diese Infos:

http://support.adobe.com/devsup/devsup. ... /52080.htm

ich hatte einmal ein PDF mit anderen Parametern, dieses ist aber nicht mehr verfügbar.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Lewi hat geschrieben:

Code: Alles auswählen

RunDefaultShellProg( cPdfFile, SHELL_PRINT, SW_HIDE )
Hallo Olaf,

der obere Aufruf funktioniert bei mir noch nicht. Merkwürdig ist dass absolut nichts passiert. Kein Druck und keine Fehlermeldung.
Das hier funktioniert dagegen einwandfrei:

Code: Alles auswählen

RunDefaultShellProg( cPdfFile, SHELL_OPEN, SW_SHOWDEFAULT )
Woran mag das wohl liegen?

Wie ich eben gesehen habe ist der Rückgabewert von ShellExecuteA 31. Da schint etwas nicht zu stimmen(?).

Gruß,
Notloesung
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

ruf es doch mal sichtbar auf. Also SW_HIDE durch SW_SHOWDEFAULT ersetzen. Eventuell sieht du dann eine Fehlermeldung.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

brandelh hat geschrieben:ruf es doch mal sichtbar auf. Also SW_HIDE durch SW_SHOWDEFAULT ersetzen. Eventuell sieht du dann eine Fehlermeldung.
Hallo,

ups, das habe ich vergessen zu erwähnen.
Das habe ich schon probiert. Es ändert nichts am Verhalten.

Der Rückgabewert von ShellExecuteA ist immer 31.
Laut der Microsoft Doku ist es folgendes:
aus: http://www.microsoft.com/germany/msdn/library/visualtools/vb6/AusVisualBasicHerausDokumenteInZugehoerigenAnwendungenOeffnen.mspx?mfr=true hat geschrieben:Die Funktion ShellExecute berichtet in ihrem Rückgabewert über den Erfolg des versuchten Aufrufs: Ist der Rückgabewert größer als 32, war der Aufruf erfolgreich. Besondere Aufmerksamkeit verdient dabei der Rückgabewert 31, dem der symbolische Konstantenname SE_ERR_NOASSOC zukommt: Gibt ShellExecute diesen Wert zurück, so besteht keine Anwendungs-Zuordnung zwischen dem angegebenen Dateityp und einem Anwendungsprogramm.
Das kann aber nicht passen. Die Parameter beim Aufruf stimmen. Immerhin kann die Datei ja geöffnet werden.

Notloesung
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo,

der Rückgabewert 31 (SE_ERR_NOASSOC) bedeutet laut MSDN

"Mit der gegebenen Dateinamenserweiterung ist keine Anwendung verknüpft. Dieser Fehler wird auch zurückgegeben, wenn man eine nicht druckbare Datei zu drucken versucht."

Kommt der Fehler von ShellExecuteA(), oder bereits von FindExecutableA() ?


Gruß,
Günter
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Sorry, ich hatte den Code nicht getestet. Dies habe ich jetzt nachgeholt und meine Lösung korrigiert. Mit dem nachfolgenden Code kann ich drucken:

Code: Alles auswählen

DLLFUNCTION ShellExecuteA( nWinHandle,  cMode, cFile, cDir, nShow) USING STDCALL FROM SHELL32.DLL


#define SHELL_OPEN      "open"
#define SHELL_PRINT     "print"
#define SHELL_EXPLORE   "explore"

// ShowWindow Modes
#define SW_HIDE             0
#define SW_SHOWNORMAL       1
#define SW_NORMAL           1
#define SW_SHOWMINIMIZED    2
#define SW_SHOWMAXIMIZED    3
#define SW_MAXIMIZE         3
#define SW_SHOWNOACTIVATE   4
#define SW_SHOW             5
#define SW_MINIMIZE         6
#define SW_SHOWMINNOACTIVE  7
#define SW_SHOWNA           8
#define SW_RESTORE          9
#define SW_SHOWDEFAULT      10


Func PrintPdf( cPdfFile )

if file( cPdfFile )
   RunDefaultShellProg( cPdfFile, SHELL_PRINT, SW_HIDE )
endif
Return ( NIL )

FUNC RunDefaultShellProg(cFile, cMode, nShow)
   LOCAL  nRet

   nRet := ShellExecuteA(AppDesktop():getHWnd(), cMode, cFile, "", nShow)

  If ! (nret > 32)
   Msgbox("Fehlercode: " + Str( nRet ))
endif

RETURN nRet
Gruß, Olaf
Zuletzt geändert von Lewi am Mi, 14. Mär 2007 9:02, insgesamt 1-mal geändert.
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Günter Beyes hat geschrieben:Kommt der Fehler von ShellExecuteA(), oder bereits von FindExecutableA() ?
Hi,

der Fehler wir erst von ShellExecuteA verursacht.

Gruß,
Notloesung
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hmm.

Erscheint beim Rechtsklick auf die PDF-Datei der Eintrag "Drucken" im Kontextmenü, und druckt es, wenn du ihn aufrufst?

Ist der Defaultdrucker bereit?

Günter
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Moin Günter,
mit dem korrigiertem Code sollte man eine PDF-Datei drucken können, wenn Acrobat auf dem Rechner installiert ist.

Der Fehler war, das der Aufruf "FindExcutable" in Zusammenhang mit "SW_PRINT" der falsche Ansatz ist.

Sobald sich über das Kontext-Menu über "drucken" eine Datei drucken lässt, sollte der neue Code funktionieren.

Gruß, Olaf

PS: Wie geschrieben, bei mir funktioniert die Lösung!
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hallo,

gibt es hierzu nicht eine Methode von xbase?? xbppdf oder so ähnlich
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

es gibt einen Zusatzbibliothek XppPDF, die wird aber nicht zum Drucken von bestehenden PDFs verwendet, sonder zum Erstellen von neuen PDFs ohne einen PDF-Druckertreiber.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Hallo,

mit der Lösung von Olaf komme ich wunderbar hin.
Zumal es eben (fast) universell einsetzbar ist. Es lassen sich z.B. Word-Dokumente, .TXT-Dateien und vieles mehr auf die Selbe Art und Weise drucken.

Folgendes bekomme ich noch nicht hin:
Das Drucken klappt wie gesagt auch z.B. aus Word. Dabei wird Word kurz geöffnet, der Druck gestartet und Word schließt sich wieder automatisch. Bei Acrobat klappt das Schließen nicht automatisch. Bei Pdfs wird der Acrobat geöffnet, der Druck angestoßen aber der Acrobat schließt sich nicht automatisch – muss also manuell geschlossen werden. (Das gleiche Verhalten ist zu beobachten wenn aus dem Explorer (rechte Maustaste – Drucken) gedruckt wird.
Gibt es da wohl etwas Spezielles zu beachten?


Eine andere Sache beschäftigt mich noch mehr:
Wenn das Drucken mit der „Olafschen-Methode“ :) ausgelöst wird, so wird immer über den Standard Drucker gedruckt.
Mein Druck muss immer über einen speziellen Drucker laufen, der nicht unbedingt der Standarddrucker sein muss.
Gibt es eine Möglichkeit abzufragen welcher Drucker auf dem Rechner der Standarddrucker ist. Ich denke daran im Programm abzufragen ob der Drucker XYZ der Standarddrucker ist. Falls nicht dann würde ich mir gerne den Standarddrucker merken, den Drucker XYZ als Standarddrucker definieren, den Druck anstoßen und danach den vorherigen Drucker wieder als Standarddrucker setzen. Ist wohl so etwas möglich?

Gruß,
Notloesung
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16514
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jarek,
das geht wunderbar mit der PrinterAPI, die Du auf der Seite von Phil Ide findest.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Eine Lösung zum automatischem Beenden von Anwenungen hat Jimmy gepostet: http://www.xbaseforum.de/viewtopic.php?t=947

Für das automatische Beenden von Acrobat nach dem Drucken sollte Dir der Lösungsansatz von Jimmy weiter helfen.

Gruß, Olaf
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hallo notloesung,


du kannst ja beim drucken mit xbpprintdialog arbeiten. Dann werden die installierten Drucker angzeigt, bei dem du dann den Drucker auswählen kannst.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hallo Rolf,
die xbpPrinterDialog()-Klasse wird hier nicht weiter helfen, da der Druck über eine API-Funktion erfolgt. Der Einsatz dieser Klasse macht nur dann Sinn, wenn der Duck über ein xBase Presentation-Space Object (mittels Verknüpfung eines Druckers zu einem Presentation space) erfolgt.

Oder anders gesagt, über xbpPrinterDialog() kann ein Drucker nicht zum Windows Standard-Drucker gesetzt werden.

Gruß, Olaf
Antworten