Customising+the+Browse+for+Folder+dialogue

//by Richard Russell, July 2009//

The main [|Help documentation] explains how you can use the Windows API to display a **Browse for Folder** dialogue box, allowing the user to select a folder (directory) for some purpose.

Unfortunately the basic functionality of **SHBrowseForFolder** is not very flexible, so below are listed two functions, the first of which lets you specify the **root** folder that the browse operation starts from, and the second lets you specify the **initial** folder selection. In both cases the default folder (i.e. the one returned if you simply click on OK) is the specified folder, but the difference is that in the first case you cannot navigate 'above' that folder, whereas in the second case you can.

The first function, **FNbrowseforfolderroot**, is called in the following context:

code format="bb4w" title$ = "Set root selection" root$ = "C:\bbcbasic\windows\programs" folder$ = FNbrowseforfolderroot(title$, root$) code The second function, **FNbrowseforfolderinit**, is called in the following context:

code format="bb4w" INSTALL @lib$+"CALLBACK"

title$ = "Set initial selection" init$ = "C:\bbcbasic\windows\programs" folder$ = FNbrowseforfolderinit(title$, init$) code It would in principle be possible to combine the functions of the two routines, so that both the **root** and the **initial selection** may be specified, however that's not very likely to be required in practice.

Here are the functions:

code format="bb4w" DEF FNbrowseforfolderroot(title$, root$) LOCAL folder%, pathw%, pidl%, malloc%, bi{} title$ += CHR$0 : root$ += CHR$0 BIF_USENEWUI = &40 DIM folder% LOCAL 260, pathw% LOCAL 520 SYS "MultiByteToWideChar", 0, 0, root$, -1, pathw%, 260 SYS "ILCreateFromPath", pathw% TO pidl% DIM bi{hOwner%, pidlRoot%, pszDisplayName%, \ \     lpszTitle%, ulFlags%, lpfn%, lParam%, iImage%} bi.hOwner% = @hwnd% bi.pidlRoot% = pidl% bi.pszDisplayName% = folder% bi.lpszTitle% = !^title$ bi.ulFlags% = BIF_USENEWUI SYS "SHBrowseForFolder", bi{} TO pidl% IF pidl% THEN SYS "SHGetPathFromIDList", pidl%, folder% SYS "SHGetMalloc", ^malloc% SYS !(!malloc%+20), malloc%, pidl% ENDIF =$$folder% code

code format="bb4w" DEF FNbrowseforfolderinit(title$, init$) LOCAL folder%, pidl%, malloc%, bi{} title$ += CHR$0 : init$ += CHR$0 BFFM_INITIALIZED = 1 BFFM_SETSELECTION = &466 BIF_USENEWUI = &40 DIM folder% LOCAL 260 DIM bi{hOwner%, pidlRoot%, pszDisplayName%, \ \     lpszTitle%, ulFlags%, lpfn%, lParam%, iImage%} bi.hOwner% = @hwnd% bi.pszDisplayName% = folder% bi.lpszTitle% = !^title$ bi.ulFlags% = BIF_USENEWUI bi.lpfn% = FN_callback(FNBrowseCallbackProc,4) bi.lParam% = !^init$ SYS FN_syscalls("SHBrowseForFolder"), bi{} pidl% = FN_sysresult IF pidl% THEN SYS "SHGetPathFromIDList", pidl%, folder% SYS "SHGetMalloc", ^malloc% SYS !(!malloc%+20), malloc%, pidl% ENDIF =$$folder% DEF FNBrowseCallbackProc(hwnd%, uMsg%, lParam%, lpData%) IF uMsg% <> BFFM_INITIALIZED THEN = 0 lParam% = FN_sendmessage(hwnd%, BFFM_SETSELECTION, TRUE, lpData%) = 0 code