'******************************************************************************************************************************************************
'    ___     _     _______  __      _   ____  _   _   _______  ___     _   _  _    ___     _     _.
'   //  \\  /\\      //    // \\   //  //    //  //     //    //  \\  //  // //   //  \\  //|   //
'  //___// //__\    //    //__//  //  //    //__||     //    //   // //  // //   //   // // |  //
' //      //   \\  //    //  \\  //  //    //  \\     //    //   // //  // //   //   // //  | //
'//      //    // //    //   // //  //___ //    \\   //     \\__// //__// //___ \\__// //   |//
'******************************************************************************************************************************************************
'capturer une plage en wmf et créer une image en memoire (Ipicture)pour
's'en servir dans un control image dans un userform
'patricktoulon sur developpez.com
'date/22/03/2010
'remasteurisation du code date: 12/09/2023
' api creation object image
'Option Explicit
'Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
'Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
'Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
'Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As LongPtr) As LongPtr
'Declare PtrSafe Function CopyEnhMetaFileA Lib "gdi32" (ByVal HwndImage As LongPtr, ByVal Direction As String) As LongPtr
'Declare PtrSafe Function OleCreatePictureIndirect Lib "OleAut32.dll" (pPictDesc As PICTDESC, ByRef riid As GUID, ByVal fOwn As Long, ByRef ppvObj As IPicture) As Long
'
'Type RECT: Left As Long: top As Long: Right As Long: BOTTOM As Long: End Type
'Type GUID: Data1 As Long: Data2 As Integer: Data3 As Integer: Data4(0 To 7) As Byte: End Type
'Type PICTDESC: cbSize As Long: picType As Long: himage As LongPtr: hPal As LongPtr: End Type
'Function copyxlPicture(obj, Optional Ex_transparency As Boolean = False) As IPicture
'    Dim hCopy As LongPtr, PictStructure As PICTDESC, DispatchInfo As GUID, IPic As IPicture, T#, p, Shap
'    obj.CopyPicture
'    Set p = obj.Parent
'    If Ex_transparency = True Then
'        p.Paste: Set Shap = p.Shapes(p.Shapes.Count)
'        Shap.Fill.Visible = msoTrue: Shap.Fill.ForeColor.RGB = vbWhite: Shap.CopyPicture: Shap.Delete
'    End If
'    OpenClipboard 0
'    T = Timer
'    Do While hCopy = 0
'        hCopy = CopyEnhMetaFileA(GetClipboardData(14), vbNullString): If Timer - T > 1 Then Exit Do
'    Loop
'    CloseClipboard
'    If hCopy = 0 Then Set copyxlPicture = IPic: Exit Function    ' si pas de handleimage WMF dans clip on arrete tout
'    With DispatchInfo
'        .Data1 = &H7BF80980: .Data2 = &HBF32: .Data3 = &H101A: .Data4(0) = &H8B: .Data4(1) = &HBB
'        .Data4(2) = &H0: .Data4(3) = &HAA: .Data4(4) = &H0: .Data4(5) = &H30: .Data4(6) = &HC: .Data4(7) = &HAB
'    End With
'    With PictStructure: .cbSize = Len(PictStructure): .picType = 4: .himage = hCopy: .hPal = 0: End With
'    OleCreatePictureIndirect PictStructure, DispatchInfo, True, IPic
'    Set copyxlPicture = IPic
'End Function
Option Explicit
Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As LongPtr) As LongPtr
Declare PtrSafe Function IIDFromString Lib "ole32" (ByVal lpsz As String, ByRef lpiid As GUID) As LongPtr
Declare PtrSafe Function copyimage Lib "user32" Alias "CopyImage" (ByVal handle As LongPtr, ByVal un1 As LongPtr, ByVal n1 As LongPtr, ByVal n2 As LongPtr, ByVal un2 As LongPtr) As LongPtr
Declare PtrSafe Function OleCreatePictureIndirect Lib "OleAut32.dll" (pPictDesc As PICTDESC, ByRef riid As GUID, ByVal fOwn As Long, ByRef ppvObj As IPicture) As Long
Type RECT: Left As Long: top As Long: Right As Long: BOTTOM As Long: End Type
Type GUID: Data1 As Long: Data2 As Integer: Data3 As Integer: Data4(0 To 7) As Byte: End Type
Type PICTDESC: cbSize As Long: picType As Long: himage As LongPtr: hPal As LongPtr: End Type
Function copyimagex(obj)
    Dim IPic As IPicture
    Dim hCopy As LongPtr
    Dim tIID As GUID
    Dim PictStructure As PICTDESC
    Dim x As Double
    Dim Ret As LongPtr
    Call OpenClipboard(0): EmptyClipboard: CloseClipboard
    obj.Copy 'Picture Format:=xlBitmap
    OpenClipboard 0&
    x = Timer
    Do While (hCopy = 0)
        hCopy = copyimage(GetClipboardData(&H2), 0, 0, 0, &H8)
        If Timer - x > 1 Then Exit Do
    Loop
    CloseClipboard
    If hCopy = 0 Then Set copyimagex = IPic: Exit Function
    Const IPictureIID = "{7BF80981-BF32-101A-8BBB-00AA00300CAB}"
    Ret = IIDFromString(StrConv(IPictureIID, vbUnicode), tIID)
    If Ret Then Set copyimagex = IPic: Exit Function
    With PictStructure: .cbSize = Len(PictStructure): .picType = 1: .himage = hCopy: End With
    Ret = OleCreatePictureIndirect(PictStructure, tIID, 1, IPic)
    If Ret Then Set copyimagex = IPic: Exit Function
    Set copyimagex = IPic
    Call OpenClipboard(0): EmptyClipboard: CloseClipboard
    Set copyimagex = IPic
End Function