Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1449

[VB6] SHBrowseForFolder - Custom filter for shown items: BFFM_IUNKNOWN/IFolderFilter

$
0
0

It's possible to have complete control over what items are shown in the SHBrowseForFolder dialog. The picture above shows a filter of *.exe applied to a dialog with the BIF_BROWSEINCLUDEFILES option, but you can filter in a wide variety of ways as the IShellFolder and pidl for each item is passed, allowing you to get the name and compare by string and properties, as in the demo, or anything else you could want. The project notes where you could even filter by SHCONTF options.
This is accomplished through the BFFM_IUNKNOWN message that is received in the callback function. A lot of places have mentioned what it's for, but I wanted to show the actual details of using that message to set up a filter.

First, you create a class module that implements the IFolderFilter interface and create an instance of it before calling the dialog. The GetEnumFlags method is where you can filter by SHCONTF, but this demo is mainly concerned with examining each item in the ShouldShow method. Whether to show the item or not is based on the return code, so the class module function is swapped out to a function in the module. Here's the demo filters files, but not folders, according to the pattern specified in the text box:
Code:

Public Function ShouldShowVB(ByVal this As IFolderFilter, ByVal psf As IShellFolder, ByVal pidlFolder As Long, ByVal pidlItem As Long) As Long
Dim psi As IShellItem
Dim lpName As Long, sName As String
Dim dwAtr As Long
On Error GoTo e0

SHCreateItemWithParent 0&, psf, pidlItem, IID_IShellItem, psi
If (psi Is Nothing) = False Then
    psi.GetAttributes SFGAO_FILESYSTEM Or SFGAO_FOLDER, dwAtr
    If ((dwAtr And SFGAO_FILESYSTEM) = SFGAO_FILESYSTEM) And ((dwAtr And SFGAO_FOLDER) = 0) Then 'is in normal file system, is not a folder
        psi.GetDisplayName SIGDN_PARENTRELATIVEPARSING, lpName
        sName = LPWSTRtoStr(lpName)
        Debug.Print "ShouldShow?" & sName & "|" & gSpec
        If PathMatchSpecW(StrPtr(sName), StrPtr(gSpec)) Then
            ShouldShowVB = S_OK 'should show
        Else
            ShouldShowVB = S_FALSE 'should not show
        End If
    End If
Else
    Debug.Print "ShouldShow.NoItem"
End If

Exit Function
e0:
Debug.Print "ShouldShowVB.Error->" & Err.Description
End Function

Now that the filter object and routine are good to go, it needs to be assigned to the dialog. When the BFFM_IUNKNOWN message fires, the lParam contains a pointer to an IUnknown object which implements IFolderFilterSite, which contains the call to assign our filter class. If the messages fires but the object is Nothing, the filter class needs to be released and reset, otherwise a subsequent call to SHBrowseDialog won't be filtered.
Code:

Public Function BrowseCallbackProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal lParam As Long, ByVal lpData As Long) As Long
Dim pSite As IFolderFilterSite
Dim pUnk As oleexp.IUnknown

Select Case uMsg

    Case BFFM_IUNKNOWN
        'lParam contains a pointer to an IUnknown that implements IFolderFilterSite
        Debug.Print "Received BFFM_IUNKNOWN"
        vbaObjSetAddRef pUnk, lParam
        Debug.Print "Set obj"
        If (pUnk Is Nothing) = False Then
            Set pSite = pUnk
            If (pSite Is Nothing) = False Then
                Debug.Print "Setting filter"
                pSite.SetFilter cFilter
                Debug.Print "Filter set"
            Else
                Debug.Print "Failed to set pSite"
            End If
        Else
            Debug.Print "Failed to set pUnk"
            Set cFilter = Nothing
        End If
End Select
End Function

And that's about it. The rest is just calling the dialog like normal (+making a new instance of the cFolderFilter class first).

Requirements
-The demo project requires Windows Vista or newer, although it could theoretically be reworked to support XP.
-oleexp 4.1 or newer (this project requires a bug fixed only in 4.1, not 4.0)
-mIID.bas (included in the oleexp download)
Attached Files

Viewing all articles
Browse latest Browse all 1449

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>