Page 1 of 2 12 LastLast
Results 1 to 40 of 55

Thread: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handler

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    [VB6] IPreviewHandler: Show non-image file previews from all reg'd preview handlers

    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.

    Project Updated: 03 Dec 2015
    -With the original version of this project, font previews showed all black boxes. This is a bug in the Windows font previewer, and can be fixed by resetting the background with the IPreviewHandlerVisuals interface. NOTE: It's very hard to deal with installed fonts; they can't be selected via the open dialog, and can't be expressed as a shell item like even objects like the control panel or my computer can, so: To preview installed fonts, you'll have to manually enter the path to the font file (C:\Windows\Fonts\whatever.ttf) and click preview. Font files not located in \Windows\Fonts can be selected and previewed normally.

    -The update also adds an icon preview function, just to show how to make a comprehensive previewer (like the existing image previews in the original, IPreviewHandler isn't used unless your system has a custom one installed).

    This update requires oleexp v4.0 or higher and mIID.bas from the oleexp download.

    Requirements

    -Reference to oleexp, v4.0 or higher. oleexp.tlb is required for the IDE only, you do not need to distribute it with a compiled program.
    -oleexp addon mIID.bas - Found in the oleexp zip.

    -Recently an issue was discovered where some preview handlers may require a manifest for Common Controls 6.0. So far only Outlook 2007 .msg files have this issue (probably related to their also being the only ones using the more modern IInitializeWithItem), but there may be others. See LaVolpe's excellent project for making manifests for your app.

    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 and IPreviewHandlerVisuals interfaces was available in XP.

    -------------------------------

    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, objpic As Object, Optional sFileIn As String = "")
    Dim iif As IInitializeWithFile
    Dim iis As IInitializeWithStream
    Dim iisi As IInitializeWithItem
    Dim pVis As IPreviewHandlerVisuals
    Dim pUnk As oleexp.IUnknown
    Dim hr As Long
    Dim sFile As String, sExt As String
    Dim lp As Long
    Dim tHandler As UUID
    On Error GoTo e0
    
    If (isi Is Nothing) Then
        Debug.Print "no isi"
        If sFileIn <> "" Then
            sFile = sFileIn
        End If
    Else
        Debug.Print "using isi"
        isi.GetDisplayName SIGDN_FILESYSPATH, lp
        sFile = BStrFromLPWStr(lp)
    End If
        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
    
    
    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
    '    Set iif = 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"
    '                Set iis = ipv
        Set pUnk = ipv
        hr = pUnk.QueryInterface(IID_IInitializeWithStream, iis)
        If (iis Is Nothing) Then
            Debug.Print "IInitializeWithStream not supported."
            Set pUnk = ipv
            If pUnk.QueryInterface(IID_IInitializeWithItem, iisi) = S_OK Then
                Debug.Print "IInitializeWithItem supported."
                If (isi Is Nothing) = False Then
                    hr = iisi.Initialize(isi, STGM_READ)
                    GoTo gpvh
                Else
                    Debug.Print "Don't have needed IShellItem."
                End If
            Else
                Debug.Print "IInitializeWithItem not supported. No more initializers."
                GoTo out
            End If
        Else
            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)
                    hr = iis.Initialize(pstrm, STGM_READ)
                End If
                Call CloseHandle(hFile)
            End If
        End If
    
    
    gpvh:
        hr = ipv.SetWindow(hWnd, rc)
        Debug.Print "SetWindow hr=" & hr
        hr = ipv.DoPreview()
        Debug.Print "DoPreview hr=" & hr
        Dim piunk As oleexp.IUnknown
        Set piunk = ipv
        hr = piunk.QueryInterface(IID_IPreviewHandlerVisuals, pVis)
        If (pVis Is Nothing) = False Then
            Debug.Print "Handler implements IPreviewHandlerVisuals; setting bk color to white"
            pVis.SetBackgroundColor &HFFFFFF
        End If
        If (isi Is Nothing) = False Then
            isi.GetDisplayName SIGDN_NORMALDISPLAY, lp
            sFile = BStrFromLPWStr(lp)
        End If
        Label1.Caption = "DoPreview called for " & sFile
    Else
        'images and videos aren't handled that way normally, so we'll do it another way
        Debug.Print "No registered handler; trying alternate method for images..."
        Dim lPcv As Long
        lPcv = FilePtypeL(sExt)
        Debug.Print "Perceived type=" & lPcv
        If lPcv = PERCEIVED_TYPE_IMAGE Then
            If Right$(sFile, 4) = ".ico" Then
                'the below methods don't properly render icons transparent
                'so we'll use a different method that does
                If DoIcoPreview(sFile, objpic.hDC, 32) = -1 Then
                    GoTo gfthm
                End If
                objpic.Refresh
                Label1.Caption = "Manually generated preview for icon."
                GoTo out
            Else
    gfthm:
                Dim hbm As Long
                hbm = GetFileThumbnail(sFile, 0, objpic.ScaleWidth, objpic.ScaleHeight)
                Debug.Print "hbm=" & hbm
                objpic.Cls
                hBitmapToPictureBox objpic, hbm
                objpic.Refresh
                Label1.Caption = "Manually generated preview for image."
            End If
        Else
            Label1.Caption = "Could not find registered preview handler for file type."
        
        End If
    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's really simpler than it looks; the hard part it the initialization, a preview handler typically only supports 1 out of the 3 IInitialize__ interfaces, so we have to go through all of them, and IStream ones are too common to omit, and that's the only complex part.

    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



    UPDATE: The image file preview in the sample project won't work on XP, here's an alternative that will:
    Code:
    Public Declare Function SHCreateShellItem Lib "shell32" (ByVal pidlParent As Long, ByVal psfParent As Long, ByVal pidl As Long, ppsi As IShellItem) As Long
    
    Public Function GetFileThumbnail2(sFile As String, pidlFQ As Long, CX As Long, CY As Long) As Long
    'alternate method
    Dim isi As IShellItem
    Dim pidl As Long
    Dim iei As IExtractImage
    Dim hBmp As Long
    Dim uThumbSize As oleexp.SIZE
        uThumbSize.CX = CX
        uThumbSize.CY = CY
    Dim sRet As String
    Dim uThumbFlags As IEIFlags
    On Error GoTo e0
    
    If pidlFQ Then
        Call SHCreateShellItem(0&, 0&, pidlFQ, isi)
    Else
        pidl = ILCreateFromPathW(StrPtr(sFile))
        Call SHCreateShellItem(0&, 0&, pidl, isi)
        Call CoTaskMemFree(pidl) 'also a change that should have been made, had originally used ILFree, which shouldn't be used on Win2k+
    End If
    
    isi.BindToHandler ByVal 0&, BHID_ThumbnailHandler, IID_IExtractImage, iei
    If (iei Is Nothing) Then
        Debug.Print "GetFileThumbnail2.Failed to create IExtractImage"
        Exit Function
    End If
    
                uThumbFlags = IEIFLAG_ORIGSIZE
                sRet = String$(MAX_PATH, 0)
                iei.GetLocation StrPtr(sRet), MAX_PATH, 0&, uThumbSize, 32, uThumbFlags
    hBmp = iei.Extract()
    GetFileThumbnail2 = hBmp
    Set iei = Nothing
    
    On Error GoTo 0
    Exit Function
    
    e0:
    Debug.Print "GetFileThumbnail2.Error->" & Err.Description & " (" & Err.Number & ")"
    End Function
    
    'NOTE: The below are not needed if your project includes oleexp's mIID.bas
    Public Function BHID_ThumbnailHandler() As UUID
    '{0x7B2E650A, 0x8E20, 0x4F4A, 0xB0,0x9E, 0x65,0x97,0xAF,0xC7,0x2F,0xB0}
    Static iid As UUID
     If (iid.Data1 = 0) Then Call DEFINE_UUID(iid, &H7B2E650A, &H8E20, &H4F4A, &HB0, &H9E, &H65, &H97, &HAF, &HC7, &H2F, &HB0)
     BHID_ThumbnailHandler = iid
    End Function
    Public Function IID_IExtractImage() As UUID
    '{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
    Static iid As UUID
     If (iid.Data1 = 0) Then Call DEFINE_UUID(iid, &HBB2E617C, CInt(&H920), CInt(&H11D1), &H9A, &HB, &H0, &HC0, &H4F, &HC2, &HD6, &HC1)
      IID_IExtractImage = iid
    End Function
    UPDATE 1 July 2016 - As was pointed out below by Steve-N, SHCreateItemFromIDList is actually Vista+ too, image preview code in this post has been changed to use SHCreateShellItem instead, which MSDN states in available as of XP SP1.

    UPDATE 24 Nov 2016 - Attached project and code in post updated to reference oleexp.tlb v4.0 or higher. Updates in post incorporated into project.




    There's now a 64-bit compatible version of this project for twinBASIC!

    https://github.com/fafalone/PreviewHandler


    In addition to 64bit support, I updated the code to work better with the crappy Adobe PDF handler while not breaking the crappy MS TXT Preview handler, and additionally fixed an issue where local server created objects escape the automatic DPI scaling applied to your dpi unaware app.These changes can be backported to VB6 with a little effort, but I haven't done so yet.
    Attached Files Attached Files
    Last edited by fafalone; Jan 16th, 2024 at 10:02 AM. Reason: Attached project updated to reference oleexp.tlb 4.0 or higher

  2. #2
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Tested your iPreviewHandler sample, by trying to preview truetype fonts. IPreviewHandler gets TTF filetype viewer CLSID OK, creates IPREVIEWHandler ok as well, but areas drawn by font, shows as totally black retangles.

    Debug window output below..
    sExt=.TTF
    Got handler CLSID; attempting to create IPreviewHandler
    iisi.init hr=0
    SetWindow hr=0
    DoPreview hr=0

    Shell preview works ok, as well starting fontview directly using filename..
    fontview.exe S:\Fonts\TTF Fonts\TTF_A\AARCO___.TTF

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    I'll look into it.. not sure what's going on. It's returning the correct CLSID that corresponds to Windows Font Previewer, and no errors are being raised. Might be tough to trace since it's a problem with drawing that's done by the preview handler rather than the host app, but I'll give it a shot.

    Font Previewer (fontview.exe) draws the preview itself, and appears to be where the handler is hosted; it's not just hosting an instance of IPreviewHandler.

    Just in case it was the VB picturebox's problem, I tried on a CreateWindowExW-created window in a manifested app and had the same problem.
    Last edited by fafalone; Nov 27th, 2015 at 06:45 PM.

  4. #4
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Maybe a CLS needed. CLS copy picture to image. Image is the showing buffer.So if we get black view then image not show the proper bitmap. I am writing from a tablet, I can't check the code above...here.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    I added a .Cls statement, with and without a following .Refresh, to no avail; the thing is it's not standard graphics drawing. All you do is specify an hWnd to the external handler. It doesn't even have to be a picturebox; you can specify your forms hwnd, a frame's hwnd, etc, and it will be drawn onto that.

  6. #6
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Hi fafalone,

    once again you post brilliant stuff that cannot be found anywhere else. Thanks a lot for your pioneering work!

    I can confirm that your sample code works well on Win8.1.

    I also have to confirm the issue with font files. Black rects only also here.

    voxy

  7. #7
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Conc. the font preview issue, maybe the IPreviewHandlerVisuals has to be used additionally to IPreviewHandler.

    https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

  8. #8
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    FYI, although I removed the
    Code:
    If hGlobal Then GlobalFree hGlobal
    line I still get random crashes after previewing PDFs. Not as often as with that line but still.

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    As for PDFs, the preview handler for that is notoriously unstable; people can't seem to get it to work in other languages either. There's not even much to work with, since it's the initial creation of IPreviewHandler that fails, with the oh-so-helpful 0x80004005 'Unspecific error' message.


    Edit: For fonts, IPreviewHandlerVisuals did the trick, thanks for pointing me in that direction. It's a little odd as to why, but simply using its SetBackgroundColor method (set to white) makes the fonts show up; for ttf, otf, and fon files that I tested, both installed in \Windows\Fonts and not installed ones. Haven't a clue why this works, since the background already was white, and changing the text color isn't needed (although you can change that too if you want). I'll update the project in a little bit; need to see if there's any ramifications to calling it with other file types (and will have to update the main tlb since this interface wasn't already defined).
    Last edited by fafalone; Dec 3rd, 2015 at 01:28 AM.

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Project updated with font preview fix (must update tlb too).

    Added after ipv.DoPreview()
    Code:
        
        Dim pVis As IPreviewHandlerVisuals    
        Dim piunk As oleexp3.IUnknown
        Set piunk = ipv
        hr = piunk.QueryInterface(IID_IPreviewHandlerVisuals, pVis)
        If (pVis Is Nothing) = False Then
            Debug.Print "Handler implements IPreviewHandlerVisuals; setting bk color to white"
            pVis.SetBackgroundColor &HFFFFFF
        End If
    Last edited by fafalone; Dec 3rd, 2015 at 07:28 AM.

  11. #11
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    ShowPreviewForFile subroutine throws an 'Object variable or With block variable not set 91' (error) in some computers (W7-64). Error does not happen all W7-64 machines, but only couple of.

    Shows preview window and font face rendering in it OK, but throws an error. Not yet known what is causing that.
    Tested running your sample in few machines. Running compiled executable, worked ok - also runs ok in computer which is used to compile source.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Throws an error after rendering the font? Or when you do something else afterwards? Or on different file?

    If it's an IDE error you should be able to just comment out the On Error Goto e0 statement and get the line where it's occuring.

    ..I think I do recall an unusual bug like you described; but not after a successful preview. I remember something was returning S_OK for pUnk.QueryInterface(IID_IInitializeWithItem, iisi), but then right after that throwing an error saying iisi wasn't set. Actually, in production apps I've commented out the whole IInitializeWithItem section, as it's so rare that no other sample I've seen uses it, and no file I've seen actually supports it but not one of the others. Edit: Turns out Outlook .msg files actually do only support IInitializeWithItem. So leave it in, but put if after IStream; and don't validate with the hr; check if Is Nothing.

    If it is after showing a font, refer to the installed fonts issue descibed in the main text. If you've selected an installed font, you can't get a valid IShellItem for it, and isi.GetDisplayName SIGDN_NORMALDISPLAY, lp could cause that error... there should be an Is Nothing check before that statement really; I'll update it tomorrow. To confirm that's the case, is it when dealing with fonts from \Windows\Fonts\, and if it works sometimes, is it possible not all machines have the underlying issue to begin with? (I'm on Win7x64 as well; will fire up a VM with 8 later too). And if the error is immediately after the font preview shows the correct preview without boxes, regardless of the cause that isi.GetDisplayName line is the only possible statement that could trigger that error, so the Is Nothing check will resolve it.
    Last edited by fafalone; Dec 4th, 2015 at 11:17 PM.

  13. #13
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    As for PDFs, the preview handler for that is notoriously unstable; people can't seem to get it to work in other languages either. There's not even much to work with, since it's the initial creation of IPreviewHandler that fails, with the oh-so-helpful 0x80004005 'Unspecific error' message.
    I don't see that error here, but still get crashes on various systems after PDF preview. One system uses the Adobe preview handler, the other the PDF-XChange preview handler. The crash happens after calling IPV.Unload, but not immediately but at the point when the handler's DLL gets unloaded, which is one or two minutes later (no idea what triggers this unloading, it just happens by itself -- you can watch it happen in Process Explorer).

    So, something is wrong here. A notorious issue with PDF previews has always been the focus stealing. I tried to control the focus with IPV.QueryFocus() but to no avail. Currently out of ideas.

  14. #14

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    I can't load the Adobe preview handler at all.. but are you saying both of those work, but just later crash when unloaded? Is it only if you manually invoke unload; what if you just let IPV go out of context/set it to nothing?
    There's .SetFocus() too, and SetWindow... what if you set the window to 0 after the preview is already displayed? That might help with the crash too.

    Will try PDF-XChange viewer on my system and see if I can reproduce the issue.

    Edit: I'm unable to reproduce the error with PDF-XChange. That handler works without issue. So; OS version, product version, and if applicable more specific steps? (i previewed a pdf then exited the program; then also previewed a pdf then loaded a new file that used a different handler; then in a 3rd run previewed a pdf then previewed another pdf.. nothing caused a crash on Win7x64)

    Edit2: The font black boxes were certainly a bizarre issue with an even more bizarre solution. Setting the bk color triggered something it shouldn't have. PDF-XChange's handler implements IPreviewHandlerVisuals as well; are you using the updated code that calls the SetBackgroundColor function, even if you want to keep it white? I have no idea how this might be preventing the crashes and it wouldn't make sense; but after it preventing black boxes it wouldn't surprise me if it helped here too
    (and speaking of the new version; it forgoes using ANY GlobalFree call... that may be an issue as well in the older version since PDF-XChange's handler uses the IStream method)
    Last edited by fafalone; Dec 4th, 2015 at 08:35 AM.

  15. #15
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    OK, this is Win8.1. Here is the steps.

    - Install PDF-Viewer 2.5.214.2 from PDF-XChange. (well, this is mine, probably other versions do as well)
    - Compile your latest sample project IPreviewHandlerSampleV2 (native code, optimized for speed)
    - Run Project1.exe and preview *one* PDF file.
    - Now close the EXE (click X-button).
    - In Task Manager you will see that it did not unload. This is a symptom of the problem.

    - Now, when you do the same thing, but preview *two* (or more) PDF files, you can close the EXE and it will unload completely.

    Note that I was not able to crash Project1.exe before unloading it. (Something in my own project is probably responsible for this crash; but I also get the crash-on-unload in my own project. I think it's all the same bug.)

    Does this tell you anything? (I hope you can reproduce it.)

    voxy

    PS: I don't use the SetBackgroundColor code. No GlobalFree calls anywhere.

  16. #16
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Now I was able to crash your sample project (compiled to EXE) just the same way as my own project.

    - preview *one* PDF
    - unload that preview using this code (you see the "Unload IPV" button I added to your sample in the screenshot):

    Code:
    Private Sub Command3_Click()
      If (ipv Is Nothing) = False Then
          ipv.Unload
          Set ipv = Nothing
      End If
    End Sub
    - finally put any other window to the foreground! The crash only happens if Project1.exe is a background window. (another hint that focus plays a role here)

    - now wait 1-3 minutes doing nothing. At some point the window will become unresponsive and look like this:
    Name:  Project1Crash.jpg
Views: 4063
Size:  9.8 KB

  17. #17
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    Throws an error after rendering the font?
    After rendering font, visually all seems fine ie. renders font OK, but throws an error. Tried previewing non installed fonts, residing in network share, but able to reproduce also with installed fonts in same machine throwing error.

    I will report back when some tests are made, with compiled program added some feedback to pinpoint code line causing error.

  18. #18

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    @Tech99: Did you add the check to make sure it's not the isi.GetDisplayName line? No object code executes between that statement and a subsequent user action.

    @voxy: Still not getting a crash or lingering processes. To me this suggests either the problem is elsewhere, or the same magic that resolved font black boxes is working here and you should add the IPreviewHandlerVisuals call (this was also available in XP so would not break that compatibility if that was a concern). I haven't tried with the older version you're using yet either though, theoretically could have been solved between your 2.5.214 and my 2.5.315.

  19. #19
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    @Tech99: Did you add the check to make sure it's not the isi.GetDisplayName line? No object code executes between that statement and a subsequent user action.
    Not sure yet. I haven't been able to reproduce error since, in that user workstation. Rebooted that machine, in the beginning of testing and no error since.

  20. #20

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    It's still a good idea to add the check; even if it's not the cause of your crashes, in case of unforseen issues that cause it to not be set.
    You're using the default Windows Font Previewer right, not a 3rd party preview handler? Did you ever get the crash with a different file type?


    Edit:
    NOTE: I had to withdraw my earlier statement about removing IInitializeWithItem. Found out that Outlook .msg files support it, but not either of the other IInitialize's. I'm working on a general bugfix update that will do this, but in the mean time I recommend checking for it after both the others, and validating it If iisi Is Nothing instead of If hr = S_OK (as per the bug I described with it).
    Last edited by fafalone; Dec 4th, 2015 at 11:31 PM.

  21. #21
    Member
    Join Date
    Jan 2015
    Posts
    50

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    @voxy: Still not getting a crash or lingering processes. To me this suggests either the problem is elsewhere, or the same magic that resolved font black boxes is working here and you should add the IPreviewHandlerVisuals call (this was also available in XP so would not break that compatibility if that was a concern). I haven't tried with the older version you're using yet either though, theoretically could have been solved between your 2.5.214 and my 2.5.315.
    Bingo!!! Upgrading to 2.5.315 fixed it! Wonderful, thanks!
    (And I don't care so much for bugs with Adobe. They are known to be buggy.)

    Just for completeness: Before upgrading PDF-XChange I tried your suggestion with IPreviewHandlerVisuals, but it did not change anything.

  22. #22
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    It's still a good idea to add the check; even if it's not the cause of your crashes, in case of unforseen issues that cause it to not be set.
    You're using the default Windows Font Previewer right, not a 3rd party preview handler? Did you ever get the crash with a different file type?
    Yes, using standard Windows Font Previewer app (fontview.exe), tried couple of other filetypes - mostly bitmap formats (png, jpg, tif) seems to work ok.

    However i changed your sample a bit, by adding resizing. Needed to remove frame1, for dynamic resizing to work.

  23. #23
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    I can't load the Adobe preview handler at all...
    Same here.

    Got handler CLSID; attempting to create IPreviewHandler
    IInitializeWithFile not supported.
    IInitializeWithItem not supported.
    Attempting to use IStream

    hr = pUnk.QueryInterface(IID_IInitializeWithStream, iis) returns -2147467259 as hr value.

  24. #24

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Yup that's the base-10 of the 80004005 'unspecific error' code. I like the 3rd party previewer solution, Adobe sux anyway. There's FoxIt or somesuch too that has a preview handler that should work.

    Wait.. if that's on QueryInterface, your call to CoCreateInstance succeeded in creating the preview handler at least then?

  25. #25
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    Wait.. if that's on QueryInterface, your call to CoCreateInstance succeeded in creating the preview handler at least then?
    Actually no, that was from machine where Adobe full featured Acrobat package was installed. Plain Adobe Reader DC (latest version) fails in CoCreateInstance.

    GetHandlerCLSID succeeds for .pdf extension tHandler(CLSID/GUID) returned {DC6EFB56-9CFA-464D-8880-44885D7DC193} for Adobe Reader DC, but the CoCreateInstance fails with hresult -2147467259 value.

    Code:
    Public Function IID_IPreviewHandler() As UUID
    '{8895b1c6-b41f-4c1c-a562-0d564250836f}
    Static iid As UUID
     If (iid.Data1 = 0) Then Call DEFINE_UUID(iid, &H8895B1C6, CInt(&HB41F), CInt(&H4C1C), &HA5, &H62, &HD, &H56, &H42, &H50, &H83, &H6F)
     IID_IPreviewHandler = iid '<- this line takes quite long time to execute.
    End Function
    https://forums.adobe.com/thread/303008?tstart=0
    Excerpt from page 3...
    This is from Adobe staff from this April "Sorry for the trouble. We had to remove the thumbnail preview functionality from Acrobat and Reader DC for technical reasons. We know there are users who value it but certain design considerations forced us to make this change."
    Last edited by Tech99; Dec 6th, 2015 at 01:22 AM.

  26. #26

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    DC is what is on my system too, that appears to be the problem. I get that for whatever reason they removed the previewer from it, but it's just terrible programming to still register the handler and just fling errors instead of a message it's been removed or just removing the registration entirely. No wonder their products are gaping security holes with the World's Worst Updater.

  27. #27
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    No wonder their products are gaping security holes with the World's Worst Updater.
    Indeed and Adobe Reader is massive bloatware nowadays - DC version is whopping 120 Mb in size.

    Looking for alternatives, MuPDF is small, fast but seems to lack of iPreviewHandler support.

  28. #28

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    The PDF-XChange viewer me and voxy were talking about is free (have to grab just the viewer, the editor and others are just trials) and works well. There's also one called Foxit thats free and widely used. Both of these support IPreviewHandler well.
    Last edited by fafalone; Dec 6th, 2015 at 08:46 AM.

  29. #29
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Quote Originally Posted by fafalone View Post
    The PDF-XChange viewer me and voxy were talking about is free (have to grab just the viewer, the editor and others are just trials) and works well. There's also one called Foxit thats free and widely used. Both of these support IPreviewHandler well.
    I tested Foxit Reader PDF Printer. It produces poor quality of pdf file (Alpha lost). PDF Creator produces normal good quality pdf.

  30. #30
    New Member
    Join Date
    Feb 2016
    Posts
    4

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Using iPreviewHandlerSampleV2 and oleexp v3.3 on Windows 7 with Office 2007 I see an issue with saved Outlook email .msg files.

    Previewing .msg files doesn't show any message body text. The message header is shown (Title, From, To and Date Sent) but not the actual message. No error occurs.

    But when looking at Windows Explorer preview pane the full message text shows also.

    It doesn't make any difference if the internal format of the .msg file is Plain Text, Rich Text or HTML.

    I assume Windows Explorer uses iPreviewHandler, so I would have expected the same results.

  31. #31

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Windows does it's own thing. IPreviewHandler is implemented and registered by the application, but Windows does a bunch of extra stuff, and there's little documentation about what to do. For example, there was zero documentation about the necessity of IPreviewHandlerVisuals to render fonts.

    Can you post a sample file? I can plug it into a version with far more extensive debug output, since the problem doesn't appear with newer versions.

  32. #32
    New Member
    Join Date
    Feb 2016
    Posts
    4

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    I'll post a sample file when I am back in the office.
    Meanwhile here is the debug output:-
    Got handler CLSID; attempting to create IPreviewHandler
    IInitializeWithFile not supported.
    iisi.init hr=0
    SetWindow hr=0
    DoPreview hr=-2147467259

  33. #33

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    That's odd, DoPreview is throwing an error that's usually a crash (the hr should be 0 [S_OK] if successful), but then it's still showing a partial preview? And are you running the sample straight, or integrated into a project-- perhaps the preview rect is just cutting it off? Definitely need a sample file.. although I am concerned that even if the message was created by 2007, it would still be rendered by my newer version (2010).
    Last edited by fafalone; Feb 10th, 2016 at 07:14 PM.

  34. #34
    New Member
    Join Date
    Feb 2016
    Posts
    4

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    I found the issue. I added a manifest to use common controls v 6.0.0.0
    The message body is now shown.

    I guess the Outlook previewer must use v6 of the common controls.

    This is using your downloaded sample, unmodified.

  35. #35

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Yeah that makes sense.. I'll make a note about it in the requirements section, thanks for the report. I've been kinda presuming anyone modernizing their app with this kinda stuff would already be manifested, but I've never seen it required except for one other (IImageList/IImageList2)-- but MSDN documented that. But yet another undocumented requirement for IPreviewHandler.

  36. #36
    New Member
    Join Date
    Feb 2016
    Posts
    1

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    hi

    i want use IPreviewHandler by file listbox.
    but it need to set isi by fileopendialog.
    please help me

    Name:  fff.jpg
Views: 4044
Size:  15.4 KB


    thanks.

  37. #37

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    You mean from a FileListBox right? You could do something similar to what the 'Preview' button does, just with the file list instead of the textbox:
    Code:
    Dim psi As IShellItem
    Dim rc As RECT
    Dim pidl As Long
    Dim sFile As String
    sFile = Dir1.Path & "\" & File1.List(File1.ListIndex)
    pidl = ILCreateFromPathW(StrPtr(sFile))
    Call SHCreateItemFromIDList(pidl, IID_IShellItem, psi)
    
        rc.Top = 16
        rc.Bottom = (Picture1.Height / Screen.TwipsPerPixelY) - 16
        rc.Left = 16
        rc.Right = (Picture1.Width / Screen.TwipsPerPixelX) - 16
        ShowPreviewForFile psi, Picture1.hWnd, rc, Picture1, sFile
    Also in your picture you're selecting a JPG, which may not by default have an IPreviewHandler; the sample project has code that manually draws image file previews, so you'd have to make sure you had that part too.

  38. #38
    New Member
    Join Date
    Feb 2016
    Posts
    4

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    I haven't tried this yet, but the XP code you give for image file preview (post #1) uses
    Code:
    SHCreateItemFromIDList
    Doesn't this have a minimum requirement of Vista ?
    Last edited by Steve-N; Jul 1st, 2016 at 12:45 PM.

  39. #39

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Ah apparently so, good catch I thought it just required 6.0.

    Fortunately it can be easily replaced with SHCreateShellItem, which MSDN says: "Minimum supported client Windows XP with SP1 [desktop apps only]"

    Public Declare Function SHCreateShellItem Lib "shell32" (ByVal pidlParent As Long, ByVal psfParent As Long, ByVal pidl As Long, ppsi As IShellItem) As Long

    I'll update it with the minor change:
    Code:
    If pidlFQ Then
        Call SHCreateShellItem(0&, 0&, pidlFQ, isi)
    Else
        pidl = ILCreateFromPathW(StrPtr(sFile))
        Call SHCreateShellItem(0&, 0&, pidl, isi)
        Call CoTaskMemFree(pidl) 'also a change that should have been made
    End If
    Sorry I didn't find out about this earlier my XP diehards, and thanks for pointing this out Steve
    Last edited by fafalone; Jul 1st, 2016 at 05:35 PM.

  40. #40
    New Member
    Join Date
    Feb 2018
    Posts
    9

    Re: [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handle

    Using the iPreview sample (v3) I have a problem.

    On Windows 10 (64 bit) with Adobe Reader XI and a fix for the 64bit Adobe Reader preview handler ( https://pretentiousname.com/adobe_pd...fix/index.html )

    Admittedly this isn't a common configuration, but I don't have control over this. It isn't possible to change this in the short term.

    The debug output from the sample program is as follows:
    Code:
    using isi
    sFile=C:\Test\00000017.PDF
    sExt=.PDF
    Got handler CLSID; attempting to create IPreviewHandler
    
    ...and after a delay of over 1 minute...
    
    Failed to create IPreviewHandler interface, hr=-2147467259
    The configuration works fine in File Explorer and Outlook, PDFs can be previewed. In File Explorer you even get thumbnails of the first page of the PDF.

    If I install say PDF-XChange viewer I can then preview PDFs, but unfortunately this isn't allowed.

    I accept this is largely a problem created by Adobe, but because Explorer and Outlook can work with this configuration it should be possible to get the iPreviewHandler to work too.

    What should I try?

Page 1 of 2 12 LastLast

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
  •  



Click Here to Expand Forum to Full Width