Shell Image Interfaces
![]()

Project Description
Windows provides a good bit of image functionality built in and accessible through simple interfaces rather than fairly complicated API. A number of these were added to the latest release of oleexp. This projects demonstrates several of these interfaces:
IShellImageData
Easy to create with ShellImageDataFactory object.
Set pFact = New ShellImageDataFactory
pFact.CreateImageFromFile StrPtr(sISID), pShImg
pShImg.Decode SHIMGDEC_DEFAULT, 10, 10
This is the most useful interface, it can:
-Display basic info about an image (see picture)
-Step frame-by-frame through an animated GIF, or use a timer to 'play' it - I added this feature in after I took the screen shot-- it's included in the attached project
-View multi-page images
-Scale images with different algorithm options e.g. bicubic
-Rotate an image at any angle
-Draw onto a picturebox with transparency
-Save changed image (supports user-defined encoder parameters, but not shown in demo)
...all through single-line calls,
Code:
pShImg.ScaleImage CLng(Text5.Text), CLng(Text6.Text), InterpolationModeBicubic
pShImg.NextFrame
pShImg.Rotate CLng(Text4.Text)
'saving is equally easy:
Dim ipf As IPersistFile
Set ipf = pShImg
ipf.Save sFullPath, 1
This interface allows you to convert any image file supported by Windows into a JPG or BMP with only a few lines of code:
Code:
Private Sub DoTranscode(psiSrc As IShellItem, psiDest As IShellItem, nTo As TI_FLAGS)
'The included module provides a standalone implemention of this routine if you're starting
'from only the file paths. This version uses a number of shortcuts getting an IShellItem
'directly from FileOpenDialog gives us
Dim lpDest As Long
Dim pStrm As IStream
Dim pTI As ImageTranscode
Dim pwi As Long, phg As Long
Set pTI = New ImageTranscode
psiDest.GetDisplayName SIGDN_FILESYSPATH, lpDest
Call SHCreateStreamOnFileEx(lpDest, STGM_CREATE Or STGM_READWRITE, FILE_ATTRIBUTE_NORMAL, 1, 0, pStrm)
pTI.TranscodeImage psiSrc, 0, 0, nTo, pStrm, pwi, phg
pStrm.Commit STGC_DEFAULT
Set pStrm = Nothing
Set pTI = Nothing
Call CoTaskMemFree(lpDest)
End Sub
These interfaces are very similar to API imagelists (and indeed you can get an API imagelist handle you can use with those functions or assign to a control just by using ObjPtr(pIML)), but apart from being slightly easier to work with also allow resizing on the fly, instead of having to reconstruct. This is also the only way to scale up, because as with API imagelists, you cannot add images smaller than the size the imagelist was created as.
It's important to note than you can create one from scratch, but not with = New ImageList, you need to use ImageList_CoCreateInstance, as shown in the sample project.
Project Requirements
-Windows Vista or higher
-oleexp3.tlb version 3.1 or higher (released 18Sep2015). Only required for the IDE, you don't need to include it with the compiled program.
-----
Some sample images to play around with are included in the ZIP; I didn't make them.