Seite 1 von 1

PDF-Druck und Pfad der PDF

Verfasst: Do, 26. Sep 2013 21:34
von Werner_Bayern
Servus,

hatte gerade das Problem, dass bei einem PDF-Druck (also über einen PDF-Drucker) ich zwar bei :startdoc() den Namen der PDF vorgeben kann, jedoch nicht den Pfad. Da wird i. d. R. ja je nach PDF-Drucker der zuletzt verwendete Pfad hergenommen oder auch schon mal Dokumente.
Übergibt man an :startdoc() den kompletten Pfad inkl. Dateiname, wird der Pfad ignoriert.

Die Lösung war:

Code: Alles auswählen

oDrucker:setPrintFile(cPfad + cPFD)
oDrucker:startDoc()
Dann kommt nicht mal mehr die Abfrage nach dem Dateinamen, man kann sich deshalb darauf verlassen, wo die PDF mit welchem Namen landet.

Falls es jemand interessiert...

Re: PDF-Druck und Pfad der PDF

Verfasst: Fr, 25. Mär 2016 18:35
von MichaMB
Hallo Werner und die lieben anderen Spezialisten,

nach 3 Tagen vergeblicher Suche...
zur Info: Nachdem ich mal alle Druckerfeatures von Hubert installiert hatte, funktionierte mein Anliegen für den Test-Druck, allerdings meine ganzen bisherigen Druck-Ausgaben nicht mehr, da ich noch die Programme von DBASE III und Clipper übernommen habe. ALso muss es eine Lösung für das bisherige Migrate (dort sind die Druckroutinen hinterlegt) geben. Vermutlich wird aber gerade dort die gesuchte Kombination ausgeschlossen.
Ich nutze die Druckerauswahl und den Druck mit @ say und auch Grafik bisher ohne den Befehl startDoc endDoc, obwohl diese Befehle vorhanden sind.
alles funktioniert bisher reibungslos, ob set Printer to (File) für *.TXT in einem bestimmten Verzeichnis oder eben verschiedene Drucker über das Auswahlfenster.

Nun wollte ich den PDF_Druck noch komfortabler gestalten um z.B. einen Druck in eine *. PDF in einem festen Verzeichnis umzuleiten..... (wie gesagt mit *.TXT geht das schon aber ohne Logos etc.)
Statt der Auswahl im Druckerfenster von Windows wollte ich einen PDF-Drucker z.B. den WINDOWS 10 Drucker "Microsoft Print to PDF" im Programm vorgeben, das habe ich auch noch hinbekommen, ohne dass der Drucker gesucht wird, aber es geht zum PDF-Druck immer ein Fenster auf und ich muss entweder einen vorhandenen File-Namen anklicken und überschreiben oder den Namen der Datei selbst in das Browserfenster eingeben.... oder schlimmstenfalls das Verzeichnis neu auswählen...

Code: Alles auswählen

         if upper(PDFDRU1) = "J"
  Local   XbpPrinter, xPrinter, cPfad, cPFD, oPrinter, MyPrinter2, oDrucker    
  
          #define GRAPHICS_PRINTER
            #include "migrate.ch"
            #PRAGMA LIBRARY( "XPPUI2.LIB" )
            oDlg := XbpPrintDialog():new()
            oDlg:create()
            oPrt := &PDF_DRUCKER    // PDF Druckername "Microsoft Print to PDF" in Datei mit '"' gespeichert
            IF oPrt == NIL
              MsgBox( "No printer selected" )
              return
            ENDIF

            SET DEVICE TO PRINTER
            SET PRINTER TO OBJECT oPrt
          else
            #define GRAPHICS_PRINTER
            #include "migrate.ch"

            #PRAGMA LIBRARY( "XPPUI2.LIB" )
            // Select printer to send output to
            oDlg := XbpPrintDialog():New():Create()
            oPrt := oDlg:Display()
            IF oPrt == NIL
              MsgBox( "No printer selected" )
              return
            ENDIF
            SET DEVICE TO PRINTER
            SET PRINTER TO OBJECT oPrt
          endif

          oPrt := oPrinter  // habe ich mal zusätzlich versucht

          cPfad := "c:\PDF\VM_INTERNET\"

          cPFD  := "Einzel_" + ConvToAnsiCP(rtrim(Kuntext1)) + ".pdf"

          oPrinter:setprintfile(CPfad + cPFD)
          oPrinter:startDoc(kuntext1) // müsste doch wenigsten den File-Namen übergeben?

