Stampando un PDF rimane aperta la finestra di Acrobat Reader

di il
10 risposte

Stampando un PDF rimane aperta la finestra di Acrobat Reader

Buongiorno a tutti.
Dovendo stampare un file PDF da codice VBA, ho seguito le indicazioni di @Alex di usare SHELLEXECUTE ed inviare il comando di PRINT (vedi https://www.iprogrammatori.it/forum-programmazione/access/stampare-file-codice-t48935.html#p8685108).
Funziona benissimo, ma ora il mio problema è che si apre la finestra di Acrobat Reader e rimane aperta sullo sfondo. Si può fare in modo che si chiuda automaticamente? Oppure si può chiudere da codice?

Grazie.

10 Risposte

  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Se leggi la guida di ShellExecute:
    http://winapi.freetechsecrets.com/win32/WIN32ShellExecute.htm

    recita:
    
    Return Values
    
    If the function succeeds, the return value is the instance handle of the application that was run, or the handle of a dynamic data exchange (DDE) server application.
    
    If the function fails, the return value is an error value that is less than or equal to 32. The following table lists these error values:
    
    Value	Meaning
    0	The operating system is out of memory or resources.
    ERROR_FILE_NOT_FOUND	The specified file was not found.
    ERROR_PATH_NOT_FOUND	The specified path was not found.
    ERROR_BAD_FORMAT	The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
    SE_ERR_ACCESSDENIED	The operating system denied access to the specified file.
    SE_ERR_ASSOCINCOMPLETE	The filename association is incomplete or invalid.
    SE_ERR_DDEBUSY	The DDE transaction could not be completed because other DDE transactions were being processed.
    SE_ERR_DDEFAIL	The DDE transaction failed.
    SE_ERR_DDETIMEOUT	The DDE transaction could not be completed because the request timed out.
    SE_ERR_DLLNOTFOUND	The specified dynamic-link library was not found.
    SE_ERR_FNF	The specified file was not found.
    SE_ERR_NOASSOC	There is no application associated with the given filename extension.
    SE_ERR_OOM	There was not enough memory to complete the operation.
    SE_ERR_PNF	The specified path was not found.
    SE_ERR_SHARE	A sharing violation occurred.
    Quindi devi leggere il Valore restituito dalla chiamata, se non hai errore il valore è>32 e rappresenta l'Hwnd dell'applicazione lanciata.
    A quel punto puoi usare SendMessage o PostMessage ed inviare a quell'Hndle il messaggio WM_CLOSE
    
    Private Const WM_CLOSE = &H10
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    OK. Non avevo pensato al fatto che ShellExecute restituisse l'handle.

    Grazie @Alex
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Verificalo perchè non ne sono in realtà certissimo... sia vero...
    Ad esempio Shell restituisce il ProcessID, da li poi si ricava l'hWnd... ma con ShellExecute non ricordo bene, ma forse c'è qualche inghippo...

    Probabilmente ti converrà usare FindWindow dopo la ShellExecute.
    
    ShellExecute(NULL, "print", "tuoExe.exe", NULL, NULL, SW_SHOWNORMAL);
    hWndApp = FindWindow(NULL, "Caption Titlebar Text")
    SendMessage(hWndApp, WM_CLOSE, 0, 0) 'oppure PostMessage
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Ho scritto questa subroutine, ma la finestra non si chiude.
    Dove sbaglio?
    Public Function StampaFilePDF(pFile) As Boolean
        Dim rShEx As Integer
        Dim rSndMsg As Integer
        If Dir(pFile) <> "" Then
            rShEx = ShellExecute(0, "print", Chr(34) & pFile & Chr(34), "", "", SW_HIDE)
            Debug.Print rShEx
            If rShEx < 33 Then
                MsgBox "Errore durante la stampa:" & vbCrLf & ErrDesc(rShEx)
                StampaFilePDF = False
            Else
                'rSndMsg = SendMessage(rShEx, WM_SYSCOMMAND, SC_CLOSE, 0)
                rSndMsg = SendMessage(rShEx, WM_CLOSE, 0, 0)
                Debug.Print rSndMsg
                StampaFilePDF = True
            End If
        Else
            MsgBox "File inesistente:" & vbCrLf & pFile
            StampaFilePDF = False
        End If
    End Function
    Grazie in anticipo
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Ho letto dopo la seconda risposta di @Alex, ora controllo. Grazie.
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    L'help di ShellExecute dice:
    Return Values
    If the function succeeds, the return value is the instance handle of the application that was run, or the handle of a dynamic data exchange (DDE) server application.
    Quindi dovrebbe funzionare, invece non succede nulla!
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    @Alex ha scritto:


    Probabilmente ti converrà usare FindWindow dopo la ShellExecute.
    Purtroppo deve funzionare su più computer e non in tutti c'è lo stesso software per stampare PDF.

    Che Caption ci metto?
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Se usi Findwindow non hai problema recupera l'handle non dal ClassName ma dalla Caption dell'app aperta che sia reader che sia altro.
    Le app si comportano tutte così, mettono nella caption bar il file aperto prova così vedrai che funziona.
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Ciao @Alex, scusa se non mi sono più fatto sentire, ma sono dovuto partire per una trasferta.

    Findwindow non riesco ad usarlo perché sia in Acrobat che in uno di quelli che ho su altri PC quando lancio la stampa con:
    rShEx = ShellExecute(0, "print", Chr(34) & pFile & Chr(34), "", "", SW_HIDE)
    dopo aver stampato scarica il file e rimane aperto il programma senza nulla caricato, e le caption sono differenti.

    Per ora ho risolto ciclando una serie di possibili parole chiave (tipo "Acrobat") da cercare nelle caption, ma questo non mi da la certezza di rilevare solo quella giusta. Ad esempio se l'utente ne ha già altre aperte con altri file caricati, gliele chiude tutte!!!
    Ed inoltre se viene comprato un nuovo PC non è detto che l'amministratore di sistema metta sempre lo stesso software per gestire i PDF (ed infatti in quelli che ci sono trovo tre programmi differenti).
    P.S. io non posso installare nulla e non posso neanche cambiare l'associazione per pensare di usarne uno "portable".

    Per capirci meglio: io devo avere una subroutine che dando il comando:
    Stampa(nomeFilePDF)
    stampi il file e non lasci nulla nuovo aperto e non chiuda nulla di quello che c'è già aperto...
  • Re: Stampando un PDF rimane aperta la finestra di Acrobat Reader

    Se hai una situazione NON NOTA a priori devi rendere il tuo codice non dipendente da Applicazioni o basi fisse.

    Non ho modo di fare una prova, ma puoi ragionare in questo modo, invece di usare ShellExecute, puoi usare ShellExecuteEX con la struttura dati preposta [SHELLEXECUTEINFO], trovi quì un esempio:
    https://stackoverflow.com/questions/1374433/shellexecuteex-in-vba
    https://stackoverflow.com/questions/32334110/shellexecuteex-crashes-in-excel-vba
    Come vedi dovrai passare a [lpVerb] il comando di OPEN...

    Questa struttura come vedi restituisce, o meglio valorizza nella struttura [hProcess] che altro non è che il PID(process ID) che identifica il processo lanciato.
    Dal PID ricavi l'Handle, lo puoi fare via API sempre sfruttando l'ENUM degli Handle o con WMI... e con l'Handle come dicevamo passando il comando WM_CLOSE tramite PostMessage puoi terminare la finestra.

    Questo esempio API vedi la funzione [GetHwnd] alla quale passi il PID:
    https://www.vbforums.com/showthread.php?561413-getting-hwnd-from-process

    Puoi leggere anche questi esempi che forse aggiungono qualche info:
    http://www.cpearson.com/excel/ShellAndWait.asp
Devi accedere o registrarti per scrivere nel forum
10 risposte