IPreviewHandler Example
![]()
![]()


Many file types have registered preview handlers, not just images. Typically documents, videos, fonts, music, even registry files, all have a preview handler that you can put on your application with little effort.
Compatibility
The current sample project won't run on XP, but if you replace the IFileDialog file selection dialog and possibly a few other things, the core IPreviewHandler interface was available in XP.
Requirements
Requires a reference to oleexp3.tlb or higher.
-------------------------------
The registry holds registered preview handlers in the HKEY_CLASSES_ROOT\filetype\ShellEx\{8895b1c6-b41f-4c1c-a562-0d564250836f} key, but as a shortcut you can also use the AssocQueryString API with ASSOCSTR_SHELLEXTENSION as the sample project shows.
Here's the basic code to show a preview:
Code:
Private Sub ShowPreviewForFile(isi As IShellItem, hWnd As Long, rc As RECT)
'isi - an IShellItem representing the file (in example loaded from IFileDialog)
'hWnd - hWnd to show the preview on, typically a form, frame, or picturebox
'rc - A rectangle representing the area within the window to show the preview;
' client-based so starts at 0
Dim iif As IInitializeWithFile
Dim iis As IInitializeWithStream
Dim iisi As IInitializeWithItem
Dim pUnk As oleexp3.IUnknown
Dim hr As Long
Dim sFile As String, sExt As String
Dim lp As Long
Dim tHandler As UUID
On Error GoTo e0
isi.GetDisplayName SIGDN_FILESYSPATH, lp
sFile = BStrFromLPWStr(lp)
Debug.Print "sFile=" & sFile
sExt = Right$(sFile, (Len(sFile) - InStrRev(sFile, ".")) + 1)
Debug.Print "sExt=" & sExt
If sExt = "" Then Exit Sub
If (ipv Is Nothing) = False Then
ipv.Unload
Set ipv = Nothing
End If
If hGlobal Then GlobalFree hGlobal
hr = GetHandlerCLSID(sExt, tHandler)
If hr = 1 Then
Debug.Print "Got handler CLSID; attempting to create IPreviewHandler"
hr = CoCreateInstance(tHandler, 0, CLSCTX_INPROC_SERVER Or CLSCTX_LOCAL_SERVER, IID_IPreviewHandler, ipv)
If (ipv Is Nothing) Then
Debug.Print "Failed to create IPreviewHandler interface, hr=" & hr
Exit Sub
End If
'Set iisi = ipv 'this normally can be used in place of Set pUnk / .QueryInterface, but we need the HRESULT
Set pUnk = ipv
If pUnk.QueryInterface(IID_IInitializeWithItem, iisi) = S_OK Then
hr = iisi.Initialize(isi, STGM_READ)
Debug.Print "iisi.init hr=" & hr
GoTo gpvh
Else
Debug.Print "IInitializeWithItem not supported."
End If
' Set iif = ipv
Set pUnk = ipv
If pUnk.QueryInterface(IID_IInitializeWithFile, iif) = S_OK Then
hr = iif.Initialize(sFile, STGM_READ)
GoTo gpvh
Else
Debug.Print "IInitializeWithFile not supported."
End If
'use IStream
Dim hFile As Long
Dim pstrm As IStream
Dim lpGlobal As Long
Dim dwSize As Long
Debug.Print "Attempting to use IStream"
hFile = CreateFile(sFile, FILE_READ_DATA, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, 0, 0)
If hFile Then
dwSize = GetFileSize(hFile, ByVal 0&)
Debug.Print "Got file size=" & dwSize
If dwSize = 0 Then Exit Sub
hGlobal = GlobalAlloc(GPTR, dwSize)
lpGlobal = GlobalLock(hGlobal)
If lpGlobal Then
Call ReadFile(hFile, ByVal lpGlobal, dwSize, dwSize, ByVal 0&)
Call GlobalUnlock(hGlobal)
Call CreateStreamOnHGlobal(hGlobal, 1, pstrm)
' Set iis = ipv
Set pUnk = ipv
hr = pUnk.QueryInterface(IID_IInitializeWithStream, iis)
Debug.Print "QI.hr=" & hr
If (iis Is Nothing) Then
Debug.Print "IInitializeWithStream not supported."
Call CloseHandle(hFile)
GoTo out
Else
hr = iis.Initialize(pstrm, STGM_READ)
End If
End If
Call CloseHandle(hFile)
End If
gpvh:
hr = ipv.SetWindow(hWnd, rc)
Debug.Print "SetWindow hr=" & hr
hr = ipv.DoPreview()
Debug.Print "DoPreview hr=" & hr
isi.GetDisplayName SIGDN_NORMALDISPLAY, lp
sFile = BStrFromLPWStr(lp)
Label1.Caption = "DoPreview called for " & sFile
Else
Label1.Caption = "Could not find registered preview handler for file type."
End If
out:
Set iisi = Nothing
Set iif = Nothing
Set iis = Nothing
On Error GoTo 0
Exit Sub
e0:
Debug.Print "ShowPreviewForFile.Error->" & Err.Description & " (" & Err.Number & ")"
End Sub
It may vary from system to system, but plain images generally aren't supported with this method, but there's a large variety of ways to preview them.
----------------
Project based on Using Preview Handlers in Windows Vista