Maybe you know this version of a folder browser dialog box that can be created by SHBrowseForFolder.

Bild

For standard users or users who just put everything in one folder, is this dialog very good to use. However there are also users out there who have a deep directory structure and hate such dialogs, because you cannot add directly a folder path as a string to select the folder directly. Many applications also show the folder path in a custom edit box, but do not allow to edit them directly.

So why isn’t there an edit box like shown below?

Bild

This dialog was created by a Delphi-Praxis member and is free to download from this DP article.

Fortunately the people from Microsoft adapted ShellExecute so it allows to enter a folder path directly. This feature is available in shell32.dll version 5.0 or later (Windows 2000 or later).

Bild

You can even change the size of the dialog. Unfortunately there is no simple way to set the initial folder of the BrowserDialog, so this has to be done in a Callback function (I will not bother your with details).

This task is accomplished by setting the flags in the browse info structure.

  • BIF_EDITBOX adds the edit box to the dialog
  • BIF_NEWDIALOGSTYLE includes more features:

    Version 5.0. Use the new user interface. Setting this flag provides the user with a larger dialog box that can be resized. The dialog box has several new capabilities, including: drag-and-drop capability within the dialog box, reordering, shortcut menus, new folders, delete, and other shortcut menu commands

  • BIF_USENEWUI combines BIF_EDITBOX and BIF_NEWDIALOGSTYLE. Don’t forget to call CoInitialize if you are going to use it.

Since using ShellExecute needs a lot of work, I just print the necessary helper function BrowseForFolder. The original function was developed by Brian Cryer. You can download it from here. However I did some improvements.

  1. The new version works also with unicode.
  2. InitialDirectory does no more rely on a global variable
  3. Return value of BrowseForFolder defines whether the user has canceled (FALSE) the dialog or not (TRUE).
  4. it can be used with Rudy’s ShellAPI Header Conversions

The function declaration can be seen here.

function BrowseForFolder(const Owner : HWND;
  const Title: TJwString;
  const InitialFolder     : TJwString;
  const AllowCreateNewFolder: Boolean;
  out NewFolder : TJwString): Boolean;

The parameter names should be meaningful enough. The function returns true, if the user clicked the OK button; otherwise it returns false. If you needn’t an initial folder just leave it empty.

The whole source code as a sample project can be downloaded here.

What units are used:

  1. JwaWindows for Windows stuff
  2. ActiveX for COM stuff
  3. Either include
    • RVShlObj – Rudy’s headers

    or

    • ShlObj – default header
  4. JwsclStrings contains TJwString which resolves to WideString or AnsiString, depending on the compiler directive UNICODE.

How to compile and use the source:

  • define UNICODE as a condition in your project settings if you want to use UNICODE strings
  • define RUDY as a condition in the source if you want Rudy’s Headers to be used.
    • Adapt RVShlObj.pas and friends if errors occur
  • Copy&Paste the necessary parts into your project.

Adapt RVShlObj:
If you encounter error messages in RVShlObj.pas and friends read on.

  • an error where “inline;” was found – solution: remove “inline;”
  • an error where “$WEAKPACKAGEUNIT” can be seen in error text – solution: find “{$WEAKPACKAGEUNIT}” and remove it.

Tell me how you liked this blog entry by adding a comment.