Results 1 to 22 of 22

Thread: [VB6, Vista+] Host Windows Explorer on your form: navigation tree and/or folder

Threaded View

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    [VB6, Vista+] Host Windows Explorer on your form: navigation tree and/or folder

    IExplorerBrowser

    IExplorerBrowser is an easy to use, more complete version of IShellView (in fact, it has an IShellView at its core that you can access) that lets you have a complete Explorer frame on your form, with very little code. You can either have just a plain file view, or with a navigation tree and toolbar. It uses all the same settings and does all the same things as Explorer, and your program can interact with those actions to do things like browse for files, or be the basis of a namespace extension.
    The only complication is that there's no event notifying of an individual file selection within the view, and getting a list of selected files is fairly complex- however there is a function to do it in the demo project.
    Here's how it looks if you're just using folder view without the frames:


    INamespaceTreeControl

    If all you want is the navigation tree, you have the INamespaceTreeControl. It's got a decent amount of options for however you want to display things, including checkboxes. There is a wide range of events that you're notified of via the event sink, and most of these use IShellItem- the demo project does show to to convert that into a path, but it's a very useful interface to learn if you're going to be doing shell programming. The selection is reported through IShellItemArray, which is slightly easier than IDataObject.
    It's got one little quirk though... you have the option to set the folder icons yourself, but if you don't want to do that and just use the default icon that you see in Explorer, you have to return -1, which requires a v-table swap. The demo project shows how to go both ways, no thanks to MSDN and their complete lack of documentation of this.
    But this is by far the easiest to create way of having a full-featured Explorer-like navigation- I've made a regular TreeView into this, and it took hundreds of lines and heavy subclassing. This is a simple object. (Note that it does support some advanced features through related interfaces, like custom draw, drop handling, and accessibility... these interfaces are included in oleexp, but have not been brought to the sample project here, perhaps in the future I'll do a more in-depth one if there's any interest)

    Requirements
    Windows Vista or higher required as these interfaces did not exist in earlier OS versions
    oleexp.tlb: Modern Interfaces Type Library v4.0 or higher (17 Jun 2015) - Only required in the IDE.
    mIID.bas - oleexp add-on module, included in the oleexp download

    These 'controls' create themselves- all you need is a blank form, and here's the creation code for a basic idea of how these things work (code to initialize some variables omitted):
    Code:
    Set pNST = New NamespaceTreeControl
    pNST.Initialize Me.hWnd, prc, lFlag
    Set pAdv = New cNSTEvents
    Set pUnkAdv = pAdv
    pNST.TreeAdvise pUnkAdv, lpck
    pNST.InsertRoot 0, isiDesk, SHCONTF_FOLDERS, NSTCRS_EXPANDED Or NSTCRS_VISIBLE, pif


    UPDATE: Enumerating selection in virtual location for IExplorerBrowser.
    So I was showing how this demo can be used to browse FTP sites and realized the IDataObject/DragQueryFile method of obtaining the selection fails in virtual folders that don't have local paths. This is an alternative method that will get their IShellItems, display names, and (if applicable and including network) paths, so that you can further interact with them (for instance, to copy to/from FTP, you can pass the IShellItems to IFileOperation even if there's no valid path):
    Code:
    'frmBasic
    
    Private Sub Command1_Click()
    Dim hr As Long
    Dim sOut As String
    Dim pIDO As oleexp.IDataObject
    Dim psv As IShellView
    Dim fmt As FORMATETC
    Dim stg As STGMEDIUM
    Dim hDrop As Long
    Dim uNumFiles As Long
    Dim i As Long
    Dim Filename As String
    
    pEBrowse.GetCurrentView IID_IShellView, psv
    If (psv Is Nothing) Then
        Debug.Print "Failed to created IShellView"
        Exit Sub
    End If
    
    Dim psia As IShellItemArray
    Dim penm As IEnumShellItems
    Dim lpName As Long
    Dim psiChild As IShellItem
    
    psv.GetItemObject SVGIO_SELECTION, IID_IShellItemArray, psia
    If (psia Is Nothing) = False Then
        psia.EnumItems penm
        If (penm Is Nothing) = False Then
            Do While (penm.Next(1&, psiChild, i) = NOERROR)
                psiChild.GetDisplayName SIGDN_NORMALDISPLAY, lpName
                Filename = BStrFromLPWStr(lpName)
                sOut = sOut & "Display: " & Filename
                psiChild.GetDisplayName SIGDN_DESKTOPABSOLUTEPARSING, lpName
                Filename = BStrFromLPWStr(lpName)
                sOut = sOut & " | AbsParse=" & Filename & vbCrLf
            Loop
        Else
            Debug.Print "Failed to enumerate selection."
        End If
    Else
        Debug.Print "Failed to get selection array."
    End If
    
    'old way that only works on non-virtual locations:        
    'psv.GetItemObject SVGIO_SELECTION, IID_IDataObject, pIDO
    'If (pIDO Is Nothing) Then
    '    Debug.Print "Failed to create IDataObject"
    '    Exit Sub
    'End If
    '
    '
    'fmt.cfFormat = CF_HDROP
    'fmt.dwAspect = DVASPECT_CONTENT
    'fmt.lindex = -1
    'fmt.TYMED = TYMED_HGLOBAL
    'stg.TYMED = TYMED_HGLOBAL
    '
    'hr = pIDO.GetData(fmt, stg)
    'Debug.Print "GetData hr=" & hr
    '
    'hDrop = GlobalLock(stg.Data)
    '
    'uNumFiles = DragQueryFile(hDrop, &HFFFFFFFF, "", 0)
    'Debug.Print "got nfiles=" & uNumFiles
    'For i = 0 To (uNumFiles - 1)
    '    Filename = String$(260, 0)
    '    Call DragQueryFile(hDrop, i, Filename, Len(Filename))
    '    If (InStr(Filename, vbNullChar)) > 1 Then
    '        Filename = Left$(Filename, InStr(Filename, vbNullChar) - 1)
    '        Debug.Print "filename=" & Filename
    '        sOut = sOut & Filename & ", "
    '    End If
    'Next i
    'Call GlobalUnlock(stg.Data)
    'ReleaseStgMedium VarPtr(stg)
    Debug.Print "output=" & sOut
    Text1.Text = sOut
    End Sub
    It's basically the same way it's done on the INamespaceTreeControl form, only difference being that you still need to go through IShellView.

    UPDATE: Showing a Custom List of Files

    (8/2018) This project allows you to browse to any particular location on the system, but what if you want to do something like display a Search Results folder, or some other view where all the files reside in different locations? There's an interface that allows you to easily do just that. See the new project:
    [VB6] Display search results or other custom file set in IExplorerBrowser
    Attached Files Attached Files
    Last edited by fafalone; Aug 24th, 2018 at 12:10 AM. Reason: New related project details added

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