'******************************************************************************************************************************************************
'    ___      _     _______  __      _    ____  _   _  _______  ___      _   _    _    ___      _     _.
'   //  \\   /\\      //    // \\   //   //    //  //    //    //  \\   //  //   //   //  \\   //|   //
'  //___//  //__\    //    //__//  //   //    //__||    //    //   //  //  //   //   //   //  // |  //
' //       //   \\  //    //  \\  //   //    //  \\    //    //   //  //  //   //   //   //  //  | //
'//       //    // //    //   // //   //___ //    \\  //     \\__//  //__//   //___ \\__//  //   |//
'******************************************************************************************************************************************************
'fonction pour lister les imprimantes pour excel
'patricktoulon sur vdeloppez.com
'date 16/12/2017
'mise à jour :10/12/2023
'api en 64
Option Explicit
'32bit'Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" (ByVal HKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As LongPtr, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As LongPtr) As Long
'32bits'Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal HKey As Long, ByVal dwIndex As Long, ByVal lpPrinterName As String, lpcbPrinterName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Byte, lpcbData As Long) As Long
Private Declare PtrSafe Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As LongPtr, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As LongPtr, lpType As Long, lpData As Byte, lpcbData As Long) As Long
'32bits'Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare PtrSafe Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As LongPtr) As Long
Private Const HKEY_CURRENT_USER As Long = &H80000001
Private Const HKCU = HKEY_CURRENT_USER
Private Const PRINTER_KEY = "Software\Microsoft\Windows NT\CurrentVersion\Devices"
Private Const KEY_QUERY_VALUE = &H1&
Private Const ERROR_NO_MORE_ITEMS = &H103
Private Const ERROR_MORE_DATA = &HEA
Sub test()
    Dim t, i&
    t = GetPrintersList
    MsgBox Join(t, vbCrLf)
End Sub
Sub test2()
    Dim t, i&
    t = GetPrintersList
    MsgBox Join(t, vbCrLf)
    For i = LBound(t) To UBound(t)
       If Not t(i) Like "*Nul*" Then Application.ActivePrinter = t(i)
       MsgBox Application.ActivePrinter
    Next i
   
End Sub
Public Function GetPrintersList() As String()
    Dim Printers$(), PrinterIndex&, hKey As LongPtr, Res&, IndexKey&, PrinterName$, LenName&, DataType&, ValueValue() As Byte, i&, t$, a&, b&: t = ""
    PrinterIndex = 0
    IndexKey = 0
    PrinterName = String$(256, Chr(0))
    LenName = 255
    ReDim ValueValue(0 To 500)
    ReDim Printers(1 To 20) 'jusqu'a 20 imprimantes
     Res = RegOpenKeyEx(HKCU, PRINTER_KEY, 0&, KEY_QUERY_VALUE, hKey)
    Res = RegEnumValue(hKey, IndexKey, PrinterName, LenName, 0&, DataType, ValueValue(0), 1000)
    Do Until Res = ERROR_NO_MORE_ITEMS
        PrinterName = Split(PrinterName, Chr(0))(0)
        a = InStr(1, ValueValue, ","): b = InStr(1, ValueValue, ":") 'recherche de la virgule et du doublepoint
        t = ""
        For i = a To b: t = t & Chr(ValueValue(i)): Next 'récupération du texte dans le tableau de bytes
        If Trim(t) = "" Then t = " Null"
        PrinterIndex = PrinterIndex + 1
        Printers(PrinterIndex) = Application.Trim(PrinterName & " sur " & t)
        PrinterName = String(255, Chr(0))
        LenName = 255
        ReDim ValueValue(0 To 500)
        IndexKey = IndexKey + 1
        Res = RegEnumValue(hKey, IndexKey, PrinterName, LenName, 0&, DataType, ValueValue(0), 1000) 'on change la cle pour le prochain Do
         If (Res <> 0) And (Res <> ERROR_MORE_DATA) Then Exit Do
    Loop
    ReDim Preserve Printers(1 To PrinterIndex)
    Res = RegCloseKey(hKey)
    GetPrintersList = Printers
End Function