1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
'patricktoulon
Private Declare PtrSafe Function GdiplusStartup Lib "gdiplus" (ByRef token As LongPtr, inputbuf As Any, ByVal outputbuf As LongPtr) As Long
Private Declare PtrSafe Function GdiplusShutdown Lib "gdiplus" (ByVal token As LongPtr) As Long
Private Declare PtrSafe Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As LongPtr, ByVal hpal As LongPtr, ByRef bitmap As LongPtr) As Long
Private Declare PtrSafe Function GdipSaveImageToFile Lib "gdiplus" (ByVal image As LongPtr, ByVal filename As LongPtr, clsidEncoder As Any, ByVal encoderParams As LongPtr) As Long
Private Declare PtrSafe Function GdipDisposeImage Lib "gdiplus" (ByVal image As LongPtr) As Long
Private Declare PtrSafe Function CLSIDFromString Lib "ole32" (ByVal strCLSID As LongPtr, ByRef pClsid As GUID) As Long
Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As LongPtr
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Type GUID: Data1 As Long: Data2 As Integer: Data3 As Integer: Data4(0 To 7) As Byte: End Type
Function CopyPngPicture_GDI_V_1(obj As Object, lPath As String) As Variant
Dim hCopy As LongPtr, token As LongPtr, bitmap As LongPtr
Dim CLSID_PNG As GUID, StartupInput As GdiplusStartupInput
Dim retries As Integer, isimage&
On Error GoTo ErrorHandler
' Initialiser GDI+
StartupInput.GdiplusVersion = 1
If GdiplusStartup(token, StartupInput, 0&) <> 0 Then Exit Function
' Effacer et préparer le clipboard pour éviter les erreurs d'accès
OpenClipboard 0: EmptyClipboard: CloseClipboard
DoEvents
' Copier la sélection en bitmap
obj.CopyPicture format:=xlBitmap
'Attendre que le bitmap soit disponible dans le clipboard environ 1 seconde max
'pour une gestion d'attente raisonnable
'au delà il y a des problèmes à régler
retries = 0
Do Until isimage <> 0 Or retries >= 1000: isimage = IsClipboardFormatAvailable(&H2)
retries = retries + 1
Loop
If isimage = 0 Then GoTo ByeBye
' Ouvrir le clipboard pour récupérer le bitmap
OpenClipboard 0: hCopy = GetClipboardData(&H2): CloseClipboard
' Si le handle est invalide, quitter
If hCopy = 0 Then GoTo ByeBye
' Créer un bitmap GDI+ à partir du handle
If GdipCreateBitmapFromHBITMAP(hCopy, 0&, bitmap) <> 0 Then GoTo ByeBye
' Obtenir le CLSID pour le format PNG
CLSIDFromString StrPtr("{557CF406-1A04-11D3-9A73-0000F81EF32E}"), CLSID_PNG
' Sauvegarder l'image en fichier PNG
If GdipSaveImageToFile(bitmap, StrPtr(lPath), CLSID_PNG, 0&) = 0 Then
CopyPngPicture_GDI_V_1 = lPath ' Sauvegarde réussie
End If
ByeBye:
' Libérer la mémoire du bitmap et fermer GDI+
If bitmap Then GdipDisposeImage bitmap
GdiplusShutdown token
Exit Function
ErrorHandler:
' Gestion d'erreur basique
CopyPngPicture_GDI_V_1 = False
Resume ByeBye
End Function |
Partager