Link to home
Create AccountLog in
Avatar of Fabrice Lambert
Fabrice LambertFlag 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 ?
Avatar of Martin Liss
Martin Liss
Flag of United States of America image

Have you tried

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

ASKER

Yep, doesn't work either.

It make sens since the LoadPicture function expect a file path as argument.
Can you attach a zip file of your project?
See attached:
Database2.accdb
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.
Very quick and dirty
Fabrice.accdb
Yup, dirty, with a bunch of 32 bits API déclarations (I have 64 bits Office).

If possible, I would like to avoid APIs.
If it helps you can use the same API declarations by modifying them like this. Declare PtrSafe Sub...
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
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
Avatar of Ryan Chong
Ryan Chong
Flag of Singapore image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
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.