Fehler: setprintfile ist kein Objekt 

Daten sind in der Datei, alles ok, bei einer anderen Methode wurde zwar die PDF im richtigen Verzeichnis angelegt mit dem richtigen Namen aber es waren keine Daten vorhanden.

Re: PDF-Druck und Pfad der PDF

Verfasst: Fr, 25. Mär 2016 18:43
von MichaMB
hier noch der Code von der Migrate.ch

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////////
//
// Defines for the graphic mode report migrator.
//
// Copyright (c) 2014, Alaska Software. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////
#ifndef __MIGRATE_CH__
#define __MIGRATE_CH__

// PreProcessor directives used to hook into
// EJECT @ , SAY commands
//
#ifdef GRAPHICS_PRINTER

#command  SET DEVICE TO SCREEN       =>  Set( _SET_DEVICE, "SCREEN" );;
                                         ResetGraphicsPrinter()

#command  SET DEVICE TO PRINTER      =>  Set( _SET_DEVICE, "PRINTER" );;
                                         SetGraphicsPrinter()

#command  SET PRINTER TO OBJECT <o> ;
      =>  IF IsPrinter();;
             GetPrinter():SetPrinter(<o>);;
          ELSE ;;
             Set( _SET_PRINTFILE, <o> );;
          ENDIF

#command  SET PRINTER TO PRESSPACE <o> ;
      =>  IF IsPrinter();;
             GetPrinter():SetPresSpace(<o>);;
          ENDIF

#command  RESET PRINTER <o> ;
      =>  IF IsPrinter();;
             GetPrinter():Reset(<o>);;
          ENDIF

#command  EJECT ;
      =>  IIF(IsPrinter(),GetPrinter():Eject(),_Eject())

#command  @ <nRow>, <nCol> SAY <say> [PICTURE <pic>] [COLOR <Color>] ;
      =>  IF IsPrinter();;
             GetPrinter():AtSayPict(<nRow>, <nCol>,<say>,<pic>);;
          ELSE ;;
             DevPos(<nRow>, <nCol>) ;;
             DevOutPict(<say>, <pic> [,<Color>]);;
          ENDIF
#command  @ <nRow>, <nCol> SAY <say> [COLOR <Color>] ;
      =>  IF IsPrinter();;
             GetPrinter():AtSay(<nRow>, <nCol>,<say>);;
          ELSE ;;
             DevPos(<nRow>, <nCol>) ;;
             DevOut(<say> [,<Color>]);;
          ENDIF

#command  ?  [<list,...>]  ;
      =>  IIF(IsPrinter(),GetPrinter():Qout( <list> ),QOUT( <list> ))
#command  ?? [<list,...>]  ;
      =>  IIF(IsPrinter(),GetPrinter():QQout( <list> ),QQOUT( <list> ))


#command  @ <nT>, <nL> IMAGE <cFile> ;
      =>  GetPrinter():DrawImage( <cFile>, <nT>, <nL> )
#command  @ <nT>, <nL>, <nB>, <nR> IMAGE <cFile> ;
      =>  GetPrinter():DrawImage( <cFile>, <nT>, <nL>, <nB>, <nR> )

#xtrans  MaxRow()   => IIF(IsPrinter(),GetPrinter():MaxRow,&("MaxRow()"))
#xtrans  MaxCol()   => IIF(IsPrinter(),GetPrinter():MaxRow,&("MaxCol()"))

#endif

#endif
und der Teil-code von der Migrate.prg

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////////
//
// Classes and functions used to implement the graphic mode report
// migrator.
//
// Copyright (c) 2014, Alaska Software. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////
#include "gra.ch"
#include "set.ch"
#include "xbp.ch"


//*#### ANSI .t. äöü ÄÖÜ ß !!!!

#include "Common.ch"
#include "Appevent.ch"
#include "Font.ch"
#include "XBPDEV.ch"




#define TEXT_DATA         1
#define IMAGE_DATA        2

#define  DRIVE_NOT_READY    21         // Fehlercode

STATIC GraphicPrinterObj := NIL

PROCEDURE MIGRATE
// Fehlende Prozeduren und Funktionen
// fehlende Prozeduren oder Funktionen werden als selbst. Prozeduren (*.prg) nachdem return eingefgt  und mssen somit nicht extra compiliert werden
// alle Functionen oder Prozeduren enden mit Return

RETURN


FUNCTION IsPrinter()

  IF GraphicPrinterObj == NIL
     IF "LPT" $ Set(_SET_PRINTFILE)   .AND.;
        Set(_SET_DEVICE) == "PRINTER" .AND.;
        GraphicPrinterObj== NIL
        MyPrinter2():RunReport()
     ENDIF
  ENDIF

RETURN (GraphicPrinterObj != NIL)

FUNCTION GetPrinter()
RETURN GraphicPrinterObj

FUNCTION SetGraphicsPrinter()
  IF(ValType(GraphicPrinterObj)=="O")
    RETURN(NIL)

  ENDIF
  MyPrinter2():RunReport()
RETURN(NIL)


FUNCTION ResetGraphicsPrinter()
  IF(ValType(GraphicPrinterObj)=="O")
    GraphicPrinterObj:Eject()
    GraphicPrinterObj:Destroy()
    GraphicPrinterObj := NIL
  ENDIF
RETURN(NIL)

#define PAGE_WIDTH       78
#define LINES_PER_PAGE   ZEILENDE  // ist Public-Variable "Zeilende" aus Programm Main Global
                                   // wird im Druckmenue aus Datenbank eingestellt

// This class is used to render our report for
// the graphic printer.
//
CLASS MyPrinter2
  CLASS VAR oPS
  CLASS VAR aData
  CLASS VAR oPrinter
  CLASS VAR aSize
  CLASS VAR nDX
  CLASS VAR nDY
  CLASS VAR lInternalPS
  CLASS VAR lInternalPrinter
  CLASS VAR IsOpenStartDoc       // .t. after Startdoc(), .f. after Enddoc()
  CLASS VAR cPrinterShowText     // Parameter merken von ::StartDoc(cText) - store cText parameter
 PROTECTED:
  CLASS METHOD PrintEsc()
 EXPORTED:
  CLASS VAR Header

  CLASS ACCESS METHOD GetMaxRow() VAR MaxRow
  CLASS ACCESS METHOD GetMaxCol() VAR MaxCol

  CLASS ACCESS METHOD GetFont()   VAR Font

  CLASS METHOD Init()
  CLASS METHOD AtSay()
  CLASS METHOD AtSayPict()
  CLASS METHOD Eject()
  CLASS METHOD SetFont()
  CLASS METHOD QOut()
  CLASS METHOD QQOut()
  CLASS METHOD startDoc()
  CLASS METHOD endDoc()
  CLASS METHOD newPage()

  CLASS METHOD DrawImage()

  CLASS METHOD RunReport()
  CLASS METHOD Destroy()

  CLASS METHOD SetPrinter()
  CLASS METHOD SetPrintFile()
  CLASS METHOD SetPresSpace()
  CLASS METHOD Reset()
ENDCLASS


CLASS METHOD MyPrinter2:Destroy()
  IF ::lInternalPrinter == .T. .AND. ValType(::oPrinter)=="O"
    ::oPrinter:Destroy()
    ::oPrinter := NIL
  ENDIF
  IF ::lInternalPS == .T. .AND. ValType(::oPS)=="O"
    ::oPS:Destroy()
    ::oPS := NIL
  ENDIF
RETURN

// initialize printer if name or object given
// dedicated printer is selected. MaxRow and
// MaxCol are used to determined space between
// lines and to calculate the position if
// @ row,col SAYs
//
CLASS METHOD MyPrinter2:Init(xPrinter,nMaxRow,nMaxCol)
  LOCAL aSize
  LOCAL cType := ValType( xPrinter )

  IF cType $ "CU"
     ::oPrinter := XbpPrinter():New()
     ::oPrinter:Create( xPrinter )
     ::lInternalPrinter := .T.
  ELSEIF cType == "O"
     ::oPrinter := xPrinter
     ::lInternalPrinter := .F.
  ENDIF

  IF ::oPS == NIL
  ::oPS := XbpPresSpace():New()
  ::lInternalPS := .T.
  ENDIF

  ::Reset()

  IF ::lInternalPS == .T.
  ::oPS:Create( ::oPrinter , ::aSize, GRA_PU_LOMETRIC )
  ENDIF

  ::aData := {}
RETURN(SELF)


