Private Declare PtrSafe Function

di il
6 risposte

Private Declare PtrSafe Function

Salve a tutti.

Ho un documento Word nel quale ho inserito vari moduli VBA con diverse routine.

Uso questo documento in due PC che usano diverse versione di Office.

Nel secondo PC, nel quale è installato Office 2016, per far funzionare le varie macro devo per forza inserire questa istruzione:

Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
        (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

E' una seccatura correggere sempre il codice. Vorrei che la cosa avvenisse automaticamente: provo con la seguente routine, ma purtroppo non funziona. La prima riga viene evidenziata in rosso ed il codice non procede. Qualche aiuto?

If VBA7 Then
    Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
        (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#Else
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
        (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#End If

6 Risposte

  • Re: Private Declare PtrSafe Function

    Nella If manca il #

    #If

  • Re: Private Declare PtrSafe Function

    Ciao ho spostato nella sezione calderone per linguaggi di programmazione come questo

  • Re: Private Declare PtrSafe Function

    21/09/2023 - coccobello ha scritto:


    Uso questo documento in due PC che usano diverse versione di Office.

    Nel secondo PC, nel quale è installato Office 2016, per far funzionare le varie macro devo per forza inserire questa istruzione:

    Forse non ho capito bene il significato della frase ma quella che usi è un'API, se serve credo che tu la debba usarla sempre, non solo sul computer con Office 2016. Quella che hai scritto è la diversa dichiarazione che usa VBA con la compilazione condizionale, in base alla versione di VBA (collegata alla versione di Office: VBA7 da Office 2010 in avanti).

    Magari è una precisazione influente però facciamo che è meglio dirlo.

  • Re: Private Declare PtrSafe Function

    21/09/2023 - Philcattivocarattere ha scritto:


    in base alla versione di VBA

    Più che alla versione di VBA, non è legato alla versione 32/64 bit di Office che è installata sulla macchina?

    La dichiarazione in esempio secondo me non è corretta perché dovrebbe prevedere in output il tipo LongPtr, che vale 32 (Long) o 64 (LongLong) bit a seconda della versione. Un Long è sempre 32 bit su qualsiasi installazione e rischia quindi di finire in overflow su un Office a 64 bit. Tutte le variabili nel codice che servono a ricevere il risultato della funzione, andrebbero dichiarate a loro volta LongPtr in modo da lasciare al compilatore la scelta se usare il Long o il LongLong a seconda dell'ambiente.

    Dico baggianate? Se non ho ricostruito male, ShellExecute ritorna un HINSTANCE, che è in realtà un HANDLE, che è un realtà un PVOID, che è un puntatore e quindi dipende dalla piattaforma per la quale è stata compilata l'app.

  • Re: Private Declare PtrSafe Function

    22/09/2023 - Sgrubak ha scritto:


    Più che alla versione di VBA, non è legato alla versione 32/64 bit di Office che è installata sulla macchina?

    La compilazione condizionale

    #If VBA7 Then
       ...
    #Else
       ...
    #End If

    serve per verificare la versione di VBA (7 o precedenti) in uso. VBA7 introdotto con Office 2010 supporta e riconosce type, data type e parole chiave che si adattano automaticamente al bitness del programma (non del sistema operativo) in cui vengono eseguiti.

    https://learn.microsoft.com/it-it/office/vba/Language/Concepts/Getting-Started/64-bit-visual-basic-for-applications-overview

    Fino ad Office 2007 (che ha VBA in versione 6.x) non si può usare LongLong, LongPtr o PtrSafe, perché non sa cosa sono, quindi le dichiarazioni di API devono seguire il “vecchio stile”, anche perché non si corre il rischio dei 64bit: fino ad Office 2007 la suite era solo a 32 bit.

    Per come si dichiarano le API per funzionare correttamente anche nei prodotti a 64 bit ci sono due immancabili siti:

    https://jkp-ads.com/articles/apideclarations.asp

    https://codekabinett.com/rdumps.php?Lang=2&targetDoc=windows-api-declaration-vba-64-bit

    nonché il file ufficiale Microsoft: https://www.microsoft.com/en-us/download/details.aspx?id=9970

  • Re: Private Declare PtrSafe Function

    22/09/2023 - Philcattivocarattere ha scritto:


    non si corre il rischio dei 64bit: fino ad Office 2007 la suite era solo a 32 bit.

    Esattamente le info che avevo trovato io. Grazie della conferma!

    22/09/2023 - Philcattivocarattere ha scritto:


    ci sono due immancabili siti

    che usano il LongPtr, ho notato.

    Perfetto. Grazie di nuovo! Almeno son sicuro di averci capito qualcosa. Mi resta oscuro solo l'uso fatto dei vari typedef… Non ho mai scritto una riga ci C/C++ in vita mia. XD

Devi accedere o registrarti per scrivere nel forum
6 risposte