The ShowFolders method of the CommDlg Ocx isn't documented properly. The method is included to provide an easy way to display the Shell's SHBrowseForFolders dialog box allowing the user to select a folder rather than a file. It is - of course - not part of the the Common Dialog Box Library and should have been implemented as a separately function. Or shouldn't it?
The FileName and Title properties
The CommDlg.ShowFolders(Optional flag As Variant) method shares two properties with other CommDlg methods that show dialog boxes: FileName and Title. In case these are used with ShowFolders their meaning is as follows:
- CommDlg.Title (R/W)
Sets the string that is displayed above the tree view control in the dialog box. This string can be used to specify instructions to the user. Returns the same value as was put into it.
- CommDlg.FileName (R/W)
Sets the browse dialog box's initial selection folder (has nothing to do with filenames!). Note, by default, the SHBrowseForFolder API lets the user start at the desktop to browse the shell's namespace and pick a folder. GFA-BASIC 32 overrides this behavior by starting the browse dialog box at the folder specified in the .FileName property. To let the dialog box start at the desktop set the FileName property to an empty string. To bring up the browse dialog box with the current directory selected, set FileName = CurDir.
After closing the ShowFolders dialog box the FileName property contains the name of the selected folder. That is if you select the Ok button; after Cancel the FileName is undefined.
CommDlg code was/is buggy
The GFA-BASIC 32 library code that implements CommDlg Ocx and specifically the Show Folder function, has always been buggy and I've been fixing it many times in the past. I was confident I fixed all bugs in Build 1169. At the time of writing this blog I tried it again and I was shocked to see that it still has a bug. When you press the browse dialog box's Cancel button the FileName property is undefined and present an Access Violation error. I will fix it as soon as possible and release Build 1170, which also contains fixes for the Dlg Open/Save commands.
The optional parameter
The ShowFolders(flag) method accepts one optional argument that specifies the options for the dialog box. When you omit the argument, the default behavior is BIF_RETURNONLYFSDIRS. The flag can include a combination of the following values:
BIF_BROWSEFORCOMPUTER (0x1000) | Only return computers. If the user selects anything other than a computer, the OK button is grayed. |
BIF_BROWSEFORPRINTER (0x2000) | Only return printers. If the user selects anything other than a printer, the OK button is grayed. |
BIF_BROWSEINCLUDEFILES (0x4000) | The browse dialog will display files as well as folders. |
BIF_DONTGOBELOWDOMAIN (0x2) | Do not include network folders below the domain level in the tree view control. |
BIF_EDITBOX (0x10) | Version 4.71. The browse dialog includes an edit control in which the user can type the name of an item. |
BIF_RETURNFSANCESTORS (0x08) | Only return file system ancestors. If the user selects anything other than a file system ancestor, the OK button is grayed. |
BIF_RETURNONLYFSDIRS (0x01) | Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed. |
BIF_STATUSTEXT (0x04) | Include a status area in the dialog box. The callback function can set the status text by sending messages to the dialog box. |
BIF_VALIDATE (0x20) | Version 4.71. If the user types an invalid name into the edit box, the browse dialog will call the application's BrowseCallBackproc with the BFFM_VALIDATEFAILED message. This flag is ignored if BIF_EDITBOX is not specified. |
The BrowseCallbackProc
Although the ShowFolders method will pass most of the flags without questions asked, it doesn't honor them all. Some of the flags require an application-defined callback function to handle application defined behavior. The underlying SHBrowseForFolder API function calls BrowseCallbackProc to notify it about events. The address of the callback function is passed in the BROWSEINFO structure that contains information used to display the dialog box. The GFA-BASIC 32 ShowFolders method uses the callback proc to select the folder set with CommDlg.FileName in response of the BFFM_INITIALIZED message. GFA-BASIC 32 does not provide a way to interact with its BrowseCallbackProc, making ShowFolders a simple folder selection mechanism.