// Change the associated printer to a
// printer selected by the application.
// All output using @..SAY directly goes
// to this printer from now on
CLASS METHOD MyPrinter2:SetPrinter( oPrt )
 LOCAL oFnt := ::oPS:SetFont()
   ::Destroy()
   ::Init( oPrt )
   IF ValType(oFnt) == "O"
      ::SetFont( LTrim(Str(oFnt:NominalPointSize)) + "." + oFnt:FamilyName )
   ENDIF
RETURN

//------------------------------------------------------------ // neu hinzugefügt, war nicht vorhanden
CLASS METHOD MyPrinter2:setPrintFile( cFileName )
       local uReturn := NIL, oDC, nBreite,nHoehe,aPaperSize

       if ::oPS:device():isDerivedFrom( "XbpPrinter" )
          oDC := ::oPS:device()       // xbpPrinter object
       elseif ::oPrinter:device():isDerivedFrom( "XbpPrinter" )
          oDC := ::oPrinter:device()
       endif

       if ! IsNil(oDC) .and. oDC:isDerivedFrom( "XbpPrinter" )

          if ::IsOpenStartDoc                       // ::StartDoc() ist aktiv / is active
             oDC:enddoc()                            // print
          endif
          uReturn := oDC:setPrintFile( cFileName )
          aPaperSize := oDC:PaperSize()               // hier kommen nur 6 Elemente
          nBreite := aPaperSize[5] - aPaperSize[3]    // laut DOKU sollten es 8 sein.
          nHoehe  := aPaperSize[6] - aPaperSize[4]
          ::oPS:Configure( oDC, {nBreite,nHoehe} , GRA_PU_LOMETRIC )
          ::SetInternalPageVars()
          if ::IsOpenStartDoc                       // neu öffnen - open again
             oDC:startdoc(::cPrinterShowText)
          endif
       endif

return uReturn
//-------------------------------------------------------------

// Associate an application-supplied
// Presentation Space with the line
// printer. All output using @..SAY
// goes to this PS now on
CLASS METHOD MyPrinter2:SetPresSpace( oPS )
 LOCAL oFnt := ::oPS:SetFont()

   IF oPS == ::oPS
      RETURN
   ENDIF

   ::Destroy()
   ::oPS := oPS
   ::lInternalPS := .F.

   IF ValType(oFnt) == "O"
      ::SetFont( LTrim(Str(oFnt:NominalPointSize)) + "." + oFnt:FamilyName )
   ENDIF
RETURN


// Reset the logicalcal page to cover
// the whole (possibly changed) print
// area. If <oPrt> is passed, this
// printer is set as the new output
// device.
CLASS METHOD MyPrinter2:Reset( oPrt )
  LOCAL aSize
  LOCAL nMaxRow
  LOCAL nMaxCol

  // Size of printable region on paper
  IF ValType(oPrt) == "O"
     ::SetPrinter( oPrt )
  ENDIF

//  aSize := ::oPrinter:paperSize()
    aSize := ::oPrinter:XbpPrinter:paperSize()
  ::aSize := { aSize[5] - aSize[3], ;
               aSize[6] - aSize[4]  }
  IF(nMaxRow==NIL)
    nMaxRow := LINES_PER_PAGE
  ENDIF
  IF(nMaxCol==NIL)
    nMaxcol := PAGE_WIDTH
  ENDIF

  ::nDX := Int( ::aSize[1] / nMaxCol )
  ::nDY := Int( ::aSize[2] / nMaxRow )
RETURN

// Simple Helper method used to specify Font
// for report
CLASS METHOD MyPrinter2:SetFont(cName)
  LOCAL oFont   := XbpFont():new(::oPS)

  oFont:Generic := .T.
  oFont:Vector  := .T.
  oFont:Fixed   := .T.
  oFont:FamilyName       := SubStr( cName, At(".",cName) +1 )
  oFont:nominalPointSize := Val( SubStr( cName,1, At(".",cName) -1 ) )
  oFont:Create()
  ::oPS:setFont(oFont)

  ::nDX := oFont:Width
  ::nDY := oFont:Height
RETURN


// Simply collect all output strings
CLASS METHOD MyPrinter2:AtSay(nR,nC,cText)

  // Numeric: also mit Str konvertieren damit tabellen decimals und length
  // benutzt werden
  IF(ValType(cText)=="N")
    cText := Str( cText )

  // Alle anderen nicht char typen mit Var2Char konvertieren
  // eventuell Var2LChar() dann wäre der text locale spezifisch.
  ELSEIF ValType(cText) != "C"
    cText := Var2Char( cText )
  ENDIF
  AAdd( ::aData , {TEXT_DATA, nR,nC, cText,NIL} )
RETURN


// Simply collect all output strings, include picture mask
CLASS METHOD MyPrinter2:AtSayPict(nR,nC,xExpr,cPict)
  AAdd( ::aData , {TEXT_DATA, nR,nC, Transform(xExpr,cPict)} )
RETURN

// now render the page and send it to the printer
CLASS METHOD MyPrinter2:Eject()
  LOCAL n,nMaxY, cTmp, nX, nY, nIndex

  IF(Len(::aData)==0)
    RETURN
  ENDIF

  nMaxY := ::aSize[2] - ::nDY

  // create new printer page
  IF ::lInternalPS == .T.
     ::oPS:device():startDoc()
  ENDIF
  IF(ValType(::Header)=="C")
    &(::Header)(::oPS)
  ENDIF
  FOR n:=1 TO Len(::aData)
      DO CASE
        CASE ::aData[n][1] == TEXT_DATA
          nX := ::aData[n][3]*::nDX
          nY := nMaxY - (::aData[n][2]*::nDY)
          DO WHILE .T.
             nIndex = At( Chr(27), ::aData[n][4] )
             IF nIndex > 0
                cTmp = SubStr( ::aData[n][4],1, nIndex -1 )
                ::PrintEsc( ::aData[n][4][nIndex+1] )

                // NOTE: We throw away anything right of the Escape code
                // so basically this only works if escape codes are send
                // seperately.
                // Original code was: ::aData[n][4] = SubStr( ::aData[n][4], nIndex +2 )
                ::aData[n][4] = ""
             ELSE
                cTmp := ::aData[n][4]
                ::aData[n][4] = ""
             ENDIF

             GraStringAt( ::oPS, {nX,nY}, cTmp )

             IF Len(::aData[n][4]) == 0
               EXIT
             ENDIF

             nX += Len(cTmp) * ::nDY
          ENDDO
        CASE ::aData[n][1] == IMAGE_DATA
           ::aData[n][3]:Draw( ::oPS, ::aData[n][2],,, GRA_BLT_BBO_IGNORE )
        ENDCASE
  NEXT n

  // close page and sent it to printer
  IF ::lInternalPS == .T.
     ::oPS:device():endDoc()
  ENDIF
  ::aData := {}
RETURN
//------------------------------------------------------------ // neu hinzugefügt, war nicht vorhanden
CLASS METHOD MYPrinter2:StartDoc(cText,nSetPageNo)
    local cAltDrive, cAltDir, cResetDir
    local uReturn := SELF
    aDATA := CText
    DEFAULT cText TO ::SpoolJobName
    DEFAULT nSetPageNo TO 1
    cAltDrive := curdrive()
    cAltDir   := curdir()
    ::nPageNo := nSetPageNo
    ::IsOpenStartDoc := .t.
   ::cPrinterShowText := cText


    if cAltDrive # curdrive() .or. cAltDir # curdir()
       cResetDir := cAltDrive +":\"+ cAltDir
       curdrive(cAltDrive)
       curdir(cResetDir)
    endif
return uReturn
//------------------------------------------------------------ // neu hinzugefügt, war nicht vorhanden
CLASS METHOD MyPrinter2:EndDoc()
    local uReturn := SELF
    ::IsOpenStartDoc := .f.
    if IsMethod(::oPS:device(),"EndDoc")
       uReturn := ::oPS:device():EndDoc()
    endif
