Home Articles Books Downloads FAQs Tips

Q: Determine the path to the Windows Desktop directory and other special folders


Answer

Use the API SHGetSpecialFolder function. SHGetSpecialFolder is prototyped in SHLOBJ.H. This function allows you to retrieve a pidl for various directories in the shell, such as the Windows desktop , the startup directory, and the My Documents folder. Once you have a pidl, you can convert the pidl to a path string through the SHGetPathFromIDList API function.

SHGetSpecialFolder takes three arguments. The first argument is an HWND that specifies an owner window for any dialog boxes or message boxes that might appear during the call (I'm not sure why a dialog box would appear). The second argument is an integer id that determines which folder you are trying to find. The possible values are

  • CSIDL_BITBUCKET Recycle bin
  • CSIDL_CONTROLS Control Panel
  • CSIDL_DESKTOP Windows desktop
  • CSIDL_DESKTOPDIRECTORY Directory for the desktop
  • CSIDL_DRIVES My Computer
  • CSIDL_FONTS Fonts directory
  • CSIDL_NETHOOD Network Neighborhood
  • CSIDL_NETWORK Network Neighborhood virtual folder
  • CSIDL_PERSONAL My Documents
  • CSIDL_PRINTERS Printers
  • CSIDL_PROGRAMS Program groups
  • CSIDL_RECENT Most recent documents list
  • CSIDL_SENDTO Send To menu items
  • CSIDL_STARTMENU Taskbar Start menu items
  • CSIDL_STARTUP Startup directory
  • CSIDL_TEMPLATES Document templates

The last argument is the address of a pidl. SHGetSpecialFolderLocation writes the result pidl to this address.

The code example below demonstrates how to use SHGetSpecialFolderLocation.

//----------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    LPITEMIDLIST  pidl;
    LPMALLOC      pShellMalloc;
    char          szDir[MAX_PATH];

    // SHGetSpecialFolderLocation generates a PIDL. The memory for the PIDL
    // is allocated by the shell, and should be freed using the shell
    // mallocator COM object. Use SHGetMalloc to retrieve the malloc object
    if(SUCCEEDED(SHGetMalloc(&pShellMalloc)))
    {
        // if we were able to get the shell malloc object, then
        // proceed by fetching the pidl for the windows desktop
        if(SUCCEEDED(SHGetSpecialFolderLocation(NULL,
                                                CSIDL_DESKTOPDIRECTORY,
                                                &pidl)))
        {
            // return is true if success
            if(SHGetPathFromIDList(pidl, szDir))
            {
                // set one caption to the directory path
                Label1->Caption = szDir;
            }

            pShellMalloc->Free(pidl);
        }

        pShellMalloc->Release();
    }
}
//----------------------------------------------------------------------

When I run the example code on my system, the path to the windows desktop is C:\Windows\Desktop. I expanded the example to retrieve directories for some of the other special folders. The figure below shows the results.



Figure 1. Results of the SHGetSpecialFolder function

Note: Notice that some of the path names are blank. Some of special folders in the shell do not have a corresponding directory in the file system.

Note: The FAQ on browsing for a folder contains an explanation of SHGetMalloc.


Downloads for this FAQ
specialfolder.zip BCB3 project that demonstrates SHGetSpecialFolder.
specialfolderx.zip Same project, includes an EXE.


Copyright © 1997-2000 by Harold Howe.
All rights reserved.