Avatar of Fabrice Lambert
Fabrice Lambert
Flag for France asked on

Browse an ImageList control

I made a form to browse images held in an ImageList control (named Images).
The form also has 2 buttons to navigate forward (named Next) and backward (named Previous), as well as an Image control (named ImageDisplay) to display the current image.

So far, my attempts to display something failed.
My code is fairly simple:
Option Compare Database
Option Explicit

Private mIl As MSComctlLib.ImageList    '// reference to the ImageList control
Private mIndex As Long                  '// index of currently displayed image

Private Sub Form_Load()
    mIndex = 1
    Set mIl = Images.Object
    
    DisplayImage
End Sub

Private Sub Next_Click()
    If (mIndex < mIl.ListImages.Count) Then
        mIndex = mIndex + 1
    End If
    DisplayImage
End Sub

Private Sub Previous_Click()
    If (mIndex > 1) Then
        mIndex = mIndex - 1
    End If
    DisplayImage
End Sub

Private Sub DisplayImage()
    ImageDisplay.Picture = mIl.ListImages(mIndex).Picture    '// failure here, the Picture property return the image's handle
End Sub

Open in new window

So, how can I display images held in an ImageList control, in an Image control ?
* imagesMicrosoft AccessVBA

Avatar of undefined
Last Comment
Fabrice Lambert

8/22/2022 - Mon
Martin Liss

Have you tried

ImageDisplay.Picture = LoadPicture(mIl.ListImages(mIndex).Picture)
Fabrice Lambert

ASKER
Yep, doesn't work either.

It make sens since the LoadPicture function expect a file path as argument.
Martin Liss

Can you attach a zip file of your project?
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
Fabrice Lambert

ASKER
See attached:
Database2.accdb
Martin Liss

I'm sorry Fabrice, but I got notification of your question because you included I Visual Basic Classic in your topics, and so I didn't notice that you are using Access. I've changed that topic to VBA so hopefully you'll get someone who can help you better than I can.
John Tsioumpris

Very quick and dirty
Fabrice.accdb
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Fabrice Lambert

ASKER
Yup, dirty, with a bunch of 32 bits API déclarations (I have 64 bits Office).

If possible, I would like to avoid APIs.
Martin Liss

If it helps you can use the same API declarations by modifying them like this. Declare PtrSafe Sub...
John Tsioumpris

If you want to avoid API then you have to use other controls to display the ImageList content..like ListView,MsFlexGrid
If you try to display the ImageList Picture to Picture you will receive a nice message that "The bitmap you specified is not in a device-independent bitmap (.dib) format."
So you need dirty API to overcome this as its not supported.
Probably you just have to change the dlls declarations ..usually a change from Long to LongPtr is sufficient
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Fabrice Lambert

ASKER
If it helps you can use the same API declarations by modifying them like this. Declare PtrSafe Sub...
yeah, I know, and pointers need to be LongPtr type.
ASKER CERTIFIED SOLUTION
Ryan Chong

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Fabrice Lambert

ASKER
Thank you Ryan, that's what I was suspecting after digging trough Google.

I even found  a way to load png files to ImageList, that's done with the help of the WIA (Windows Image Acquisition) library:
Private Sub Form_Load()
    Dim Il As Object        '// MSComctlLib.ImageList
    Set Il = myImageList.Object

    Il.ListImages.Add Key:="myKey", Picture:=LoadImage("c:\.............\myPicture.png")
End Sub

Open in new window

Public Function LoadImage(ByVal path As String, Optional ByVal colorMask As Long = &HFF00FF) As IPicture
    Dim Img As Object		'// wia.ImageFile
    Set Img = CreateObject("WIA.ImageFile")
    
    Img.LoadFile path
    
    Dim imgData As Object	'// wia.Vector
    Set imgData = Img.ARGBData
    
    Const wiaFormatBMP As String = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
    If (Img.FormatID = wiaFormatBMP) Then
            '// Fake transparency for BMP
        Dim i As Integer
        For i = 1 To imgData.count
                '// Set the alpha channel to zero for pixel matching the color mask
            If ((imgData(i) And colorMask) = colorMask) Then
                imgData(i) = colorMask
            End If
        Next
    End If
    Set LoadImage = imgData.picture(Img.width, Img.height)
End Function

Open in new window

Bonus: It also work with the ribbon, no need for the GDI+ API anymore.