return uReturn
//-------------------------------------------------------------
// now render the page and send it to the printer
CLASS METHOD MyPrinter2:newPage()
  LOCAL n,nMaxY, cTmp, nX, nY, nIndex

  IF(Len(::aData)==0)
    RETURN
  ENDIF

  nMaxY := ::aSize[2] - ::nDY

  // create new printer page
  IF ::lInternalPS == .T.
     ::oPS:device():startDoc()
  ENDIF
  IF(ValType(::Header)=="C")
    &(::Header)(::oPS)
  ENDIF
  FOR n:=1 TO Len(::aData)
      DO CASE
        CASE ::aData[n][1] == TEXT_DATA
          nX := ::aData[n][3]*::nDX
          nY := nMaxY - (::aData[n][2]*::nDY)
          DO WHILE .T.
             nIndex = At( Chr(27), ::aData[n][4] )
             IF nIndex > 0
                cTmp = SubStr( ::aData[n][4],1, nIndex -1 )
                ::PrintEsc( ::aData[n][4][nIndex+1] )

                // NOTE: We throw away anything right of the Escape code
                // so basically this only works if escape codes are send
                // seperately.
                // Original code was: ::aData[n][4] = SubStr( ::aData[n][4], nIndex +2 )
                ::aData[n][4] = ""
             ELSE
                cTmp := ::aData[n][4]
                ::aData[n][4] = ""
             ENDIF

             GraStringAt( ::oPS, {nX,nY}, cTmp )

             IF Len(::aData[n][4]) == 0
               EXIT
             ENDIF

             nX += Len(cTmp) * ::nDY
          ENDDO
        CASE ::aData[n][1] == IMAGE_DATA
           ::aData[n][3]:Draw( ::oPS, ::aData[n][2],,, GRA_BLT_BBO_IGNORE )
        ENDCASE
  NEXT n

  // close page and sent it to printer
  IF ::lInternalPS == .T.
     ::oPS:device():endDoc()
  ENDIF
  ::aData := {}
RETURN

usw...
//

Re: PDF-Druck und Pfad der PDF

Verfasst: Sa, 26. Mär 2016 14:50
von Werner_Bayern
Servus Micha,

woher kommt
SetfilePrinter
?

Kann ich in Deinem Code nicht finden.

Re: PDF-Druck und Pfad der PDF

Verfasst: Do, 31. Mär 2016 11:24
von MichaMB
Sorry Werner,
das war natürlich ein Schreibfehler in der Fehlermeldung! (habe es in der Originalanfrage geändert)
Fehlermeldung kommt:
Fehler Base/2266
Beschreibung:Empfänger der Nachrichten ist kein Objekt
Operation: setprintfile
Thread ID 1:
aufgerufen von dem Programm in der Zeile 433:
store cPfad + cPFD to wohin

//433/ oPrinter:setprintfile(wohin)
oPrinter:startDoc(kuntext1)

lg
Micha

Re: PDF-Druck und Pfad der PDF

Verfasst: Sa, 02. Apr 2016 15:44
von Werner_Bayern
Servus Micha,

komische Fehlermeldung. Entweder müsste es heißen, dass setprintfile keine Methode oder oPrinter kein Objekt ist.

Ich würde sagen, dass oPrinter kein Objekt zu dem Zeitpunkt ist. Was sagt der Debugger?

Re: PDF-Druck und Pfad der PDF

Verfasst: So, 22. Sep 2019 0:05
von Werner_Bayern
Nachtrag: Zumindest beim Adobe PDF-Drucker funktioniert setPrintFile() nicht, da es den Modus für PostScript-Dateien aktiviert.

Re: PDF-Druck und Pfad der PDF

Verfasst: Mo, 23. Sep 2019 5:15
von AUGE_OHR
MichaMB hat geschrieben:
Fr, 25. Mär 2016 18:35
aber es geht zum PDF-Druck immer ein Fenster auf und ich muss entweder einen vorhandenen File-Namen anklicken und überschreiben oder den Namen der Datei selbst in das Browserfenster eingeben.... oder schlimmstenfalls das Verzeichnis neu auswählen...
wie wäre es einen Thread zu starten der das "Fenster" sucht ...

Code: Alles auswählen

   cText := "Lieferschein " + cRgjahr + "-" + cLNr
   oPrinter:device() :startDoc( cText )
   ...
   oPrinter:device() :endDoc()
   Wait4PDF(cText)
das "Fenster" hat die Caption

Code: Alles auswählen

LOCAL cTitle   := "Druckausgabe speichern unter"
was dann aufgeht.

mit "FindWindowA" findet man ein Fenster mit der Caption und erhält das Handle des Fenster.
ein Control findet man mit "FindWindowExA" hier das Eingabefeld ("EDIT")
mit "SendMessageA" und WM_SETTEXT "schreibe" ich es in das Eingabefeld

anbei ausbaufähigem Demo Code
WAIT4PDF.ZIP
pure Xbase++ Source
(667 Bytes) 39-mal heruntergeladen
have Fun

Re: PDF-Druck und Pfad der PDF

Verfasst: Mo, 23. Sep 2019 12:37
von Werner_Bayern
Servus Jimmy,

guter Vorschlag, schaue ich mir mal an. Danke.

Re: PDF-Druck und Pfad der PDF

Verfasst: Di, 15. Okt 2019 18:49
von Bernd Reinhardt
Hallo
Wir installieren bei unseren Kunden edoc pdf printer pro. Ist ein Drucker to pdf und kostenlos.
In den Eigenschaften gebe ich ein Ziel und einen Dateinamen an z. B. d:\pdferzeugen\lieferschein.pdf
Vor dem Ausdruck lösche ich die lieferschein.pdf
Drucke auf den Drucker und warte bis die Datei lieferschein.pdf vorhanden ist und sich die Größe nicht mehr ändert.
Speichere die Datei wo ich sie brauche oder verschicke die gleich per Mail.

Kostenpflichtige Version hat auch PDF/A3 und ZUGFeRD Unterstützung
PDF Dateien können digital unterschreiben werden.

Installation geht sehr schnell.
Gruß
Bernd

Re: PDF-Druck und Pfad der PDF

Verfasst: Mi, 16. Okt 2019 9:24
von flanelli
@Bernd,
im Prinzip erledige ich das genauso, ich verwende halt den PDF-Creator und lasse das PDF
im vordefinierten ( oder auch justintime individualisierten ) Ordner erstellen und verfahre
dann mit diesem PDF je nach Gegebenheiten weiter ( kopieren, verschieben, umbenennen,
als Anhang mailen etc ).
Wichtig dabei ist, so wie du das auch angeführt hast, dass man ein eventuell vorhandenes
( also gleichnamiges ) PDF vor der Erstellung löscht.
Die Sicherheit, dass die Erstellung des PDF auch wirklich zur Gänze abgeschlossen ist,
erlange ich persönlich lieber durch eine Schleife, in der versucht wird, das PDF exclusiv
zu öffnen < check_hdl = FOpen("derdateiname.pdf",16) >
Bei einem Check auf den Stillstand der Dateigrößenänderung hätte ich ein wenig Bauchweh
denn wo setzt man da den Schwellenwert, also das Zeitlimit an, wie lange ein Stillstand der
Größe dauern muß damit man sicher sein kann, dass nichts mehr kommt?
Da kann man schon seine blauen Wunder erleben, da es ja gar nicht selten vorkommt, dass ein
Ausdruck ( aus welchen Gründen auch immer ) mal heftig ins Stocken gerät.
Aber es gibt viele Wege die nach Rom führen. Hauptsache man kommt dort sicher an.

Jedenfalls geht es mit einigen PDF-Druckern recht einfach und vor allem unsichtbar im Hintergrund
abwickelbar und wenn zudem noch eine COM-Schnittstelle existiert kommt Freude auf.

Re: PDF-Druck und Pfad der PDF

Verfasst: Mi, 16. Okt 2019 18:29
von Wolfgang Ciriack
Wichtig dabei ist, so wie du das auch angeführt hast, dass man ein eventuell vorhandenes
( also gleichnamiges ) PDF vor der Erstellung löscht.
Da kann man ja beim PDCreator die Option "vorhandene überschreiben" setzen.

Re: PDF-Druck und Pfad der PDF

Verfasst: Mi, 16. Okt 2019 23:07
von flanelli
Wolfgang Ciriack hat geschrieben:
Mi, 16. Okt 2019 18:29
Wichtig dabei ist, so wie du das auch angeführt hast, dass man ein eventuell vorhandenes
( also gleichnamiges ) PDF vor der Erstellung löscht.
Da kann man ja beim PDCreator die Option "vorhandene überschreiben" setzen.
ja natüriich kann man das machen und es wird auch in den meisten Fällen so eingestellt werden
aber in dem Moment wo die Zieldatei nicht gelöscht wird und der Druck erfolgt, hat man ein,
wenn auch nur geringes, aber immerhin mögliches Restrisiko eines fehlgeschlagenen Druckes
und es kann passieren, dass diese Datei unbeschadet mit ihrem alten Inhalt stehen bleibt.
Damit hätte diese Datei, so wie es Bernd checkt keine veränderte Größe mehr und so wie
ich es bevorzuge zu checken wäre die Datei auch exclusiv zu öffnen.
Mir ist das halt einfach zu unsicher und auf diverse allfällige Rückgabewerte irgendeines
PDF-Druckers verlasse ich mich aus gutem Grunde nicht [-X

Also nach dem Motto "wech is wech" ... es ist ja nicht der Dom den man in Kölle lassen sollte :lol: