Consulting

Page 2 of 2 FirstFirst 1 2
Results 21 to 32 of 32

Thread: A Class Module to store Images from a folder for later reuse in Workbook Excel VBA

  1. #21
    No Worries Dave. i had put the Declaration on the top of the module. :-)

    Here is a sample file to demonstrate my problem. I have used your code and followed the steps you suggested.

    If you put a watch on the PicCollect Collection or on IPic in the API Module then you will notice that none of the IPicture properties are populating. They are instead showing "Nothing".
    Attached Files Attached Files

  2. #22
    VBAX Expert Dave's Avatar
    Joined
    Mar 2005
    Posts
    832
    Location
    Trial this. Dave
    Attached Files Attached Files

  3. #23
    I didn't change any of your code, but clicked on the CommandButton. Got the following error:

    ClipboardData - Type Mismatch.JPG

    I am on Windows 10 Enterprise, Excel 2016 Pro. Was my file working for you, as it contained both Win32 as well as Win64 API code?
    Last edited by sifar786; 02-20-2020 at 09:54 AM.

  4. #24
    VBAX Expert Dave's Avatar
    Joined
    Mar 2005
    Posts
    832
    Location
    Tested perfect... the 64 bit code for GetClipBoardData must not be correct. I have no 64 bit to test on. Dave

  5. #25
    hmmm...how do i resolve this issue? Is there some documentation for 64 bit that you can suggest that may shed some light on this issue?

    BTW does Data1 need to be a longPtr?

        
        Private Type GUID        
            Data1 As Long
            Data2 As Integer
            Data3 As Integer
            Data4(0 To 7) As Byte
        End Type
    or any of the other Types or Enums that go into defining the IPicture attributes?
    Last edited by sifar786; 02-20-2020 at 10:45 AM.

  6. #26
    VBAX Expert Dave's Avatar
    Joined
    Mar 2005
    Posts
    832
    Location
    I googled some more. U can trial this 64bit stuff....
     #If VBA7 Then
        Type uPicDesc
            Size As Long
            Type As Long
            hPic As LongPtr
            hPal As LongPtr
        End Type
        Declare PtrSafe Function CloseClipboard Lib "user32" () As LongPtr
        Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
        Declare PtrSafe Function EmptyClipboard Lib "user32" () As LongPtr
        Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
        Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As LongPtr) As LongPtr
        Declare PtrSafe Function OleCreatePictureIndirect Lib "OleAut32.dll" (PicDesc As uPicDesc, _
                  RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
        Declare PtrSafe Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" ( _
                  ByVal hemfSrc As LongPtr, ByVal lpszFile As String) As LongPtr
        Declare PtrSafe Function CopyImage Lib "user32" ( _
        ByVal Handle As LongPtr, ByVal un1 As Long, ByVal n1 As Long, _
        ByVal N2 As Long, ByVal un2 As Long) As LongPtr
        Dim hPtr As LongPtr

  7. #27
    Thanks @Dave.

    What i found out was that the IPic was returning the picture as seen from this test :

    IPic Returned.JPG

    Image1 Returned.JPG
    But I think the Collection or Dictionary is not returning it to the Image1 in the proper format.

    How does one store an IPicture interface to a Collection or Dictionary?
    Last edited by sifar786; 02-22-2020 at 02:15 AM.

  8. #28
    VBAX Expert Dave's Avatar
    Joined
    Mar 2005
    Posts
    832
    Location
    "How does one store an IPicture interface to a Collection" ….. that is what this code does. Sorry sifar786 but I have no 64 bit instal to test code. As stated it works with gif, bmp, jpg and png files on my 32 bit install. I'm guessing that the VBA 7 declarations are still not correct. Good luck. Dave
    ps. Collections are not the same as a Dictionary and I have no idea if a Dictionary can contain images/objects.
    On second look, why are you not using the code I provided? U are not loading the pics in a collection, U are trying to create a picture from within the createpicture routine???
    PicCollect.Add PastePicture(CF_ENHMETAFILE)
    Is how the pics are loaded in the collection. So...
     sheets("picsht").image1.Picture =PastePicture(CF_ENHMETAFILE)
    would work for a copied picture if U use the code correctly.
    Last edited by Dave; 02-22-2020 at 08:03 AM.

  9. #29
    The earlier sample file i attached used your Collection approach only. Dictionaries can store any datatypes including Objects (not sure of Picture types if they are not considered as objects...).

    I am also using the same declarations that you provided, but still the same issue. The only way it works, is as shown in my earlier reply, i am able
    to load the pic directly i.e.

    Thisworkbook.sheets("PicSht").Image1.Picture=IPic
    but not by assigning from a Collection
    PicCollect.Add PastePicture(CF_ENHMETAFILE)

    Last edited by sifar786; 02-22-2020 at 08:38 AM.

  10. #30
    Hi @Dave,

    I finally was able to make your file work for 64 bit address space using the latest declarations you gave me. :-)

    I have not changed any major part of the code, except the following:

    -
    Added a Do...DoEvents....Loop Until H=0
    This is necessary, else the Clipboard doesn't Clear/Close correctly e.g., if you run the button once and then click the Up or Down arrows of the Spinbutton and then click the button again, it shoots up an Error!

    - Put
    On Error Resume Next....On Error Goto 0
    on the SpinButton click procedures...otherwise if button is not clicked and spinbutton Up/Down arrows are clicked, it shoots up an Error!



    I saw that you had commented 32 bit WinAPI code. When i uncommented it and tried to use something like below to redirect the call either to 64 bit function or 32 bit functions, strange enough, i was not able to show the images in the Image1 control :

    Public Function PastePicture(Optional lXlPicType As Long = xlPicture) As IPicture
        #If VBA7 Or Win64 Then
            PastePictureVBA7 (lXlPicType)
        #Else
            PastePictureWin32 (lXlPicType)
        #End If
    End Function

    One Last help : Could you help me by adding the correct 32 bit WinAPI code, as people with 32 bit systems will also be using it?

    Here's the attached file.
    Attached Files Attached Files

  11. #31
    VBAX Expert Dave's Avatar
    Joined
    Mar 2005
    Posts
    832
    Location
    Well it's been quite a journey. I'm glad that U have got it working and hope that it addresses your needs. Not sure why U need to adjust the pastepicture and I really don't understand it? The error on spinbutton will occur if the collection isn't loaded. Not sure why U need a delay to clear the clipboard but I'll post some code that U can trial. The file U sent still works for all image types on my 32 bit install. Have a nice day. Dave
               'clear then close clipboard. The Do...Loop ensure proper clearing & closing of clipboard
              ' Do
                    EmptyClipboard
                    'DoEvents
                    Dim t As Double
                    t = Timer
                    Do Until Timer - t > 1
                    DoEvents
                    Loop
                    H = CloseClipboard  'Release the clipboard to other programs
                 '   DoEvents
               ' Loop Until H = 0
    ]

  12. #32
    Banned VBAX Regular
    Joined
    Feb 2020
    Posts
    8
    Location
    Seems similar to your previous query except that U now want to use a temporary wb to store the images. You can load images into a collection for later use however the collection will only exist as long as the temporary wb is open. HTH. Dave

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •