Attribute VB_Name = "z_PastePictureAPI" '================ Модуль загрузки изображения через Copy/Paste ============= ' Shared module version: 20210228 ' Required reference: OLE Automation ' PastePicture The entry point for the routine ' CreatePicture Private function to convert a bitmap or metafile handle to an OLE reference ' ErrorDescription Get the error text for an OLE error code Option Private Module Option Explicit Option Compare Text ' Declare a UDT to store a GUID for the IPicture OLE Interface Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type ' Declare a UDT to store the bitmap information Private Type PictDescriptor size_ As LongLong type_ As LongLong hPic_ As LongPtr hPal_ As LongLong End Type 'Does the clipboard contain a bitmap/metafile? Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long 'Convert the handle into an OLE IPicture interface. Private Declare PtrSafe Function OleCreatePictureIndirect Lib "olepro32.dll" (pDesct As PictDescriptor, refID As GUID, ByVal nPicHandle As Long, iPic As IPicture) As Long 'Create our own copy of the metafile, so it doesn't get wiped out by subsequent clipboard updates. Private Declare PtrSafe Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long 'Create our own copy of the bitmap, so it doesn't get wiped out by subsequent clipboard updates. Private Declare PtrSafe Function CopyImage Lib "user32" (ByVal nHandle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long 'The API format types Private Const CF_BITMAP = 2 Private Const CF_PALETTE = 9 Private Const CF_ENHMETAFILE = 14 Private Const IMAGE_BITMAP = 0 Private Const LR_COPYRETURNORG = &H4 Public Function PastePicture(Optional nType& = xlPicture) As IPicture 'Convert the type of picture requested from the xl constant to the API constant Dim lPicType&: lPicType = IIf(nType = xlBitmap, CF_BITMAP, CF_ENHMETAFILE) 'Check if the clipboard contains the required format Dim hPicAvail&: hPicAvail = IsClipboardFormatAvailable(lPicType) If hPicAvail = 0 Then _ Exit Function Dim cbHandle&: cbHandle = OpenClipboard(0&) If cbHandle <= 0 Then _ Exit Function 'Get a handle to the image data Dim hPtr&: hPtr = GetClipboardData(lPicType) 'Create our own copy of the image on the clipboard, in the appropriate format. Dim hCopy& If lPicType = CF_BITMAP Then hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG) Else hCopy = CopyEnhMetaFile(hPtr, vbNullString) End If 'Release the clipboard to other programs cbHandle = CloseClipboard 'If we got a handle to the image, convert it into a Picture object and return it If hPtr <> 0 Then _ Set PastePicture = CreatePicture(hCopy, 0, lPicType) End Function Private Function CreatePicture(ByVal hPic&, ByVal hPal&, ByVal lPicType) As IPicture 'OLE Picture types Const PICTYPE_BITMAP = 1 Const PICTYPE_ENHMETAFILE = 4 ' Create the Interface GUID (for the IPicture interface) Dim IID_IDispatch As GUID With IID_IDispatch .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 ' Fill uPicInfo with necessary parts. Dim uPicInfo As PictDescriptor With uPicInfo .size_ = Len(uPicInfo) ' Length of structure. .type_ = IIf(lPicType = CF_BITMAP, PICTYPE_BITMAP, PICTYPE_ENHMETAFILE) ' Type of Picture .hPic_ = hPic ' Handle to image. .hPal_ = IIf(lPicType = CF_BITMAP, hPal, 0) ' Handle to palette (if bitmap). End With ' Create the Picture object. Dim r& Dim iPic As IPicture r = OleCreatePictureIndirect(uPicInfo, IID_IDispatch, True, iPic) ' If an error occured, show the description If r <> 0 Then _ Debug.Print "Create Picture: " & ErrorDescription(r) ' Return the new Picture object. Set CreatePicture = iPic End Function Private Function ErrorDescription(nErr&) As String 'OLECreatePictureIndirect return values Const E_ABORT = &H80004004 Const E_ACCESSDENIED = &H80070005 Const E_FAIL = &H80004005 Const E_HANDLE = &H80070006 Const E_INVALIDARG = &H80070057 Const E_NOINTERFACE = &H80004002 Const E_NOTIMPL = &H80004001 Const E_OUTOFMEMORY = &H8007000E Const E_POINTER = &H80004003 Const E_UNEXPECTED = &H8000FFFF Const S_OK = &H0 Select Case nErr Case E_ABORT: ErrorDescription = " Aborted" Case E_ACCESSDENIED: ErrorDescription = " Access Denied" Case E_FAIL: ErrorDescription = " General Failure" Case E_HANDLE: ErrorDescription = " Bad/Missing Handle" Case E_INVALIDARG: ErrorDescription = " Invalid Argument" Case E_NOINTERFACE: ErrorDescription = " No Interface" Case E_NOTIMPL: ErrorDescription = " Not Implemented" Case E_OUTOFMEMORY: ErrorDescription = " Out of Memory" Case E_POINTER: ErrorDescription = " Invalid Pointer" Case E_UNEXPECTED: ErrorDescription = " Unknown Error" Case S_OK: ErrorDescription = " Success!" End Select End Function